|
@@ -5,7 +5,12 @@ import 'package:app_flowy/plugins/grid/application/filter/filter_service.dart';
|
|
|
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
|
|
import 'package:app_flowy/plugins/grid/application/setting/setting_listener.dart';
|
|
|
import 'package:app_flowy/plugins/grid/application/setting/setting_service.dart';
|
|
|
+import 'package:app_flowy/plugins/grid/application/sort/sort_listener.dart';
|
|
|
+import 'package:app_flowy/plugins/grid/application/sort/sort_service.dart';
|
|
|
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
|
|
+import 'package:app_flowy/plugins/grid/presentation/widgets/sort/sort_info.dart';
|
|
|
+import 'package:appflowy_backend/protobuf/flowy-grid/filter_changeset.pb.dart';
|
|
|
+import 'package:appflowy_backend/protobuf/flowy-grid/sort_entities.pb.dart';
|
|
|
import 'package:dartz/dartz.dart';
|
|
|
import 'package:appflowy_backend/log.dart';
|
|
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
|
@@ -46,21 +51,39 @@ class _GridFilterNotifier extends ChangeNotifier {
|
|
|
List<FilterInfo> get filters => _filters;
|
|
|
}
|
|
|
|
|
|
+class _GridSortNotifier extends ChangeNotifier {
|
|
|
+ List<SortInfo> _sorts = [];
|
|
|
+
|
|
|
+ set sorts(List<SortInfo> sorts) {
|
|
|
+ _sorts = sorts;
|
|
|
+ notifyListeners();
|
|
|
+ }
|
|
|
+
|
|
|
+ void notify() {
|
|
|
+ notifyListeners();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<SortInfo> get sorts => _sorts;
|
|
|
+}
|
|
|
+
|
|
|
typedef OnReceiveUpdateFields = void Function(List<FieldInfo>);
|
|
|
typedef OnReceiveFields = void Function(List<FieldInfo>);
|
|
|
typedef OnReceiveFilters = void Function(List<FilterInfo>);
|
|
|
+typedef OnReceiveSorts = void Function(List<SortInfo>);
|
|
|
|
|
|
class GridFieldController {
|
|
|
final String gridId;
|
|
|
// Listeners
|
|
|
final GridFieldsListener _fieldListener;
|
|
|
final SettingListener _settingListener;
|
|
|
- final FiltersListener _filterListener;
|
|
|
+ final FiltersListener _filtersListener;
|
|
|
+ final SortsListener _sortsListener;
|
|
|
|
|
|
// FFI services
|
|
|
final GridFFIService _gridFFIService;
|
|
|
final SettingFFIService _settingFFIService;
|
|
|
final FilterFFIService _filterFFIService;
|
|
|
+ final SortFFIService _sortFFIService;
|
|
|
|
|
|
// Field callbacks
|
|
|
final Map<OnReceiveFields, VoidCallback> _fieldCallbacks = {};
|
|
@@ -78,9 +101,16 @@ class GridFieldController {
|
|
|
_GridFilterNotifier? _filterNotifier = _GridFilterNotifier();
|
|
|
final Map<String, FilterPB> _filterPBByFieldId = {};
|
|
|
|
|
|
+ // Sort callbacks
|
|
|
+ final Map<OnReceiveSorts, VoidCallback> _sortCallbacks = {};
|
|
|
+ _GridSortNotifier? _sortNotifier = _GridSortNotifier();
|
|
|
+ final Map<String, SortPB> _sortPBByFieldId = {};
|
|
|
+
|
|
|
// Getters
|
|
|
List<FieldInfo> get fieldInfos => [..._fieldNotifier?.fieldInfos ?? []];
|
|
|
List<FilterInfo> get filterInfos => [..._filterNotifier?.filters ?? []];
|
|
|
+ List<SortInfo> get sortInfos => [..._sortNotifier?.sorts ?? []];
|
|
|
+
|
|
|
FieldInfo? getField(String fieldId) {
|
|
|
final fields = _fieldNotifier?.fieldInfos
|
|
|
.where((element) => element.id == fieldId)
|
|
@@ -105,12 +135,26 @@ class GridFieldController {
|
|
|
return filters.first;
|
|
|
}
|
|
|
|
|
|
+ SortInfo? getSort(String sortId) {
|
|
|
+ final sorts = _sortNotifier?.sorts
|
|
|
+ .where((element) => element.sortId == sortId)
|
|
|
+ .toList() ??
|
|
|
+ [];
|
|
|
+ if (sorts.isEmpty) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ assert(sorts.length == 1);
|
|
|
+ return sorts.first;
|
|
|
+ }
|
|
|
+
|
|
|
GridFieldController({required this.gridId})
|
|
|
: _fieldListener = GridFieldsListener(gridId: gridId),
|
|
|
_settingListener = SettingListener(gridId: gridId),
|
|
|
- _filterListener = FiltersListener(viewId: gridId),
|
|
|
- _gridFFIService = GridFFIService(gridId: gridId),
|
|
|
_filterFFIService = FilterFFIService(viewId: gridId),
|
|
|
+ _filtersListener = FiltersListener(viewId: gridId),
|
|
|
+ _gridFFIService = GridFFIService(gridId: gridId),
|
|
|
+ _sortFFIService = SortFFIService(viewId: gridId),
|
|
|
+ _sortsListener = SortsListener(viewId: gridId),
|
|
|
_settingFFIService = SettingFFIService(viewId: gridId) {
|
|
|
//Listen on field's changes
|
|
|
_listenOnFieldChanges();
|
|
@@ -121,9 +165,12 @@ class GridFieldController {
|
|
|
//Listen on the fitler changes
|
|
|
_listenOnFilterChanges();
|
|
|
|
|
|
+ //Listen on the sort changes
|
|
|
+ _listenOnSortChanged();
|
|
|
+
|
|
|
_settingFFIService.getSetting().then((result) {
|
|
|
result.fold(
|
|
|
- (setting) => _updateSettingConfiguration(setting),
|
|
|
+ (setting) => _updateSetting(setting),
|
|
|
(err) => Log.error(err),
|
|
|
);
|
|
|
});
|
|
@@ -131,70 +178,185 @@ class GridFieldController {
|
|
|
|
|
|
void _listenOnFilterChanges() {
|
|
|
//Listen on the fitler changes
|
|
|
- _filterListener.start(onFilterChanged: (result) {
|
|
|
+
|
|
|
+ deleteFilterFromChangeset(
|
|
|
+ List<FilterInfo> filters,
|
|
|
+ FilterChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ final deleteFilterIds = changeset.deleteFilters.map((e) => e.id).toList();
|
|
|
+ if (deleteFilterIds.isNotEmpty) {
|
|
|
+ filters.retainWhere(
|
|
|
+ (element) => !deleteFilterIds.contains(element.filter.id),
|
|
|
+ );
|
|
|
+
|
|
|
+ _filterPBByFieldId
|
|
|
+ .removeWhere((key, value) => deleteFilterIds.contains(value.id));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ insertFilterFromChangeset(
|
|
|
+ List<FilterInfo> filters,
|
|
|
+ FilterChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ for (final newFilter in changeset.insertFilters) {
|
|
|
+ final filterIndex =
|
|
|
+ filters.indexWhere((element) => element.filter.id == newFilter.id);
|
|
|
+ if (filterIndex == -1) {
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: newFilter.fieldId,
|
|
|
+ fieldType: newFilter.fieldType,
|
|
|
+ );
|
|
|
+ if (fieldInfo != null) {
|
|
|
+ _filterPBByFieldId[fieldInfo.id] = newFilter;
|
|
|
+ filters.add(FilterInfo(gridId, newFilter, fieldInfo));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ updateFilterFromChangeset(
|
|
|
+ List<FilterInfo> filters,
|
|
|
+ FilterChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ for (final updatedFilter in changeset.updateFilters) {
|
|
|
+ final filterIndex = filters.indexWhere(
|
|
|
+ (element) => element.filter.id == updatedFilter.filterId,
|
|
|
+ );
|
|
|
+ // Remove the old filter
|
|
|
+ if (filterIndex != -1) {
|
|
|
+ filters.removeAt(filterIndex);
|
|
|
+ _filterPBByFieldId
|
|
|
+ .removeWhere((key, value) => value.id == updatedFilter.filterId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Insert the filter if there is a fitler and its field info is
|
|
|
+ // not null
|
|
|
+ if (updatedFilter.hasFilter()) {
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: updatedFilter.filter.fieldId,
|
|
|
+ fieldType: updatedFilter.filter.fieldType,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (fieldInfo != null) {
|
|
|
+ // Insert the filter with the position: filterIndex, otherwise,
|
|
|
+ // append it to the end of the list.
|
|
|
+ final filterInfo =
|
|
|
+ FilterInfo(gridId, updatedFilter.filter, fieldInfo);
|
|
|
+ if (filterIndex != -1) {
|
|
|
+ filters.insert(filterIndex, filterInfo);
|
|
|
+ } else {
|
|
|
+ filters.add(filterInfo);
|
|
|
+ }
|
|
|
+ _filterPBByFieldId[fieldInfo.id] = updatedFilter.filter;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _filtersListener.start(onFilterChanged: (result) {
|
|
|
result.fold(
|
|
|
- (changeset) {
|
|
|
+ (FilterChangesetNotificationPB changeset) {
|
|
|
final List<FilterInfo> filters = filterInfos;
|
|
|
// Deletes the filters
|
|
|
- final deleteFilterIds =
|
|
|
- changeset.deleteFilters.map((e) => e.id).toList();
|
|
|
- if (deleteFilterIds.isNotEmpty) {
|
|
|
- filters.retainWhere(
|
|
|
- (element) => !deleteFilterIds.contains(element.filter.id),
|
|
|
- );
|
|
|
-
|
|
|
- _filterPBByFieldId.removeWhere(
|
|
|
- (key, value) => deleteFilterIds.contains(value.id));
|
|
|
- }
|
|
|
+ deleteFilterFromChangeset(filters, changeset);
|
|
|
|
|
|
// Inserts the new filter if it's not exist
|
|
|
- for (final newFilter in changeset.insertFilters) {
|
|
|
- final filterIndex = filters
|
|
|
- .indexWhere((element) => element.filter.id == newFilter.id);
|
|
|
- if (filterIndex == -1) {
|
|
|
- final fieldInfo = _findFieldInfoForFilter(fieldInfos, newFilter);
|
|
|
- if (fieldInfo != null) {
|
|
|
- _filterPBByFieldId[fieldInfo.id] = newFilter;
|
|
|
- filters.add(FilterInfo(gridId, newFilter, fieldInfo));
|
|
|
- }
|
|
|
- }
|
|
|
+ insertFilterFromChangeset(filters, changeset);
|
|
|
+
|
|
|
+ updateFilterFromChangeset(filters, changeset);
|
|
|
+
|
|
|
+ _updateFieldInfos();
|
|
|
+ _filterNotifier?.filters = filters;
|
|
|
+ },
|
|
|
+ (err) => Log.error(err),
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ void _listenOnSortChanged() {
|
|
|
+ deleteSortFromChangeset(
|
|
|
+ List<SortInfo> newSortInfos,
|
|
|
+ SortChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ final deleteSortIds = changeset.deleteSorts.map((e) => e.id).toList();
|
|
|
+ if (deleteSortIds.isNotEmpty) {
|
|
|
+ newSortInfos.retainWhere(
|
|
|
+ (element) => !deleteSortIds.contains(element.sortId),
|
|
|
+ );
|
|
|
+
|
|
|
+ _sortPBByFieldId
|
|
|
+ .removeWhere((key, value) => deleteSortIds.contains(value.id));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ insertSortFromChangeset(
|
|
|
+ List<SortInfo> newSortInfos,
|
|
|
+ SortChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ for (final newSortPB in changeset.insertSorts) {
|
|
|
+ final sortIndex = newSortInfos
|
|
|
+ .indexWhere((element) => element.sortId == newSortPB.id);
|
|
|
+ if (sortIndex == -1) {
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: newSortPB.fieldId,
|
|
|
+ fieldType: newSortPB.fieldType,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (fieldInfo != null) {
|
|
|
+ _sortPBByFieldId[newSortPB.fieldId] = newSortPB;
|
|
|
+ newSortInfos.add(SortInfo(sortPB: newSortPB, fieldInfo: fieldInfo));
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- for (final updatedFilter in changeset.updateFilters) {
|
|
|
- final filterIndex = filters.indexWhere(
|
|
|
- (element) => element.filter.id == updatedFilter.filterId,
|
|
|
- );
|
|
|
- // Remove the old filter
|
|
|
- if (filterIndex != -1) {
|
|
|
- filters.removeAt(filterIndex);
|
|
|
- _filterPBByFieldId.removeWhere(
|
|
|
- (key, value) => value.id == updatedFilter.filterId);
|
|
|
- }
|
|
|
+ updateSortFromChangeset(
|
|
|
+ List<SortInfo> newSortInfos,
|
|
|
+ SortChangesetNotificationPB changeset,
|
|
|
+ ) {
|
|
|
+ for (final updatedSort in changeset.updateSorts) {
|
|
|
+ final sortIndex = newSortInfos.indexWhere(
|
|
|
+ (element) => element.sortId == updatedSort.id,
|
|
|
+ );
|
|
|
+ // Remove the old filter
|
|
|
+ if (sortIndex != -1) {
|
|
|
+ newSortInfos.removeAt(sortIndex);
|
|
|
+ }
|
|
|
|
|
|
- // Insert the filter if there is a fitler and its field info is
|
|
|
- // not null
|
|
|
- if (updatedFilter.hasFilter()) {
|
|
|
- final fieldInfo = _findFieldInfoForFilter(
|
|
|
- fieldInfos,
|
|
|
- updatedFilter.filter,
|
|
|
- );
|
|
|
-
|
|
|
- if (fieldInfo != null) {
|
|
|
- // Insert the filter with the position: filterIndex, otherwise,
|
|
|
- // append it to the end of the list.
|
|
|
- final filterInfo =
|
|
|
- FilterInfo(gridId, updatedFilter.filter, fieldInfo);
|
|
|
- if (filterIndex != -1) {
|
|
|
- filters.insert(filterIndex, filterInfo);
|
|
|
- } else {
|
|
|
- filters.add(filterInfo);
|
|
|
- }
|
|
|
- _filterPBByFieldId[fieldInfo.id] = updatedFilter.filter;
|
|
|
- }
|
|
|
- }
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: updatedSort.fieldId,
|
|
|
+ fieldType: updatedSort.fieldType,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (fieldInfo != null) {
|
|
|
+ final newSortInfo = SortInfo(
|
|
|
+ sortPB: updatedSort,
|
|
|
+ fieldInfo: fieldInfo,
|
|
|
+ );
|
|
|
+ if (sortIndex != -1) {
|
|
|
+ newSortInfos.insert(sortIndex, newSortInfo);
|
|
|
+ } else {
|
|
|
+ newSortInfos.add(newSortInfo);
|
|
|
}
|
|
|
+ _sortPBByFieldId[updatedSort.fieldId] = updatedSort;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _sortsListener.start(onSortChanged: (result) {
|
|
|
+ result.fold(
|
|
|
+ (SortChangesetNotificationPB changeset) {
|
|
|
+ final List<SortInfo> newSortInfos = sortInfos;
|
|
|
+ deleteSortFromChangeset(newSortInfos, changeset);
|
|
|
+ insertSortFromChangeset(newSortInfos, changeset);
|
|
|
+ updateSortFromChangeset(newSortInfos, changeset);
|
|
|
+
|
|
|
_updateFieldInfos();
|
|
|
- _filterNotifier?.filters = filters;
|
|
|
+ _sortNotifier?.sorts = newSortInfos;
|
|
|
},
|
|
|
(err) => Log.error(err),
|
|
|
);
|
|
@@ -205,7 +367,7 @@ class GridFieldController {
|
|
|
//Listen on setting changes
|
|
|
_settingListener.start(onSettingUpdated: (result) {
|
|
|
result.fold(
|
|
|
- (setting) => _updateSettingConfiguration(setting),
|
|
|
+ (setting) => _updateSetting(setting),
|
|
|
(r) => Log.error(r),
|
|
|
);
|
|
|
});
|
|
@@ -229,14 +391,18 @@ class GridFieldController {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- void _updateSettingConfiguration(GridSettingPB setting) {
|
|
|
+ void _updateSetting(GridSettingPB setting) {
|
|
|
_groupConfigurationByFieldId.clear();
|
|
|
for (final configuration in setting.groupConfigurations.items) {
|
|
|
_groupConfigurationByFieldId[configuration.fieldId] = configuration;
|
|
|
}
|
|
|
|
|
|
- for (final configuration in setting.filters.items) {
|
|
|
- _filterPBByFieldId[configuration.fieldId] = configuration;
|
|
|
+ for (final filter in setting.filters.items) {
|
|
|
+ _filterPBByFieldId[filter.fieldId] = filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (final sort in setting.sorts.items) {
|
|
|
+ _sortPBByFieldId[sort.fieldId] = sort;
|
|
|
}
|
|
|
|
|
|
_updateFieldInfos();
|
|
@@ -247,6 +413,7 @@ class GridFieldController {
|
|
|
for (var field in _fieldNotifier!.fieldInfos) {
|
|
|
field._isGroupField = _groupConfigurationByFieldId[field.id] != null;
|
|
|
field._hasFilter = _filterPBByFieldId[field.id] != null;
|
|
|
+ field._hasSort = _sortPBByFieldId[field.id] != null;
|
|
|
}
|
|
|
_fieldNotifier?.notify();
|
|
|
}
|
|
@@ -254,8 +421,9 @@ class GridFieldController {
|
|
|
|
|
|
Future<void> dispose() async {
|
|
|
await _fieldListener.stop();
|
|
|
- await _filterListener.stop();
|
|
|
+ await _filtersListener.stop();
|
|
|
await _settingListener.stop();
|
|
|
+ await _sortsListener.stop();
|
|
|
|
|
|
for (final callback in _fieldCallbacks.values) {
|
|
|
_fieldNotifier?.removeListener(callback);
|
|
@@ -266,8 +434,15 @@ class GridFieldController {
|
|
|
for (final callback in _filterCallbacks.values) {
|
|
|
_filterNotifier?.removeListener(callback);
|
|
|
}
|
|
|
+ for (final callback in _sortCallbacks.values) {
|
|
|
+ _sortNotifier?.removeListener(callback);
|
|
|
+ }
|
|
|
+
|
|
|
_filterNotifier?.dispose();
|
|
|
_filterNotifier = null;
|
|
|
+
|
|
|
+ _sortNotifier?.dispose();
|
|
|
+ _sortNotifier = null;
|
|
|
}
|
|
|
|
|
|
Future<Either<Unit, FlowyError>> loadFields({
|
|
@@ -280,6 +455,7 @@ class GridFieldController {
|
|
|
_fieldNotifier?.fieldInfos =
|
|
|
newFields.map((field) => FieldInfo(field: field)).toList();
|
|
|
_loadFilters();
|
|
|
+ _loadSorts();
|
|
|
_updateFieldInfos();
|
|
|
return left(unit);
|
|
|
},
|
|
@@ -294,14 +470,17 @@ class GridFieldController {
|
|
|
(filterPBs) {
|
|
|
final List<FilterInfo> filters = [];
|
|
|
for (final filterPB in filterPBs) {
|
|
|
- final fieldInfo = _findFieldInfoForFilter(fieldInfos, filterPB);
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: filterPB.fieldId,
|
|
|
+ fieldType: filterPB.fieldType,
|
|
|
+ );
|
|
|
if (fieldInfo != null) {
|
|
|
final filterInfo = FilterInfo(gridId, filterPB, fieldInfo);
|
|
|
filters.add(filterInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- _updateFieldInfos();
|
|
|
_filterNotifier?.filters = filters;
|
|
|
return left(unit);
|
|
|
},
|
|
@@ -310,10 +489,38 @@ class GridFieldController {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ Future<Either<Unit, FlowyError>> _loadSorts() async {
|
|
|
+ return _sortFFIService.getAllSorts().then((result) {
|
|
|
+ return result.fold(
|
|
|
+ (sortPBs) {
|
|
|
+ final List<SortInfo> sortInfos = [];
|
|
|
+ for (final sortPB in sortPBs) {
|
|
|
+ final fieldInfo = _findFieldInfo(
|
|
|
+ fieldInfos: fieldInfos,
|
|
|
+ fieldId: sortPB.fieldId,
|
|
|
+ fieldType: sortPB.fieldType,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (fieldInfo != null) {
|
|
|
+ final sortInfo = SortInfo(sortPB: sortPB, fieldInfo: fieldInfo);
|
|
|
+ sortInfos.add(sortInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _updateFieldInfos();
|
|
|
+ _sortNotifier?.sorts = sortInfos;
|
|
|
+ return left(unit);
|
|
|
+ },
|
|
|
+ (err) => right(err),
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
void addListener({
|
|
|
OnReceiveFields? onFields,
|
|
|
OnReceiveUpdateFields? onFieldsUpdated,
|
|
|
OnReceiveFilters? onFilters,
|
|
|
+ OnReceiveSorts? onSorts,
|
|
|
bool Function()? listenWhen,
|
|
|
}) {
|
|
|
if (onFieldsUpdated != null) {
|
|
@@ -350,10 +557,23 @@ class GridFieldController {
|
|
|
_filterCallbacks[onFilters] = callback;
|
|
|
_filterNotifier?.addListener(callback);
|
|
|
}
|
|
|
+
|
|
|
+ if (onSorts != null) {
|
|
|
+ callback() {
|
|
|
+ if (listenWhen != null && listenWhen() == false) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ onSorts(sortInfos);
|
|
|
+ }
|
|
|
+
|
|
|
+ _sortCallbacks[onSorts] = callback;
|
|
|
+ _sortNotifier?.addListener(callback);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void removeListener({
|
|
|
OnReceiveFields? onFieldsListener,
|
|
|
+ OnReceiveSorts? onSortsListener,
|
|
|
OnReceiveFilters? onFiltersListener,
|
|
|
OnReceiveUpdateFields? onChangesetListener,
|
|
|
}) {
|
|
@@ -369,6 +589,13 @@ class GridFieldController {
|
|
|
_filterNotifier?.removeListener(callback);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (onSortsListener != null) {
|
|
|
+ final callback = _sortCallbacks.remove(onSortsListener);
|
|
|
+ if (callback != null) {
|
|
|
+ _sortNotifier?.removeListener(callback);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void _deleteFields(List<FieldIdPB> deletedFields) {
|
|
@@ -466,11 +693,13 @@ class GridRowFieldNotifierImpl extends IGridRowFieldNotifier {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-FieldInfo? _findFieldInfoForFilter(
|
|
|
- List<FieldInfo> fieldInfos, FilterPB filter) {
|
|
|
+FieldInfo? _findFieldInfo({
|
|
|
+ required List<FieldInfo> fieldInfos,
|
|
|
+ required String fieldId,
|
|
|
+ required FieldType fieldType,
|
|
|
+}) {
|
|
|
final fieldIndex = fieldInfos.indexWhere((element) {
|
|
|
- return element.id == filter.fieldId &&
|
|
|
- element.fieldType == filter.fieldType;
|
|
|
+ return element.id == fieldId && element.fieldType == fieldType;
|
|
|
});
|
|
|
if (fieldIndex != -1) {
|
|
|
return fieldInfos[fieldIndex];
|
|
@@ -485,6 +714,8 @@ class FieldInfo {
|
|
|
|
|
|
bool _hasFilter = false;
|
|
|
|
|
|
+ bool _hasSort = false;
|
|
|
+
|
|
|
String get id => _field.id;
|
|
|
|
|
|
FieldType get fieldType => _field.fieldType;
|
|
@@ -529,5 +760,18 @@ class FieldInfo {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ bool get canCreateSort {
|
|
|
+ if (_hasSort) return false;
|
|
|
+
|
|
|
+ switch (_field.fieldType) {
|
|
|
+ case FieldType.RichText:
|
|
|
+ case FieldType.Checkbox:
|
|
|
+ case FieldType.Number:
|
|
|
+ return true;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
FieldInfo({required FieldPB field}) : _field = field;
|
|
|
}
|