mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-10 14:07:59 -06:00
Add migration scripts, remove dependencies to codegen, and cleanups
This commit is contained in:
@@ -36,9 +36,9 @@ class PaperlessApiHiveTypeIds {
|
||||
void registerPaperlessApiHiveTypeAdapters() {
|
||||
Hive.registerAdapter(DocumentFilterAdapter());
|
||||
// TagsQuery
|
||||
Hive.registerAdapter(AnyAssignedTagsQueryImplAdapter());
|
||||
Hive.registerAdapter(NotAssignedTagsQueryImplAdapter());
|
||||
Hive.registerAdapter(IdsTagsQueryImplAdapter());
|
||||
Hive.registerAdapter(AnyAssignedTagsQueryAdapter());
|
||||
Hive.registerAdapter(NotAssignedTagsQueryAdapter());
|
||||
Hive.registerAdapter(IdsTagsQueryAdapter());
|
||||
|
||||
Hive.registerAdapter(SortFieldAdapter());
|
||||
Hive.registerAdapter(SortOrderAdapter());
|
||||
@@ -49,13 +49,13 @@ void registerPaperlessApiHiveTypeAdapters() {
|
||||
Hive.registerAdapter(TextQueryAdapter());
|
||||
Hive.registerAdapter(QueryTypeAdapter());
|
||||
// IdQueryParameter
|
||||
Hive.registerAdapter(SetIdQueryParameterImplAdapter());
|
||||
Hive.registerAdapter(UnsetIdQueryParameterImplAdapter());
|
||||
Hive.registerAdapter(AnyAssignedIdQueryParameterImplAdapter());
|
||||
Hive.registerAdapter(NotAssignedIdQueryParameterImplAdapter());
|
||||
Hive.registerAdapter(SetIdQueryParameterAdapter());
|
||||
Hive.registerAdapter(UnsetIdQueryParameterAdapter());
|
||||
Hive.registerAdapter(AnyAssignedIdQueryParameterAdapter());
|
||||
Hive.registerAdapter(NotAssignedIdQueryParameterAdapter());
|
||||
// Users and permissions
|
||||
Hive.registerAdapter(UserModelV3ImplAdapter());
|
||||
Hive.registerAdapter(UserModelV2ImplAdapter());
|
||||
Hive.registerAdapter(UserModelV3Adapter());
|
||||
Hive.registerAdapter(UserModelV2Adapter());
|
||||
Hive.registerAdapter(GroupModelAdapter());
|
||||
Hive.registerAdapter(PermissionsAdapter());
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ import 'package:equatable/equatable.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query.dart';
|
||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query_field.dart';
|
||||
|
||||
part 'document_filter.g.dart';
|
||||
|
||||
@DateRangeQueryJsonConverter()
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
// @JsonSerializable(explicitToJson: true)
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.documentFilter)
|
||||
class DocumentFilter extends Equatable {
|
||||
static const DocumentFilter initial = DocumentFilter();
|
||||
@@ -67,11 +66,11 @@ class DocumentFilter extends Equatable {
|
||||
final int? selectedView;
|
||||
|
||||
const DocumentFilter({
|
||||
this.documentType = const IdQueryParameter.unset(),
|
||||
this.correspondent = const IdQueryParameter.unset(),
|
||||
this.storagePath = const IdQueryParameter.unset(),
|
||||
this.asnQuery = const IdQueryParameter.unset(),
|
||||
this.tags = const TagsQuery.ids(),
|
||||
this.documentType = const UnsetIdQueryParameter(),
|
||||
this.correspondent = const UnsetIdQueryParameter(),
|
||||
this.storagePath = const UnsetIdQueryParameter(),
|
||||
this.asnQuery = const UnsetIdQueryParameter(),
|
||||
this.tags = const IdsTagsQuery(),
|
||||
this.sortField = SortField.created,
|
||||
this.sortOrder = SortOrder.descending,
|
||||
this.page = 1,
|
||||
@@ -164,7 +163,8 @@ class DocumentFilter extends Equatable {
|
||||
created: created ?? this.created,
|
||||
modified: modified ?? this.modified,
|
||||
moreLike: moreLike != null ? moreLike.call() : this.moreLike,
|
||||
selectedView: selectedView != null ? selectedView.call() : this.selectedView,
|
||||
selectedView:
|
||||
selectedView != null ? selectedView.call() : this.selectedView,
|
||||
);
|
||||
if (query?.queryType != QueryType.extended &&
|
||||
newFilter.forceExtendedQuery) {
|
||||
@@ -195,24 +195,23 @@ class DocumentFilter extends Equatable {
|
||||
}
|
||||
|
||||
int get appliedFiltersCount => [
|
||||
documentType.maybeWhen(
|
||||
unset: () => 0,
|
||||
orElse: () => 1,
|
||||
),
|
||||
correspondent.maybeWhen(
|
||||
unset: () => 0,
|
||||
orElse: () => 1,
|
||||
),
|
||||
storagePath.maybeWhen(
|
||||
unset: () => 0,
|
||||
orElse: () => 1,
|
||||
),
|
||||
tags.maybeWhen(
|
||||
ids: (include, exclude) => include.length + exclude.length,
|
||||
anyAssigned: (tagIds) => tagIds.length,
|
||||
notAssigned: () => 1,
|
||||
orElse: () => 0,
|
||||
),
|
||||
switch (documentType) {
|
||||
UnsetIdQueryParameter() => 0,
|
||||
_ => 1,
|
||||
},
|
||||
switch (correspondent) {
|
||||
UnsetIdQueryParameter() => 0,
|
||||
_ => 1,
|
||||
},
|
||||
switch (storagePath) {
|
||||
UnsetIdQueryParameter() => 0,
|
||||
_ => 1,
|
||||
},
|
||||
switch (tags) {
|
||||
NotAssignedTagsQuery() => 1,
|
||||
AnyAssignedTagsQuery(tagIds: var tags) => tags.length,
|
||||
IdsTagsQuery(include: var i, exclude: var e) => e.length + i.length,
|
||||
},
|
||||
switch (added) {
|
||||
RelativeDateRangeQuery() => 1,
|
||||
AbsoluteDateRangeQuery() => 1,
|
||||
@@ -228,10 +227,10 @@ class DocumentFilter extends Equatable {
|
||||
AbsoluteDateRangeQuery() => 1,
|
||||
UnsetDateRangeQuery() => 0,
|
||||
},
|
||||
asnQuery.maybeWhen(
|
||||
unset: () => 0,
|
||||
orElse: () => 1,
|
||||
),
|
||||
switch (asnQuery) {
|
||||
UnsetIdQueryParameter() => 0,
|
||||
_ => 1,
|
||||
},
|
||||
(query.queryText?.isNotEmpty ?? false) ? 1 : 0,
|
||||
].fold(0, (previousValue, element) => previousValue + element);
|
||||
|
||||
@@ -254,8 +253,8 @@ class DocumentFilter extends Equatable {
|
||||
selectedView,
|
||||
];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@ import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_api/src/constants.dart';
|
||||
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query.dart';
|
||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query_field.dart';
|
||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_unit.dart';
|
||||
|
||||
part 'filter_rule_model.g.dart';
|
||||
|
||||
@@ -59,48 +57,49 @@ class FilterRule with EquatableMixin {
|
||||
case documentTypeRule:
|
||||
return filter.copyWith(
|
||||
documentType: value == null
|
||||
? const IdQueryParameter.notAssigned()
|
||||
: IdQueryParameter.fromId(int.parse(value!)),
|
||||
? const NotAssignedIdQueryParameter()
|
||||
: SetIdQueryParameter(id: int.parse(value!)),
|
||||
);
|
||||
case correspondentRule:
|
||||
return filter.copyWith(
|
||||
correspondent: value == null
|
||||
? const IdQueryParameter.notAssigned()
|
||||
: IdQueryParameter.fromId(int.parse(value!)),
|
||||
? const NotAssignedIdQueryParameter()
|
||||
: SetIdQueryParameter(id: int.parse(value!)),
|
||||
);
|
||||
case storagePathRule:
|
||||
return filter.copyWith(
|
||||
storagePath: value == null
|
||||
? const IdQueryParameter.notAssigned()
|
||||
: IdQueryParameter.fromId(int.parse(value!)),
|
||||
? const NotAssignedIdQueryParameter()
|
||||
: SetIdQueryParameter(id: int.parse(value!)),
|
||||
);
|
||||
case hasAnyTag:
|
||||
return filter.copyWith(
|
||||
tags: value == "true"
|
||||
? const TagsQuery.anyAssigned()
|
||||
: const TagsQuery.notAssigned(),
|
||||
? const AnyAssignedTagsQuery()
|
||||
: const NotAssignedTagsQuery(),
|
||||
);
|
||||
case includeTagsRule:
|
||||
assert(filter.tags is IdsTagsQuery);
|
||||
return filter.copyWith(
|
||||
tags: filter.tags.maybeWhen(
|
||||
ids: (include, exclude) => TagsQuery.ids(
|
||||
include: [...include, int.parse(value!)],
|
||||
exclude: exclude,
|
||||
),
|
||||
orElse: () => filter.tags,
|
||||
),
|
||||
tags: switch (filter.tags) {
|
||||
// TODO: Handle this case.
|
||||
IdsTagsQuery(include: var i, exclude: var e) => IdsTagsQuery(
|
||||
include: [...i, int.parse(value!)],
|
||||
exclude: e,
|
||||
),
|
||||
_ => filter.tags,
|
||||
},
|
||||
);
|
||||
case excludeTagsRule:
|
||||
assert(filter.tags is IdsTagsQuery);
|
||||
return filter.copyWith(
|
||||
tags: filter.tags.maybeWhen(
|
||||
ids: (include, exclude) => TagsQuery.ids(
|
||||
include: include,
|
||||
exclude: [...exclude, int.parse(value!)],
|
||||
),
|
||||
orElse: () => filter.tags,
|
||||
),
|
||||
tags: switch (filter.tags) {
|
||||
IdsTagsQuery(include: var i, exclude: var e) => IdsTagsQuery(
|
||||
include: i,
|
||||
exclude: [...e, int.parse(value!)],
|
||||
),
|
||||
_ => filter.tags,
|
||||
},
|
||||
);
|
||||
case createdBeforeRule:
|
||||
if (filter.created is AbsoluteDateRangeQuery) {
|
||||
@@ -245,37 +244,46 @@ class FilterRule with EquatableMixin {
|
||||
///
|
||||
static List<FilterRule> fromFilter(final DocumentFilter filter) {
|
||||
List<FilterRule> filterRules = [];
|
||||
final corrRule = filter.correspondent.whenOrNull(
|
||||
notAssigned: () => FilterRule(correspondentRule, null),
|
||||
fromId: (id) => FilterRule(correspondentRule, id.toString()),
|
||||
);
|
||||
final corrRule = switch (filter.correspondent) {
|
||||
NotAssignedIdQueryParameter() => FilterRule(correspondentRule, null),
|
||||
SetIdQueryParameter(id: var id) =>
|
||||
FilterRule(correspondentRule, id.toString()),
|
||||
_ => null,
|
||||
};
|
||||
if (corrRule != null) {
|
||||
filterRules.add(corrRule);
|
||||
}
|
||||
|
||||
final docTypeRule = filter.documentType.whenOrNull(
|
||||
notAssigned: () => FilterRule(documentTypeRule, null),
|
||||
fromId: (id) => FilterRule(documentTypeRule, id.toString()),
|
||||
);
|
||||
final docTypeRule = switch (filter.documentType) {
|
||||
NotAssignedIdQueryParameter() => FilterRule(documentTypeRule, null),
|
||||
SetIdQueryParameter(id: var id) =>
|
||||
FilterRule(documentTypeRule, id.toString()),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
if (docTypeRule != null) {
|
||||
filterRules.add(docTypeRule);
|
||||
}
|
||||
|
||||
final sPathRule = filter.storagePath.whenOrNull(
|
||||
notAssigned: () => FilterRule(storagePathRule, null),
|
||||
fromId: (id) => FilterRule(storagePathRule, id.toString()),
|
||||
);
|
||||
final sPathRule = switch (filter.storagePath) {
|
||||
NotAssignedIdQueryParameter() => FilterRule(storagePathRule, null),
|
||||
SetIdQueryParameter(id: var id) =>
|
||||
FilterRule(storagePathRule, id.toString()),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
if (sPathRule != null) {
|
||||
filterRules.add(sPathRule);
|
||||
}
|
||||
final tagRules = filter.tags.when(
|
||||
notAssigned: () => [FilterRule(hasAnyTag, 'false')],
|
||||
anyAssigned: (_) => [FilterRule(hasAnyTag, 'true')],
|
||||
ids: (include, exclude) => [
|
||||
...include.map((id) => FilterRule(includeTagsRule, id.toString())),
|
||||
...exclude.map((id) => FilterRule(excludeTagsRule, id.toString())),
|
||||
],
|
||||
);
|
||||
final tagRules = switch (filter.tags) {
|
||||
NotAssignedTagsQuery() => [FilterRule(hasAnyTag, 'false')],
|
||||
AnyAssignedTagsQuery() => [FilterRule(hasAnyTag, 'true')],
|
||||
IdsTagsQuery(include: var i, exclude: var e) => [
|
||||
...i.map((id) => FilterRule(includeTagsRule, id.toString())),
|
||||
...e.map((id) => FilterRule(excludeTagsRule, id.toString())),
|
||||
],
|
||||
};
|
||||
|
||||
filterRules.addAll(tagRules);
|
||||
|
||||
if (filter.query.queryText != null) {
|
||||
|
||||
@@ -2,32 +2,36 @@ import 'package:paperless_api/paperless_api.dart';
|
||||
|
||||
extension UserPermissionExtension on UserModel {
|
||||
bool hasPermission(PermissionAction action, PermissionTarget target) {
|
||||
return map(
|
||||
v3: (user) {
|
||||
final permission = [action.value, target.value].join("_");
|
||||
return user.userPermissions.any((element) => element == permission) ||
|
||||
user.inheritedPermissions
|
||||
.any((element) => element.split(".").last == permission);
|
||||
},
|
||||
v2: (_) => true,
|
||||
);
|
||||
final permission = [action.value, target.value].join("_");
|
||||
return switch (this) {
|
||||
UserModelV2() => true,
|
||||
UserModelV3(
|
||||
userPermissions: var userPermissions,
|
||||
inheritedPermissions: var inheritedPermissions,
|
||||
) =>
|
||||
userPermissions.any((p) => p == permission) ||
|
||||
inheritedPermissions.any((p) => p.split(".").last == permission)
|
||||
};
|
||||
}
|
||||
|
||||
bool hasPermissions(
|
||||
List<PermissionAction> actions, List<PermissionTarget> targets) {
|
||||
return map(
|
||||
v3: (user) {
|
||||
final permissions = [
|
||||
for (var action in actions)
|
||||
for (var target in targets) [action, target].join("_")
|
||||
];
|
||||
return permissions.every((requestedPermission) =>
|
||||
user.userPermissions.contains(requestedPermission) ||
|
||||
user.inheritedPermissions.any(
|
||||
(element) => element.split(".").last == requestedPermission));
|
||||
},
|
||||
v2: (_) => true,
|
||||
);
|
||||
List<PermissionAction> actions,
|
||||
List<PermissionTarget> targets,
|
||||
) {
|
||||
final permissions = [
|
||||
for (var action in actions)
|
||||
for (var target in targets) [action, target].join("_")
|
||||
];
|
||||
return switch (this) {
|
||||
UserModelV2() => true,
|
||||
UserModelV3(
|
||||
userPermissions: var userPermissions,
|
||||
inheritedPermissions: var inheritedPermissions,
|
||||
) =>
|
||||
permissions.every((p) =>
|
||||
userPermissions.contains(p) ||
|
||||
inheritedPermissions.any((ip) => ip.split(".").last == p))
|
||||
};
|
||||
}
|
||||
|
||||
bool get canViewDocuments =>
|
||||
|
||||
@@ -1,110 +1,79 @@
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'id_query_parameter.freezed.dart';
|
||||
part 'id_query_parameter.g.dart';
|
||||
|
||||
@freezed
|
||||
class IdQueryParameter with _$IdQueryParameter {
|
||||
const IdQueryParameter._();
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
|
||||
const factory IdQueryParameter.unset() = UnsetIdQueryParameter;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
|
||||
const factory IdQueryParameter.notAssigned() = NotAssignedIdQueryParameter;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
|
||||
const factory IdQueryParameter.anyAssigned() = AnyAssignedIdQueryParameter;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.setIdQueryParameter)
|
||||
const factory IdQueryParameter.fromId(@HiveField(0) int id) = SetIdQueryParameter;
|
||||
sealed class IdQueryParameter {
|
||||
const IdQueryParameter();
|
||||
Map<String, String> toQueryParameter(String field);
|
||||
bool matches(int? id);
|
||||
|
||||
Map<String, String> toQueryParameter(String field) {
|
||||
return when(
|
||||
unset: () => {},
|
||||
notAssigned: () => {
|
||||
'${field}__isnull': '1',
|
||||
},
|
||||
anyAssigned: () => {
|
||||
'${field}__isnull': '0',
|
||||
},
|
||||
fromId: (id) {
|
||||
return {'${field}__id': '$id'};
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
bool isOnlyNotAssigned() => this is NotAssignedIdQueryParameter;
|
||||
|
||||
bool isOnlyAssigned() => this is AnyAssignedIdQueryParameter;
|
||||
|
||||
bool isSet() => this is SetIdQueryParameter;
|
||||
|
||||
bool isUnset() => this is UnsetIdQueryParameter;
|
||||
|
||||
bool matches(int? id) {
|
||||
return when(
|
||||
unset: () => true,
|
||||
notAssigned: () => id == null,
|
||||
anyAssigned: () => id != null,
|
||||
fromId: (id_) => id == id_,
|
||||
);
|
||||
}
|
||||
|
||||
factory IdQueryParameter.fromJson(Map<String, dynamic> json) => _$IdQueryParameterFromJson(json);
|
||||
bool get isUnset => this is UnsetIdQueryParameter;
|
||||
bool get isSet => this is SetIdQueryParameter;
|
||||
bool get isOnlyNotAssigned => this is NotAssignedIdQueryParameter;
|
||||
bool get isOnlyAssigned => this is AnyAssignedIdQueryParameter;
|
||||
}
|
||||
|
||||
// @JsonSerializable()
|
||||
// @HiveType(typeId: PaperlessApiHiveTypeIds.idQueryParameter)
|
||||
// class IdQueryParameter extends Equatable {
|
||||
// @HiveField(0)
|
||||
// final int? assignmentStatus;
|
||||
// @HiveField(1)
|
||||
// final int? id;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class UnsetIdQueryParameter extends IdQueryParameter
|
||||
with _$UnsetIdQueryParameter {
|
||||
const UnsetIdQueryParameter._();
|
||||
const factory UnsetIdQueryParameter() = _UnsetIdQueryParameter;
|
||||
@override
|
||||
Map<String, String> toQueryParameter(String field) => {};
|
||||
|
||||
// @Deprecated("Use named constructors, this is only meant for code generation")
|
||||
// const IdQueryParameter(this.assignmentStatus, this.id);
|
||||
@override
|
||||
bool matches(int? id) => true;
|
||||
}
|
||||
|
||||
// const IdQueryParameter.notAssigned()
|
||||
// : assignmentStatus = 1,
|
||||
// id = null;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class NotAssignedIdQueryParameter extends IdQueryParameter
|
||||
with _$NotAssignedIdQueryParameter {
|
||||
const NotAssignedIdQueryParameter._();
|
||||
const factory NotAssignedIdQueryParameter() = _NotAssignedIdQueryParameter;
|
||||
@override
|
||||
Map<String, String> toQueryParameter(String field) {
|
||||
return {'${field}__isnull': '1'};
|
||||
}
|
||||
|
||||
// const IdQueryParameter.anyAssigned()
|
||||
// : assignmentStatus = 0,
|
||||
// id = null;
|
||||
@override
|
||||
bool matches(int? id) => id == null;
|
||||
}
|
||||
|
||||
// const IdQueryParameter.fromId(this.id) : assignmentStatus = null;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class AnyAssignedIdQueryParameter extends IdQueryParameter
|
||||
with _$AnyAssignedIdQueryParameter {
|
||||
const factory AnyAssignedIdQueryParameter() = _AnyAssignedIdQueryParameter;
|
||||
const AnyAssignedIdQueryParameter._();
|
||||
@override
|
||||
Map<String, String> toQueryParameter(String field) {
|
||||
return {'${field}__isnull': '0'};
|
||||
}
|
||||
|
||||
// const IdQueryParameter.unset() : this.fromId(null);
|
||||
@override
|
||||
bool matches(int? id) => id != null;
|
||||
}
|
||||
|
||||
// bool get isUnset => id == null && assignmentStatus == null;
|
||||
|
||||
// bool get isSet => id != null && assignmentStatus == null;
|
||||
|
||||
// bool get onlyNotAssigned => assignmentStatus == 1;
|
||||
|
||||
// bool get onlyAssigned => assignmentStatus == 0;
|
||||
|
||||
// Map<String, String> toQueryParameter(String field) {
|
||||
// final Map<String, String> params = {};
|
||||
// if (onlyNotAssigned || onlyAssigned) {
|
||||
// params.putIfAbsent('${field}__isnull', () => assignmentStatus!.toString());
|
||||
// }
|
||||
// if (isSet) {
|
||||
// params.putIfAbsent("${field}__id", () => id!.toString());
|
||||
// }
|
||||
// return params;
|
||||
// }
|
||||
|
||||
// bool matches(int? id) {
|
||||
// return onlyAssigned && id != null ||
|
||||
// onlyNotAssigned && id == null ||
|
||||
// isSet && id == this.id ||
|
||||
// isUnset;
|
||||
// }
|
||||
|
||||
// @override
|
||||
// List<Object?> get props => [assignmentStatus, id];
|
||||
|
||||
// Map<String, dynamic> toJson() => _$IdQueryParameterToJson(this);
|
||||
|
||||
// factory IdQueryParameter.fromJson(Map<String, dynamic> json) => _$IdQueryParameterFromJson(json);
|
||||
// }
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.setIdQueryParameter)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class SetIdQueryParameter extends IdQueryParameter with _$SetIdQueryParameter {
|
||||
const SetIdQueryParameter._();
|
||||
const factory SetIdQueryParameter({
|
||||
@HiveField(0) required int id,
|
||||
}) = _SetIdQueryParameter;
|
||||
@override
|
||||
Map<String, String> toQueryParameter(String field) {
|
||||
return {'${field}__id': '$id'};
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(int? id) => id == this.id;
|
||||
}
|
||||
|
||||
@@ -4,54 +4,68 @@ import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||
part 'tags_query.freezed.dart';
|
||||
part 'tags_query.g.dart';
|
||||
|
||||
@freezed
|
||||
class TagsQuery with _$TagsQuery {
|
||||
const TagsQuery._();
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
|
||||
const factory TagsQuery.notAssigned() = NotAssignedTagsQuery;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedTagsQuery)
|
||||
const factory TagsQuery.anyAssigned({
|
||||
@Default([]) List<int> tagIds,
|
||||
}) = AnyAssignedTagsQuery;
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.idsTagsQuery)
|
||||
const factory TagsQuery.ids({
|
||||
@Default([]) List<int> include,
|
||||
@Default([]) List<int> exclude,
|
||||
}) = IdsTagsQuery;
|
||||
|
||||
Map<String, String> toQueryParameter() {
|
||||
return when(
|
||||
anyAssigned: (tagIds) {
|
||||
if (tagIds.isEmpty) {
|
||||
return {'is_tagged': '1'};
|
||||
}
|
||||
return {'tags__id__in': tagIds.join(',')};
|
||||
},
|
||||
ids: (include, exclude) {
|
||||
final Map<String, String> params = {};
|
||||
if (include.isNotEmpty) {
|
||||
params.putIfAbsent('tags__id__all', () => include.join(','));
|
||||
}
|
||||
if (exclude.isNotEmpty) {
|
||||
params.putIfAbsent('tags__id__none', () => exclude.join(','));
|
||||
}
|
||||
return params;
|
||||
},
|
||||
notAssigned: () {
|
||||
return {'is_tagged': '0'};
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
bool matches(Iterable<int> ids) {
|
||||
return when(
|
||||
anyAssigned: (_) => ids.isNotEmpty,
|
||||
ids: (include, exclude) =>
|
||||
include.toSet().difference(ids.toSet()).isEmpty &&
|
||||
exclude.toSet().intersection(ids.toSet()).isEmpty,
|
||||
notAssigned: () => ids.isEmpty,
|
||||
);
|
||||
}
|
||||
|
||||
factory TagsQuery.fromJson(Map<String, dynamic> json) => _$TagsQueryFromJson(json);
|
||||
sealed class TagsQuery {
|
||||
const TagsQuery();
|
||||
Map<String, String> toQueryParameter();
|
||||
bool matches(Iterable<int> ids);
|
||||
}
|
||||
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class NotAssignedTagsQuery extends TagsQuery with _$NotAssignedTagsQuery {
|
||||
const NotAssignedTagsQuery._();
|
||||
const factory NotAssignedTagsQuery() = _NotAssignedTagsQuery;
|
||||
@override
|
||||
Map<String, String> toQueryParameter() {
|
||||
return {'is_tagged': '0'};
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(Iterable<int> ids) => ids.isEmpty;
|
||||
}
|
||||
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedTagsQuery)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class AnyAssignedTagsQuery extends TagsQuery with _$AnyAssignedTagsQuery {
|
||||
const AnyAssignedTagsQuery._();
|
||||
const factory AnyAssignedTagsQuery({
|
||||
@HiveField(0) @Default([]) List<int> tagIds,
|
||||
}) = _AnyAssignedTagsQuery;
|
||||
@override
|
||||
Map<String, String> toQueryParameter() {
|
||||
if (tagIds.isEmpty) {
|
||||
return {'is_tagged': '1'};
|
||||
}
|
||||
return {'tags__id__in': tagIds.join(',')};
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(Iterable<int> ids) => ids.isNotEmpty;
|
||||
}
|
||||
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.idsTagsQuery)
|
||||
@Freezed(toJson: false, fromJson: false)
|
||||
class IdsTagsQuery extends TagsQuery with _$IdsTagsQuery {
|
||||
const IdsTagsQuery._();
|
||||
const factory IdsTagsQuery({
|
||||
@HiveField(0) @Default([]) List<int> include,
|
||||
@HiveField(1) @Default([]) List<int> exclude,
|
||||
}) = _IdsTagsQuery;
|
||||
@override
|
||||
Map<String, String> toQueryParameter() {
|
||||
final Map<String, String> params = {};
|
||||
if (include.isNotEmpty) {
|
||||
params.putIfAbsent('tags__id__all', () => include.join(','));
|
||||
}
|
||||
if (exclude.isNotEmpty) {
|
||||
params.putIfAbsent('tags__id__none', () => exclude.join(','));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(Iterable<int> ids) {
|
||||
return include.toSet().difference(ids.toSet()).isEmpty &&
|
||||
exclude.toSet().intersection(ids.toSet()).isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,55 +4,93 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||
|
||||
part 'user_model.freezed.dart';
|
||||
part 'user_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class UserModel with _$UserModel {
|
||||
const UserModel._();
|
||||
sealed class UserModel {
|
||||
@HiveField(0)
|
||||
final int id;
|
||||
@HiveField(1)
|
||||
final String username;
|
||||
const UserModel({
|
||||
required this.id,
|
||||
required this.username,
|
||||
});
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv3)
|
||||
const factory UserModel.v3({
|
||||
@HiveField(0) required int id,
|
||||
@HiveField(1) required String username,
|
||||
@HiveField(2) String? email,
|
||||
@HiveField(3) String? firstName,
|
||||
@HiveField(4) String? lastName,
|
||||
@HiveField(5) DateTime? dateJoined,
|
||||
@HiveField(6) @Default(true) bool isStaff,
|
||||
@HiveField(7) @Default(true) bool isActive,
|
||||
@HiveField(8) @Default(true) bool isSuperuser,
|
||||
@HiveField(9) @Default([]) List<int> groups,
|
||||
@HiveField(10) @Default([]) List<String> userPermissions,
|
||||
@HiveField(11) @Default([]) List<String> inheritedPermissions,
|
||||
}) = UserModelV3;
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv2)
|
||||
const factory UserModel.v2({
|
||||
@HiveField(0) @JsonKey(name: "user_id") required int id,
|
||||
@HiveField(1) required String username,
|
||||
@HiveField(2) String? displayName,
|
||||
}) = UserModelV2;
|
||||
|
||||
factory UserModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelFromJson(json);
|
||||
|
||||
String? get fullName => map(
|
||||
v2: (value) => value.displayName,
|
||||
v3: (value) {
|
||||
bool hasFirstName = value.firstName?.trim().isNotEmpty ?? false;
|
||||
bool hasLastName = value.lastName?.trim().isNotEmpty ?? false;
|
||||
if (hasFirstName && hasLastName) {
|
||||
return "${value.firstName!} ${value.lastName!}";
|
||||
} else if (hasFirstName) {
|
||||
return value.firstName!;
|
||||
} else if (hasLastName) {
|
||||
return value.lastName;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
);
|
||||
String? get fullName;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv2)
|
||||
class UserModelV2 extends UserModel {
|
||||
@HiveField(2)
|
||||
final String? displayName;
|
||||
const UserModelV2({
|
||||
required super.id,
|
||||
required super.username,
|
||||
this.displayName,
|
||||
});
|
||||
Map<String, dynamic> toJson() => _$UserModelV2ToJson(this);
|
||||
factory UserModelV2.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelV2FromJson(json);
|
||||
|
||||
@override
|
||||
String? get fullName => displayName;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv3)
|
||||
class UserModelV3 extends UserModel {
|
||||
@HiveField(2)
|
||||
final String? email;
|
||||
@HiveField(3)
|
||||
final String? firstName;
|
||||
@HiveField(4)
|
||||
final String? lastName;
|
||||
@HiveField(5)
|
||||
final DateTime? dateJoined;
|
||||
@HiveField(6)
|
||||
final bool isStaff;
|
||||
@HiveField(7)
|
||||
final bool isActive;
|
||||
@HiveField(8)
|
||||
final bool isSuperuser;
|
||||
@HiveField(9)
|
||||
final List<int> groups;
|
||||
@HiveField(10)
|
||||
final List<String> userPermissions;
|
||||
@HiveField(11)
|
||||
final List<String> inheritedPermissions;
|
||||
|
||||
@override
|
||||
String? get fullName {
|
||||
bool hasFirstName = firstName?.trim().isNotEmpty ?? false;
|
||||
bool hasLastName = lastName?.trim().isNotEmpty ?? false;
|
||||
if (hasFirstName && hasLastName) {
|
||||
return "${firstName!} ${lastName!}";
|
||||
} else if (hasFirstName) {
|
||||
return firstName!;
|
||||
} else if (hasLastName) {
|
||||
return lastName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const UserModelV3({
|
||||
required super.id,
|
||||
required super.username,
|
||||
this.email,
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.dateJoined,
|
||||
required this.isStaff,
|
||||
required this.isActive,
|
||||
required this.isSuperuser,
|
||||
required this.groups,
|
||||
required this.userPermissions,
|
||||
required this.inheritedPermissions,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => _$UserModelV3ToJson(this);
|
||||
factory UserModelV3.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelV3FromJson(json);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ class PaperlessDocumentsApiImpl implements PaperlessDocumentsApi {
|
||||
const DocumentFilter asnQueryFilter = DocumentFilter(
|
||||
sortField: SortField.archiveSerialNumber,
|
||||
sortOrder: SortOrder.descending,
|
||||
asnQuery: IdQueryParameter.anyAssigned(),
|
||||
asnQuery: AnyAssignedIdQueryParameter(),
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:paperless_api/src/models/models.dart';
|
||||
|
||||
///
|
||||
|
||||
@@ -65,10 +65,10 @@ void main() {
|
||||
}).toDocumentFilter(),
|
||||
equals(
|
||||
DocumentFilter.initial.copyWith(
|
||||
correspondent: const IdQueryParameter.fromId(42),
|
||||
documentType: const IdQueryParameter.fromId(69),
|
||||
storagePath: const IdQueryParameter.fromId(14),
|
||||
tags: const TagsQuery.ids(
|
||||
correspondent: const SetIdQueryParameter(id: 42),
|
||||
documentType: const SetIdQueryParameter(id: 69),
|
||||
storagePath: const SetIdQueryParameter(id: 14),
|
||||
tags: const IdsTagsQuery(
|
||||
include: [1, 2],
|
||||
exclude: [3, 4],
|
||||
),
|
||||
@@ -131,10 +131,10 @@ void main() {
|
||||
],
|
||||
}).toDocumentFilter();
|
||||
final expected = DocumentFilter.initial.copyWith(
|
||||
correspondent: const IdQueryParameter.notAssigned(),
|
||||
documentType: const IdQueryParameter.notAssigned(),
|
||||
storagePath: const IdQueryParameter.notAssigned(),
|
||||
tags: const TagsQuery.notAssigned(),
|
||||
correspondent: const NotAssignedIdQueryParameter(),
|
||||
documentType: const NotAssignedIdQueryParameter(),
|
||||
storagePath: const NotAssignedIdQueryParameter(),
|
||||
tags: const NotAssignedTagsQuery(),
|
||||
);
|
||||
expect(
|
||||
actual,
|
||||
@@ -148,10 +148,10 @@ void main() {
|
||||
expect(
|
||||
SavedView.fromDocumentFilter(
|
||||
DocumentFilter(
|
||||
correspondent: const IdQueryParameter.fromId(1),
|
||||
documentType: const IdQueryParameter.fromId(2),
|
||||
storagePath: const IdQueryParameter.fromId(3),
|
||||
tags: const TagsQuery.ids(
|
||||
correspondent: const SetIdQueryParameter(id: 1),
|
||||
documentType: const SetIdQueryParameter(id: 2),
|
||||
storagePath: const SetIdQueryParameter(id: 3),
|
||||
tags: const IdsTagsQuery(
|
||||
include: [4, 5],
|
||||
exclude: [6, 7, 8],
|
||||
),
|
||||
@@ -202,9 +202,9 @@ void main() {
|
||||
expect(
|
||||
SavedView.fromDocumentFilter(
|
||||
const DocumentFilter(
|
||||
correspondent: IdQueryParameter.unset(),
|
||||
documentType: IdQueryParameter.unset(),
|
||||
storagePath: IdQueryParameter.unset(),
|
||||
correspondent: UnsetIdQueryParameter(),
|
||||
documentType: UnsetIdQueryParameter(),
|
||||
storagePath: UnsetIdQueryParameter(),
|
||||
tags: IdsTagsQuery(),
|
||||
sortField: SortField.created,
|
||||
sortOrder: SortOrder.descending,
|
||||
@@ -233,10 +233,10 @@ void main() {
|
||||
expect(
|
||||
SavedView.fromDocumentFilter(
|
||||
const DocumentFilter(
|
||||
correspondent: IdQueryParameter.notAssigned(),
|
||||
documentType: IdQueryParameter.notAssigned(),
|
||||
storagePath: IdQueryParameter.notAssigned(),
|
||||
tags: TagsQuery.notAssigned(),
|
||||
correspondent: NotAssignedIdQueryParameter(),
|
||||
documentType: NotAssignedIdQueryParameter(),
|
||||
storagePath: NotAssignedIdQueryParameter(),
|
||||
tags: NotAssignedTagsQuery(),
|
||||
sortField: SortField.created,
|
||||
sortOrder: SortOrder.ascending,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user