mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-09 06:07:54 -06:00
WIP - Implemented similar documents view
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
export 'document_model_json_converter.dart';
|
||||
export 'similar_document_model_json_converter.dart';
|
||||
export 'date_range_query_json_converter.dart';
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
|
||||
class SimilarDocumentModelJsonConverter
|
||||
extends JsonConverter<SimilarDocumentModel, Map<String, dynamic>> {
|
||||
@override
|
||||
SimilarDocumentModel fromJson(Map<String, dynamic> json) {
|
||||
return SimilarDocumentModel.fromJson(json);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson(SimilarDocumentModel object) {
|
||||
return object.toJson();
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,9 @@ class DocumentFilter extends Equatable {
|
||||
final DateRangeQuery modified;
|
||||
final TextQuery query;
|
||||
|
||||
/// Query documents similar to the document with this id.
|
||||
final int? moreLike;
|
||||
|
||||
const DocumentFilter({
|
||||
this.documentType = const IdQueryParameter.unset(),
|
||||
this.correspondent = const IdQueryParameter.unset(),
|
||||
@@ -47,6 +50,7 @@ class DocumentFilter extends Equatable {
|
||||
this.added = const UnsetDateRangeQuery(),
|
||||
this.created = const UnsetDateRangeQuery(),
|
||||
this.modified = const UnsetDateRangeQuery(),
|
||||
this.moreLike,
|
||||
});
|
||||
|
||||
bool get forceExtendedQuery {
|
||||
@@ -77,6 +81,10 @@ class DocumentFilter extends Equatable {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (moreLike != null) {
|
||||
params.add(MapEntry('more_like_id', moreLike.toString()));
|
||||
}
|
||||
// Reverse ordering can also be encoded using &reverse=1
|
||||
// Merge query params
|
||||
final queryParams = groupBy(params, (e) => e.key).map(
|
||||
@@ -107,7 +115,7 @@ class DocumentFilter extends Equatable {
|
||||
DateRangeQuery? created,
|
||||
DateRangeQuery? modified,
|
||||
TextQuery? query,
|
||||
int? selectedViewId,
|
||||
int? Function()? moreLike,
|
||||
}) {
|
||||
final newFilter = DocumentFilter(
|
||||
pageSize: pageSize ?? this.pageSize,
|
||||
@@ -123,6 +131,7 @@ class DocumentFilter extends Equatable {
|
||||
added: added ?? this.added,
|
||||
created: created ?? this.created,
|
||||
modified: modified ?? this.modified,
|
||||
moreLike: moreLike != null ? moreLike.call() : this.moreLike,
|
||||
);
|
||||
if (query?.queryType != QueryType.extended &&
|
||||
newFilter.forceExtendedQuery) {
|
||||
|
||||
@@ -48,6 +48,7 @@ DocumentFilter _$DocumentFilterFromJson(Map<String, dynamic> json) =>
|
||||
? const UnsetDateRangeQuery()
|
||||
: const DateRangeQueryJsonConverter()
|
||||
.fromJson(json['modified'] as Map<String, dynamic>),
|
||||
moreLike: json['moreLike'] as int?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DocumentFilterToJson(DocumentFilter instance) =>
|
||||
@@ -65,6 +66,7 @@ Map<String, dynamic> _$DocumentFilterToJson(DocumentFilter instance) =>
|
||||
'added': const DateRangeQueryJsonConverter().toJson(instance.added),
|
||||
'modified': const DateRangeQueryJsonConverter().toJson(instance.modified),
|
||||
'query': instance.query.toJson(),
|
||||
'moreLike': instance.moreLike,
|
||||
};
|
||||
|
||||
const _$SortFieldEnumMap = {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
||||
import 'package:paperless_api/src/models/search_hit.dart';
|
||||
|
||||
part 'document_model.g.dart';
|
||||
|
||||
@@ -37,6 +38,12 @@ class DocumentModel extends Equatable {
|
||||
final String originalFileName;
|
||||
final String? archivedFileName;
|
||||
|
||||
@JsonKey(
|
||||
name: '__search_hit__',
|
||||
includeIfNull: false,
|
||||
)
|
||||
final SearchHit? searchHit;
|
||||
|
||||
const DocumentModel({
|
||||
required this.id,
|
||||
required this.title,
|
||||
@@ -51,6 +58,7 @@ class DocumentModel extends Equatable {
|
||||
required this.originalFileName,
|
||||
this.archivedFileName,
|
||||
this.storagePath,
|
||||
this.searchHit,
|
||||
});
|
||||
|
||||
factory DocumentModel.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -25,21 +25,34 @@ DocumentModel _$DocumentModelFromJson(Map<String, dynamic> json) =>
|
||||
originalFileName: json['original_file_name'] as String,
|
||||
archivedFileName: json['archived_file_name'] as String?,
|
||||
storagePath: json['storage_path'] as int?,
|
||||
searchHit: json['__search_hit__'] == null
|
||||
? null
|
||||
: SearchHit.fromJson(json['__search_hit__'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DocumentModelToJson(DocumentModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'title': instance.title,
|
||||
'content': instance.content,
|
||||
'tags': instance.tags.toList(),
|
||||
'document_type': instance.documentType,
|
||||
'correspondent': instance.correspondent,
|
||||
'storage_path': instance.storagePath,
|
||||
'created': const LocalDateTimeJsonConverter().toJson(instance.created),
|
||||
'modified': const LocalDateTimeJsonConverter().toJson(instance.modified),
|
||||
'added': const LocalDateTimeJsonConverter().toJson(instance.added),
|
||||
'archive_serial_number': instance.archiveSerialNumber,
|
||||
'original_file_name': instance.originalFileName,
|
||||
'archived_file_name': instance.archivedFileName,
|
||||
};
|
||||
Map<String, dynamic> _$DocumentModelToJson(DocumentModel instance) {
|
||||
final val = <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'title': instance.title,
|
||||
'content': instance.content,
|
||||
'tags': instance.tags.toList(),
|
||||
'document_type': instance.documentType,
|
||||
'correspondent': instance.correspondent,
|
||||
'storage_path': instance.storagePath,
|
||||
'created': const LocalDateTimeJsonConverter().toJson(instance.created),
|
||||
'modified': const LocalDateTimeJsonConverter().toJson(instance.modified),
|
||||
'added': const LocalDateTimeJsonConverter().toJson(instance.added),
|
||||
'archive_serial_number': instance.archiveSerialNumber,
|
||||
'original_file_name': instance.originalFileName,
|
||||
'archived_file_name': instance.archivedFileName,
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('__search_hit__', instance.searchHit);
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ export 'paperless_server_exception.dart';
|
||||
export 'paperless_server_information_model.dart';
|
||||
export 'paperless_server_statistics_model.dart';
|
||||
export 'saved_view_model.dart';
|
||||
export 'similar_document_model.dart';
|
||||
export 'task/task.dart';
|
||||
export 'task/task_status.dart';
|
||||
export 'field_suggestions.dart';
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
||||
import 'package:paperless_api/src/models/document_model.dart';
|
||||
import 'package:paperless_api/src/models/search_hit.dart';
|
||||
|
||||
part 'similar_document_model.g.dart';
|
||||
|
||||
@LocalDateTimeJsonConverter()
|
||||
@JsonSerializable()
|
||||
class SimilarDocumentModel extends DocumentModel {
|
||||
@JsonKey(name: '__search_hit__')
|
||||
final SearchHit searchHit;
|
||||
|
||||
const SimilarDocumentModel({
|
||||
required super.id,
|
||||
required super.title,
|
||||
required super.documentType,
|
||||
required super.correspondent,
|
||||
required super.created,
|
||||
required super.modified,
|
||||
required super.added,
|
||||
required super.originalFileName,
|
||||
required this.searchHit,
|
||||
super.archiveSerialNumber,
|
||||
super.archivedFileName,
|
||||
super.content,
|
||||
super.storagePath,
|
||||
super.tags,
|
||||
});
|
||||
|
||||
factory SimilarDocumentModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$SimilarDocumentModelFromJson(json);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() => _$SimilarDocumentModelToJson(this);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'similar_document_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SimilarDocumentModel _$SimilarDocumentModelFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
SimilarDocumentModel(
|
||||
id: json['id'] as int,
|
||||
title: json['title'] as String,
|
||||
documentType: json['documentType'] as int?,
|
||||
correspondent: json['correspondent'] as int?,
|
||||
created: const LocalDateTimeJsonConverter()
|
||||
.fromJson(json['created'] as String),
|
||||
modified: const LocalDateTimeJsonConverter()
|
||||
.fromJson(json['modified'] as String),
|
||||
added:
|
||||
const LocalDateTimeJsonConverter().fromJson(json['added'] as String),
|
||||
originalFileName: json['originalFileName'] as String,
|
||||
searchHit:
|
||||
SearchHit.fromJson(json['__search_hit__'] as Map<String, dynamic>),
|
||||
archiveSerialNumber: json['archiveSerialNumber'] as int?,
|
||||
archivedFileName: json['archivedFileName'] as String?,
|
||||
content: json['content'] as String?,
|
||||
storagePath: json['storagePath'] as int?,
|
||||
tags: (json['tags'] as List<dynamic>?)?.map((e) => e as int) ??
|
||||
const <int>[],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SimilarDocumentModelToJson(
|
||||
SimilarDocumentModel instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'title': instance.title,
|
||||
'content': instance.content,
|
||||
'tags': instance.tags.toList(),
|
||||
'documentType': instance.documentType,
|
||||
'correspondent': instance.correspondent,
|
||||
'storagePath': instance.storagePath,
|
||||
'created': const LocalDateTimeJsonConverter().toJson(instance.created),
|
||||
'modified': const LocalDateTimeJsonConverter().toJson(instance.modified),
|
||||
'added': const LocalDateTimeJsonConverter().toJson(instance.added),
|
||||
'archiveSerialNumber': instance.archiveSerialNumber,
|
||||
'originalFileName': instance.originalFileName,
|
||||
'archivedFileName': instance.archivedFileName,
|
||||
'__search_hit__': instance.searchHit,
|
||||
};
|
||||
@@ -18,7 +18,6 @@ abstract class PaperlessDocumentsApi {
|
||||
Future<int> findNextAsn();
|
||||
Future<PagedSearchResult<DocumentModel>> findAll(DocumentFilter filter);
|
||||
Future<DocumentModel?> find(int id);
|
||||
Future<List<SimilarDocumentModel>> findSimilar(int docId);
|
||||
Future<int> delete(DocumentModel doc);
|
||||
Future<DocumentMetaData> getMetaData(DocumentModel document);
|
||||
Future<Iterable<int>> bulkAction(BulkAction action);
|
||||
|
||||
@@ -241,27 +241,6 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<SimilarDocumentModel>> findSimilar(int docId) async {
|
||||
try {
|
||||
final response =
|
||||
await client.get("/api/documents/?more_like=$docId&pageSize=10");
|
||||
if (response.statusCode == 200) {
|
||||
return (await compute(
|
||||
PagedSearchResult<SimilarDocumentModel>.fromJsonSingleParam,
|
||||
PagedSearchResultJsonSerializer(
|
||||
response.data,
|
||||
SimilarDocumentModelJsonConverter(),
|
||||
),
|
||||
))
|
||||
.results;
|
||||
}
|
||||
throw const PaperlessServerException(ErrorCode.similarQueryError);
|
||||
} on DioError catch (err) {
|
||||
throw err.error;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<FieldSuggestions> findSuggestions(DocumentModel document) async {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user