feat: Add debug output for label repository calls

This commit is contained in:
Anton Stubenbord
2023-06-03 15:39:27 +02:00
parent 880695e04f
commit 2f25a948ee
4 changed files with 186 additions and 88 deletions

View File

@@ -10,21 +10,26 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
LabelRepository(this._api) : super(const LabelRepositoryState()); LabelRepository(this._api) : super(const LabelRepositoryState());
Future<void> initialize() { Future<void> initialize() async {
debugPrint("Initializing labels..."); debugPrint("[LabelRepository] initialize() called.");
return Future.wait([ try {
findAllCorrespondents(), await Future.wait([
findAllDocumentTypes(), findAllCorrespondents(),
findAllStoragePaths(), findAllDocumentTypes(),
findAllTags(), findAllStoragePaths(),
]).catchError((error) { findAllTags(),
debugPrint(error.toString()); ]);
}, test: (error) => false); } catch (error, stackTrace) {
debugPrint(
"[LabelRepository] An error occurred in initialize(): ${error.toString()}");
debugPrintStack(stackTrace: stackTrace);
}
} }
Future<Tag> createTag(Tag object) async { Future<Tag> createTag(Tag object) async {
final created = await _api.saveTag(object); final created = await _api.saveTag(object);
final updatedState = {...state.tags}..putIfAbsent(created.id!, () => created); final updatedState = {...state.tags}
..putIfAbsent(created.id!, () => created);
emit(state.copyWith(tags: updatedState)); emit(state.copyWith(tags: updatedState));
return created; return created;
} }
@@ -48,7 +53,8 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
Future<Iterable<Tag>> findAllTags([Iterable<int>? ids]) async { Future<Iterable<Tag>> findAllTags([Iterable<int>? ids]) async {
final tags = await _api.getTags(ids); final tags = await _api.getTags(ids);
final updatedState = {...state.tags}..addEntries(tags.map((e) => MapEntry(e.id!, e))); final updatedState = {...state.tags}
..addEntries(tags.map((e) => MapEntry(e.id!, e)));
emit(state.copyWith(tags: updatedState)); emit(state.copyWith(tags: updatedState));
return tags; return tags;
} }
@@ -62,14 +68,16 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
Future<Correspondent> createCorrespondent(Correspondent correspondent) async { Future<Correspondent> createCorrespondent(Correspondent correspondent) async {
final created = await _api.saveCorrespondent(correspondent); final created = await _api.saveCorrespondent(correspondent);
final updatedState = {...state.correspondents}..putIfAbsent(created.id!, () => created); final updatedState = {...state.correspondents}
..putIfAbsent(created.id!, () => created);
emit(state.copyWith(correspondents: updatedState)); emit(state.copyWith(correspondents: updatedState));
return created; return created;
} }
Future<int> deleteCorrespondent(Correspondent correspondent) async { Future<int> deleteCorrespondent(Correspondent correspondent) async {
await _api.deleteCorrespondent(correspondent); await _api.deleteCorrespondent(correspondent);
final updatedState = {...state.correspondents}..removeWhere((k, v) => k == correspondent.id); final updatedState = {...state.correspondents}
..removeWhere((k, v) => k == correspondent.id);
emit(state.copyWith(correspondents: updatedState)); emit(state.copyWith(correspondents: updatedState));
return correspondent.id!; return correspondent.id!;
@@ -86,22 +94,22 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
return null; return null;
} }
Future<Iterable<Correspondent>> findAllCorrespondents([Iterable<int>? ids]) async { Future<Iterable<Correspondent>> findAllCorrespondents(
[Iterable<int>? ids]) async {
debugPrint("Loading correspondents..."); debugPrint("Loading correspondents...");
final correspondents = await _api.getCorrespondents(ids); final correspondents = await _api.getCorrespondents(ids);
debugPrint("${correspondents.length} correspondents successfully loaded."); debugPrint("${correspondents.length} correspondents successfully loaded.");
final updatedState = { final updatedState = {
...state.correspondents, ...state.correspondents,
}..addAll({for (var element in correspondents) element.id!: element}); }..addAll({for (var element in correspondents) element.id!: element});
debugPrint("Pushing new correspondents state.");
emit(state.copyWith(correspondents: updatedState)); emit(state.copyWith(correspondents: updatedState));
debugPrint("New correspondents state pushed.");
return correspondents; return correspondents;
} }
Future<Correspondent> updateCorrespondent(Correspondent correspondent) async { Future<Correspondent> updateCorrespondent(Correspondent correspondent) async {
final updated = await _api.updateCorrespondent(correspondent); final updated = await _api.updateCorrespondent(correspondent);
final updatedState = {...state.correspondents}..update(updated.id!, (_) => updated); final updatedState = {...state.correspondents}
..update(updated.id!, (_) => updated);
emit(state.copyWith(correspondents: updatedState)); emit(state.copyWith(correspondents: updatedState));
return updated; return updated;
@@ -109,14 +117,16 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
Future<DocumentType> createDocumentType(DocumentType documentType) async { Future<DocumentType> createDocumentType(DocumentType documentType) async {
final created = await _api.saveDocumentType(documentType); final created = await _api.saveDocumentType(documentType);
final updatedState = {...state.documentTypes}..putIfAbsent(created.id!, () => created); final updatedState = {...state.documentTypes}
..putIfAbsent(created.id!, () => created);
emit(state.copyWith(documentTypes: updatedState)); emit(state.copyWith(documentTypes: updatedState));
return created; return created;
} }
Future<int> deleteDocumentType(DocumentType documentType) async { Future<int> deleteDocumentType(DocumentType documentType) async {
await _api.deleteDocumentType(documentType); await _api.deleteDocumentType(documentType);
final updatedState = {...state.documentTypes}..removeWhere((k, v) => k == documentType.id); final updatedState = {...state.documentTypes}
..removeWhere((k, v) => k == documentType.id);
emit(state.copyWith(documentTypes: updatedState)); emit(state.copyWith(documentTypes: updatedState));
return documentType.id!; return documentType.id!;
} }
@@ -131,7 +141,8 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
return null; return null;
} }
Future<Iterable<DocumentType>> findAllDocumentTypes([Iterable<int>? ids]) async { Future<Iterable<DocumentType>> findAllDocumentTypes(
[Iterable<int>? ids]) async {
final documentTypes = await _api.getDocumentTypes(ids); final documentTypes = await _api.getDocumentTypes(ids);
final updatedState = {...state.documentTypes} final updatedState = {...state.documentTypes}
..addEntries(documentTypes.map((e) => MapEntry(e.id!, e))); ..addEntries(documentTypes.map((e) => MapEntry(e.id!, e)));
@@ -141,21 +152,24 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
Future<DocumentType> updateDocumentType(DocumentType documentType) async { Future<DocumentType> updateDocumentType(DocumentType documentType) async {
final updated = await _api.updateDocumentType(documentType); final updated = await _api.updateDocumentType(documentType);
final updatedState = {...state.documentTypes}..update(updated.id!, (_) => updated); final updatedState = {...state.documentTypes}
..update(updated.id!, (_) => updated);
emit(state.copyWith(documentTypes: updatedState)); emit(state.copyWith(documentTypes: updatedState));
return updated; return updated;
} }
Future<StoragePath> createStoragePath(StoragePath storagePath) async { Future<StoragePath> createStoragePath(StoragePath storagePath) async {
final created = await _api.saveStoragePath(storagePath); final created = await _api.saveStoragePath(storagePath);
final updatedState = {...state.storagePaths}..putIfAbsent(created.id!, () => created); final updatedState = {...state.storagePaths}
..putIfAbsent(created.id!, () => created);
emit(state.copyWith(storagePaths: updatedState)); emit(state.copyWith(storagePaths: updatedState));
return created; return created;
} }
Future<int> deleteStoragePath(StoragePath storagePath) async { Future<int> deleteStoragePath(StoragePath storagePath) async {
await _api.deleteStoragePath(storagePath); await _api.deleteStoragePath(storagePath);
final updatedState = {...state.storagePaths}..removeWhere((k, v) => k == storagePath.id); final updatedState = {...state.storagePaths}
..removeWhere((k, v) => k == storagePath.id);
emit(state.copyWith(storagePaths: updatedState)); emit(state.copyWith(storagePaths: updatedState));
return storagePath.id!; return storagePath.id!;
} }
@@ -170,7 +184,8 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
return null; return null;
} }
Future<Iterable<StoragePath>> findAllStoragePaths([Iterable<int>? ids]) async { Future<Iterable<StoragePath>> findAllStoragePaths(
[Iterable<int>? ids]) async {
final storagePaths = await _api.getStoragePaths(ids); final storagePaths = await _api.getStoragePaths(ids);
final updatedState = {...state.storagePaths} final updatedState = {...state.storagePaths}
..addEntries(storagePaths.map((e) => MapEntry(e.id!, e))); ..addEntries(storagePaths.map((e) => MapEntry(e.id!, e)));
@@ -180,7 +195,8 @@ class LabelRepository extends PersistentRepository<LabelRepositoryState> {
Future<StoragePath> updateStoragePath(StoragePath storagePath) async { Future<StoragePath> updateStoragePath(StoragePath storagePath) async {
final updated = await _api.updateStoragePath(storagePath); final updated = await _api.updateStoragePath(storagePath);
final updatedState = {...state.storagePaths}..update(updated.id!, (_) => updated); final updatedState = {...state.storagePaths}
..update(updated.id!, (_) => updated);
emit(state.copyWith(storagePaths: updatedState)); emit(state.copyWith(storagePaths: updatedState));
return updated; return updated;
} }

View File

@@ -233,10 +233,28 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
BlocListener<ConnectivityCubit, ConnectivityState>( BlocListener<ConnectivityCubit, ConnectivityState>(
// If app was started offline, load data once it comes back online. // If app was started offline, load data once it comes back online.
listenWhen: (previous, current) => listenWhen: (previous, current) =>
previous != ConnectivityState.connected &&
current == ConnectivityState.connected, current == ConnectivityState.connected,
listener: (context, state) { listener: (context, state) async {
context.read<LabelRepository>().initialize(); try {
context.read<SavedViewRepository>().initialize(); debugPrint(
"[HomePage] BlocListener#listener: "
"Loading saved views and labels...",
);
await Future.wait([
context.read<LabelRepository>().initialize(),
context.read<SavedViewRepository>().initialize(),
]);
debugPrint("[HomePage] BlocListener#listener: "
"Saved views and labels successfully loaded.");
} catch (error, stackTrace) {
debugPrint(
'[HomePage] BlocListener.listener: '
'An error occurred while loading saved views and labels.\n'
'${error.toString()}',
);
debugPrintStack(stackTrace: stackTrace);
}
}, },
), ),
BlocListener<TaskStatusCubit, TaskStatusState>( BlocListener<TaskStatusCubit, TaskStatusState>(

View File

@@ -29,9 +29,12 @@ class LabelsPage extends StatefulWidget {
State<LabelsPage> createState() => _LabelsPageState(); State<LabelsPage> createState() => _LabelsPageState();
} }
class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateMixin { class _LabelsPageState extends State<LabelsPage>
final SliverOverlapAbsorberHandle searchBarHandle = SliverOverlapAbsorberHandle(); with SingleTickerProviderStateMixin {
final SliverOverlapAbsorberHandle tabBarHandle = SliverOverlapAbsorberHandle(); final SliverOverlapAbsorberHandle searchBarHandle =
SliverOverlapAbsorberHandle();
final SliverOverlapAbsorberHandle tabBarHandle =
SliverOverlapAbsorberHandle();
late final TabController _tabController; late final TabController _tabController;
int _currentIndex = 0; int _currentIndex = 0;
@@ -81,25 +84,33 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
Tab( Tab(
icon: Icon( icon: Icon(
Icons.person_outline, Icons.person_outline,
color: Theme.of(context).colorScheme.onPrimaryContainer, color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
), ),
), ),
Tab( Tab(
icon: Icon( icon: Icon(
Icons.description_outlined, Icons.description_outlined,
color: Theme.of(context).colorScheme.onPrimaryContainer, color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
), ),
), ),
Tab( Tab(
icon: Icon( icon: Icon(
Icons.label_outline, Icons.label_outline,
color: Theme.of(context).colorScheme.onPrimaryContainer, color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
), ),
), ),
Tab( Tab(
icon: Icon( icon: Icon(
Icons.folder_open, Icons.folder_open,
color: Theme.of(context).colorScheme.onPrimaryContainer, color: Theme.of(context)
.colorScheme
.onPrimaryContainer,
), ),
), ),
], ],
@@ -118,25 +129,44 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
if (metrics.maxScrollExtent == 0) { if (metrics.maxScrollExtent == 0) {
return true; return true;
} }
final desiredTab = ((metrics.pixels / metrics.maxScrollExtent) * final desiredTab =
(_tabController.length - 1)) ((metrics.pixels / metrics.maxScrollExtent) *
.round(); (_tabController.length - 1))
.round();
if (metrics.axis == Axis.horizontal && _currentIndex != desiredTab) { if (metrics.axis == Axis.horizontal &&
_currentIndex != desiredTab) {
setState(() => _currentIndex = desiredTab); setState(() => _currentIndex = desiredTab);
} }
return true; return true;
}, },
child: RefreshIndicator( child: RefreshIndicator(
edgeOffset: kTextTabBarHeight, edgeOffset: kTextTabBarHeight,
notificationPredicate: (notification) => connectedState.isConnected, notificationPredicate: (notification) =>
onRefresh: () => [ connectedState.isConnected,
context.read<LabelCubit>().reloadCorrespondents, onRefresh: () async {
context.read<LabelCubit>().reloadDocumentTypes, try {
context.read<LabelCubit>().reloadTags, await [
context.read<LabelCubit>().reloadStoragePaths, context.read<LabelCubit>().reloadCorrespondents,
][_currentIndex] context.read<LabelCubit>().reloadDocumentTypes,
.call(), context.read<LabelCubit>().reloadTags,
context.read<LabelCubit>().reloadStoragePaths,
][_currentIndex]
.call();
} catch (error, stackTrace) {
debugPrint(
"[LabelsPage] RefreshIndicator.onRefresh "
"${[
"correspondents",
"document types",
"tags",
"storage paths"
][_currentIndex]}: "
"An error occurred (${error.toString()})",
);
debugPrintStack(stackTrace: stackTrace);
}
},
child: TabBarView( child: TabBarView(
controller: _tabController, controller: _tabController,
children: [ children: [
@@ -144,22 +174,29 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
builder: (context) { builder: (context) {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverOverlapInjector(handle: searchBarHandle), SliverOverlapInjector(
handle: searchBarHandle),
SliverOverlapInjector(handle: tabBarHandle), SliverOverlapInjector(handle: tabBarHandle),
LabelTabView<Correspondent>( LabelTabView<Correspondent>(
labels: state.correspondents, labels: state.correspondents,
filterBuilder: (label) => DocumentFilter( filterBuilder: (label) => DocumentFilter(
correspondent: IdQueryParameter.fromId(label.id!), correspondent:
IdQueryParameter.fromId(label.id!),
), ),
canEdit: LocalUserAccount.current.paperlessUser.hasPermission( canEdit: LocalUserAccount
PermissionAction.change, PermissionTarget.correspondent), .current.paperlessUser
canAddNew: LocalUserAccount.current.paperlessUser
.hasPermission( .hasPermission(
PermissionAction.add, PermissionTarget.correspondent), PermissionAction.change,
PermissionTarget.correspondent),
canAddNew: LocalUserAccount
.current.paperlessUser
.hasPermission(PermissionAction.add,
PermissionTarget.correspondent),
onEdit: _openEditCorrespondentPage, onEdit: _openEditCorrespondentPage,
emptyStateActionButtonLabel: emptyStateActionButtonLabel:
S.of(context)!.addNewCorrespondent, S.of(context)!.addNewCorrespondent,
emptyStateDescription: S.of(context)!.noCorrespondentsSetUp, emptyStateDescription:
S.of(context)!.noCorrespondentsSetUp,
onAddNew: _openAddCorrespondentPage, onAddNew: _openAddCorrespondentPage,
), ),
], ],
@@ -170,22 +207,29 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
builder: (context) { builder: (context) {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverOverlapInjector(handle: searchBarHandle), SliverOverlapInjector(
handle: searchBarHandle),
SliverOverlapInjector(handle: tabBarHandle), SliverOverlapInjector(handle: tabBarHandle),
LabelTabView<DocumentType>( LabelTabView<DocumentType>(
labels: state.documentTypes, labels: state.documentTypes,
filterBuilder: (label) => DocumentFilter( filterBuilder: (label) => DocumentFilter(
documentType: IdQueryParameter.fromId(label.id!), documentType:
IdQueryParameter.fromId(label.id!),
), ),
canEdit: LocalUserAccount.current.paperlessUser.hasPermission( canEdit: LocalUserAccount
PermissionAction.change, PermissionTarget.documentType), .current.paperlessUser
canAddNew: LocalUserAccount.current.paperlessUser
.hasPermission( .hasPermission(
PermissionAction.add, PermissionTarget.documentType), PermissionAction.change,
PermissionTarget.documentType),
canAddNew: LocalUserAccount
.current.paperlessUser
.hasPermission(PermissionAction.add,
PermissionTarget.documentType),
onEdit: _openEditDocumentTypePage, onEdit: _openEditDocumentTypePage,
emptyStateActionButtonLabel: emptyStateActionButtonLabel:
S.of(context)!.addNewDocumentType, S.of(context)!.addNewDocumentType,
emptyStateDescription: S.of(context)!.noDocumentTypesSetUp, emptyStateDescription:
S.of(context)!.noDocumentTypesSetUp,
onAddNew: _openAddDocumentTypePage, onAddNew: _openAddDocumentTypePage,
), ),
], ],
@@ -196,18 +240,24 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
builder: (context) { builder: (context) {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverOverlapInjector(handle: searchBarHandle), SliverOverlapInjector(
handle: searchBarHandle),
SliverOverlapInjector(handle: tabBarHandle), SliverOverlapInjector(handle: tabBarHandle),
LabelTabView<Tag>( LabelTabView<Tag>(
labels: state.tags, labels: state.tags,
filterBuilder: (label) => DocumentFilter( filterBuilder: (label) => DocumentFilter(
tags: TagsQuery.ids(include: [label.id!]), tags:
TagsQuery.ids(include: [label.id!]),
), ),
canEdit: LocalUserAccount.current.paperlessUser.hasPermission( canEdit: LocalUserAccount
PermissionAction.change, PermissionTarget.tag), .current.paperlessUser
canAddNew: LocalUserAccount.current.paperlessUser
.hasPermission( .hasPermission(
PermissionAction.add, PermissionTarget.tag), PermissionAction.change,
PermissionTarget.tag),
canAddNew: LocalUserAccount
.current.paperlessUser
.hasPermission(PermissionAction.add,
PermissionTarget.tag),
onEdit: _openEditTagPage, onEdit: _openEditTagPage,
leadingBuilder: (t) => CircleAvatar( leadingBuilder: (t) => CircleAvatar(
backgroundColor: t.color, backgroundColor: t.color,
@@ -218,8 +268,10 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
) )
: null, : null,
), ),
emptyStateActionButtonLabel: S.of(context)!.addNewTag, emptyStateActionButtonLabel:
emptyStateDescription: S.of(context)!.noTagsSetUp, S.of(context)!.addNewTag,
emptyStateDescription:
S.of(context)!.noTagsSetUp,
onAddNew: _openAddTagPage, onAddNew: _openAddTagPage,
), ),
], ],
@@ -230,22 +282,30 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
builder: (context) { builder: (context) {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverOverlapInjector(handle: searchBarHandle), SliverOverlapInjector(
handle: searchBarHandle),
SliverOverlapInjector(handle: tabBarHandle), SliverOverlapInjector(handle: tabBarHandle),
LabelTabView<StoragePath>( LabelTabView<StoragePath>(
labels: state.storagePaths, labels: state.storagePaths,
onEdit: _openEditStoragePathPage, onEdit: _openEditStoragePathPage,
filterBuilder: (label) => DocumentFilter( filterBuilder: (label) => DocumentFilter(
storagePath: IdQueryParameter.fromId(label.id!), storagePath:
IdQueryParameter.fromId(label.id!),
), ),
canEdit: LocalUserAccount.current.paperlessUser.hasPermission( canEdit: LocalUserAccount
PermissionAction.change, PermissionTarget.storagePath), .current.paperlessUser
canAddNew: LocalUserAccount.current.paperlessUser
.hasPermission( .hasPermission(
PermissionAction.add, PermissionTarget.storagePath), PermissionAction.change,
PermissionTarget.storagePath),
canAddNew: LocalUserAccount
.current.paperlessUser
.hasPermission(PermissionAction.add,
PermissionTarget.storagePath),
contentBuilder: (path) => Text(path.path), contentBuilder: (path) => Text(path.path),
emptyStateActionButtonLabel: S.of(context)!.addNewStoragePath, emptyStateActionButtonLabel:
emptyStateDescription: S.of(context)!.noStoragePathsSetUp, S.of(context)!.addNewStoragePath,
emptyStateDescription:
S.of(context)!.noStoragePathsSetUp,
onAddNew: _openAddStoragePathPage, onAddNew: _openAddStoragePathPage,
), ),
], ],
@@ -326,13 +386,13 @@ class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateM
MaterialPageRoute<dynamic> _buildLabelPageRoute(Widget page) { MaterialPageRoute<dynamic> _buildLabelPageRoute(Widget page) {
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => MultiProvider( builder: (_) => MultiProvider(
providers: [ providers: [
Provider.value(value: context.read<LabelRepository>()), Provider.value(value: context.read<LabelRepository>()),
Provider.value(value: context.read<ApiVersion>()) Provider.value(value: context.read<ApiVersion>())
], ],
child: page child: page,
) ),
); );
} }
} }

View File

@@ -115,7 +115,9 @@ class DocumentFilter extends Equatable {
final queryParams = groupBy(params, (e) => e.key).map( final queryParams = groupBy(params, (e) => e.key).map(
(key, entries) => MapEntry( (key, entries) => MapEntry(
key, key,
entries.length == 1 ? entries.first.value : entries.map((e) => e.value).join(","), entries.length == 1
? entries.first.value
: entries.map((e) => e.value).join(","),
), ),
); );
return queryParams; return queryParams;
@@ -156,7 +158,8 @@ class DocumentFilter extends Equatable {
modified: modified ?? this.modified, modified: modified ?? this.modified,
moreLike: moreLike != null ? moreLike.call() : this.moreLike, moreLike: moreLike != null ? moreLike.call() : this.moreLike,
); );
if (query?.queryType != QueryType.extended && newFilter.forceExtendedQuery) { if (query?.queryType != QueryType.extended &&
newFilter.forceExtendedQuery) {
//Prevents infinite recursion //Prevents infinite recursion
return newFilter.copyWith( return newFilter.copyWith(
query: newFilter.query.copyWith(queryType: QueryType.extended), query: newFilter.query.copyWith(queryType: QueryType.extended),
@@ -212,7 +215,8 @@ class DocumentFilter extends Equatable {
query, query,
]; ];
factory DocumentFilter.fromJson(Map<String, dynamic> json) => _$DocumentFilterFromJson(json); factory DocumentFilter.fromJson(Map<String, dynamic> json) =>
_$DocumentFilterFromJson(json);
Map<String, dynamic> toJson() => _$DocumentFilterToJson(this); Map<String, dynamic> toJson() => _$DocumentFilterToJson(this);
} }