mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-10 08:07:59 -06:00
fix: Add custom fields, translations, add app logs to login routes
This commit is contained in:
@@ -18,6 +18,7 @@ class DateAndDocumentTypeLabelWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final subtitleStyle =
|
||||
Theme.of(context).textTheme.labelMedium?.apply(color: Colors.grey);
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
return RichText(
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -37,11 +38,8 @@ class DateAndDocumentTypeLabelWidget extends StatelessWidget {
|
||||
? () => onDocumentTypeSelected!(document.documentType)
|
||||
: null,
|
||||
child: Text(
|
||||
context
|
||||
.watch<LabelRepository>()
|
||||
.state
|
||||
.documentTypes[document.documentType]!
|
||||
.name,
|
||||
labelRepository
|
||||
.documentTypes[document.documentType]!.name,
|
||||
style: subtitleStyle,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:hive_flutter/adapters.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/date_and_document_type_widget.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart';
|
||||
import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
|
||||
import 'package:paperless_mobile/features/labels/document_type/view/widgets/document_type_widget.dart';
|
||||
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -58,7 +55,7 @@ class DocumentDetailedItem extends DocumentItem {
|
||||
final maxHeight = highlights != null
|
||||
? min(600.0, availableHeight)
|
||||
: min(500.0, availableHeight);
|
||||
final labels = context.watch<LabelRepository>().state;
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
return Card(
|
||||
color: isSelected ? Theme.of(context).colorScheme.inversePrimary : null,
|
||||
child: InkWell(
|
||||
@@ -93,8 +90,9 @@ class DocumentDetailedItem extends DocumentItem {
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: TagsWidget(
|
||||
tags:
|
||||
document.tags.map((e) => labels.tags[e]!).toList(),
|
||||
tags: document.tags
|
||||
.map((e) => labelRepository.tags[e]!)
|
||||
.toList(),
|
||||
onTagSelected: onTagSelected,
|
||||
).padded(),
|
||||
),
|
||||
@@ -107,7 +105,8 @@ class DocumentDetailedItem extends DocumentItem {
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.apply(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
correspondent: labels.correspondents[document.correspondent],
|
||||
correspondent:
|
||||
labelRepository.correspondents[document.correspondent],
|
||||
).paddedLTRB(8, 8, 8, 0),
|
||||
Text(
|
||||
document.title.isEmpty ? '(-)' : document.title,
|
||||
|
||||
@@ -30,6 +30,7 @@ class DocumentGridItem extends DocumentItem {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var currentUser = context.watch<LocalUserAccount>().paperlessUser;
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
return Stack(
|
||||
children: [
|
||||
Card(
|
||||
@@ -75,10 +76,7 @@ class DocumentGridItem extends DocumentItem {
|
||||
if (currentUser.canViewTags)
|
||||
TagsWidget.sliver(
|
||||
tags: document.tags
|
||||
.map((e) => context
|
||||
.watch<LabelRepository>()
|
||||
.state
|
||||
.tags[e]!)
|
||||
.map((e) => labelRepository.tags[e]!)
|
||||
.toList(),
|
||||
onTagSelected: onTagSelected,
|
||||
),
|
||||
@@ -102,17 +100,13 @@ class DocumentGridItem extends DocumentItem {
|
||||
children: [
|
||||
if (currentUser.canViewCorrespondents)
|
||||
CorrespondentWidget(
|
||||
correspondent: context
|
||||
.watch<LabelRepository>()
|
||||
.state
|
||||
correspondent: labelRepository
|
||||
.correspondents[document.correspondent],
|
||||
onSelected: onCorrespondentSelected,
|
||||
),
|
||||
if (currentUser.canViewDocumentTypes)
|
||||
DocumentTypeWidget(
|
||||
documentType: context
|
||||
.watch<LabelRepository>()
|
||||
.state
|
||||
documentType: labelRepository
|
||||
.documentTypes[document.documentType],
|
||||
onSelected: onDocumentTypeSelected,
|
||||
),
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:paperless_api/src/models/document_model.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/date_and_document_type_widget.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart';
|
||||
@@ -32,7 +29,7 @@ class DocumentListItem extends DocumentItem {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final labels = context.watch<LabelRepository>().state;
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
|
||||
return ListTile(
|
||||
tileColor: backgroundColor,
|
||||
@@ -51,10 +48,8 @@ class DocumentListItem extends DocumentItem {
|
||||
absorbing: isSelectionActive,
|
||||
child: CorrespondentWidget(
|
||||
isClickable: isLabelClickable,
|
||||
correspondent: context
|
||||
.watch<LabelRepository>()
|
||||
.state
|
||||
.correspondents[document.correspondent],
|
||||
correspondent:
|
||||
labelRepository.correspondents[document.correspondent],
|
||||
onSelected: onCorrespondentSelected,
|
||||
),
|
||||
),
|
||||
@@ -70,8 +65,8 @@ class DocumentListItem extends DocumentItem {
|
||||
child: TagsWidget(
|
||||
isClickable: isLabelClickable,
|
||||
tags: document.tags
|
||||
.where((e) => labels.tags.containsKey(e))
|
||||
.map((e) => labels.tags[e]!)
|
||||
.where((e) => labelRepository.tags.containsKey(e))
|
||||
.map((e) => labelRepository.tags[e]!)
|
||||
.toList(),
|
||||
onTagSelected: (id) => onTagSelected?.call(id),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart';
|
||||
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart';
|
||||
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
|
||||
@@ -47,10 +48,6 @@ class DocumentFilterForm extends StatefulWidget {
|
||||
final DocumentFilter initialFilter;
|
||||
final ScrollController? scrollController;
|
||||
final EdgeInsets padding;
|
||||
final Map<int, Correspondent> correspondents;
|
||||
final Map<int, DocumentType> documentTypes;
|
||||
final Map<int, Tag> tags;
|
||||
final Map<int, StoragePath> storagePaths;
|
||||
|
||||
const DocumentFilterForm({
|
||||
super.key,
|
||||
@@ -59,10 +56,6 @@ class DocumentFilterForm extends StatefulWidget {
|
||||
required this.initialFilter,
|
||||
this.scrollController,
|
||||
this.padding = const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
required this.correspondents,
|
||||
required this.documentTypes,
|
||||
required this.tags,
|
||||
required this.storagePaths,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -80,13 +73,14 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
return FormBuilder(
|
||||
key: widget.formKey,
|
||||
child: CustomScrollView(
|
||||
controller: widget.scrollController,
|
||||
slivers: [
|
||||
if (widget.header != null) widget.header!,
|
||||
..._buildFormFieldList(),
|
||||
..._buildFormFieldList(labelRepository),
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 32,
|
||||
@@ -97,7 +91,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildFormFieldList() {
|
||||
List<Widget> _buildFormFieldList(LabelRepository labelRepository) {
|
||||
return [
|
||||
_buildQueryFormField(),
|
||||
Align(
|
||||
@@ -123,10 +117,10 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
_checkQueryConstraints();
|
||||
},
|
||||
),
|
||||
_buildCorrespondentFormField(),
|
||||
_buildDocumentTypeFormField(),
|
||||
_buildStoragePathFormField(),
|
||||
_buildTagsFormField(),
|
||||
_buildCorrespondentFormField(labelRepository.correspondents),
|
||||
_buildDocumentTypeFormField(labelRepository.documentTypes),
|
||||
_buildStoragePathFormField(labelRepository.storagePaths),
|
||||
_buildTagsFormField(labelRepository.tags),
|
||||
]
|
||||
.map((w) => SliverPadding(
|
||||
padding: widget.padding,
|
||||
@@ -151,10 +145,10 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildDocumentTypeFormField() {
|
||||
Widget _buildDocumentTypeFormField(Map<int, DocumentType> documentTypes) {
|
||||
return LabelFormField<DocumentType>(
|
||||
name: DocumentFilterForm.fkDocumentType,
|
||||
options: widget.documentTypes,
|
||||
options: documentTypes,
|
||||
labelText: S.of(context)!.documentType,
|
||||
initialValue: widget.initialFilter.documentType,
|
||||
prefixIcon: const Icon(Icons.description_outlined),
|
||||
@@ -166,10 +160,10 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCorrespondentFormField() {
|
||||
Widget _buildCorrespondentFormField(Map<int, Correspondent> correspondents) {
|
||||
return LabelFormField<Correspondent>(
|
||||
name: DocumentFilterForm.fkCorrespondent,
|
||||
options: widget.correspondents,
|
||||
options: correspondents,
|
||||
labelText: S.of(context)!.correspondent,
|
||||
initialValue: widget.initialFilter.correspondent,
|
||||
prefixIcon: const Icon(Icons.person_outline),
|
||||
@@ -181,10 +175,10 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStoragePathFormField() {
|
||||
Widget _buildStoragePathFormField(Map<int, StoragePath> storagePaths) {
|
||||
return LabelFormField<StoragePath>(
|
||||
name: DocumentFilterForm.fkStoragePath,
|
||||
options: widget.storagePaths,
|
||||
options: storagePaths,
|
||||
labelText: S.of(context)!.storagePath,
|
||||
initialValue: widget.initialFilter.storagePath,
|
||||
prefixIcon: const Icon(Icons.folder_outlined),
|
||||
@@ -202,11 +196,11 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTagsFormField() {
|
||||
Widget _buildTagsFormField(Map<int, Tag> tags) {
|
||||
return TagsFormField(
|
||||
name: DocumentModel.tagsKey,
|
||||
initialValue: widget.initialFilter.tags,
|
||||
options: widget.tags,
|
||||
options: tags,
|
||||
allowExclude: false,
|
||||
allowOnlySelection: false,
|
||||
allowCreation: false,
|
||||
|
||||
@@ -13,20 +13,12 @@ class DocumentFilterPanel extends StatefulWidget {
|
||||
final DocumentFilter initialFilter;
|
||||
final ScrollController scrollController;
|
||||
final DraggableScrollableController draggableSheetController;
|
||||
final Map<int, Correspondent> correspondents;
|
||||
final Map<int, DocumentType> documentTypes;
|
||||
final Map<int, Tag> tags;
|
||||
final Map<int, StoragePath> storagePaths;
|
||||
|
||||
const DocumentFilterPanel({
|
||||
Key? key,
|
||||
required this.initialFilter,
|
||||
required this.scrollController,
|
||||
required this.draggableSheetController,
|
||||
required this.correspondents,
|
||||
required this.documentTypes,
|
||||
required this.tags,
|
||||
required this.storagePaths,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -104,10 +96,6 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
|
||||
scrollController: widget.scrollController,
|
||||
initialFilter: widget.initialFilter,
|
||||
header: _buildPanelHeader(),
|
||||
correspondents: widget.correspondents,
|
||||
documentTypes: widget.documentTypes,
|
||||
storagePaths: widget.storagePaths,
|
||||
tags: widget.tags,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.dart';
|
||||
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
@@ -8,10 +10,6 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
class SortFieldSelectionBottomSheet extends StatefulWidget {
|
||||
final SortOrder initialSortOrder;
|
||||
final SortField? initialSortField;
|
||||
final Map<int, Correspondent> correspondents;
|
||||
final Map<int, DocumentType> documentTypes;
|
||||
final Map<int, Tag> tags;
|
||||
final Map<int, StoragePath> storagePaths;
|
||||
|
||||
final Future Function(SortField? field, SortOrder order) onSubmit;
|
||||
|
||||
@@ -20,10 +18,6 @@ class SortFieldSelectionBottomSheet extends StatefulWidget {
|
||||
required this.initialSortOrder,
|
||||
required this.initialSortField,
|
||||
required this.onSubmit,
|
||||
required this.correspondents,
|
||||
required this.documentTypes,
|
||||
required this.tags,
|
||||
required this.storagePaths,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -45,6 +39,7 @@ class _SortFieldSelectionBottomSheetState
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final labelRepository = context.watch<LabelRepository>();
|
||||
return ClipRRect(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
@@ -75,7 +70,7 @@ class _SortFieldSelectionBottomSheetState
|
||||
_buildSortOption(SortField.archiveSerialNumber),
|
||||
_buildSortOption(
|
||||
SortField.correspondentName,
|
||||
enabled: widget.correspondents.values.fold<bool>(
|
||||
enabled: labelRepository.correspondents.values.fold<bool>(
|
||||
false,
|
||||
(previousValue, element) =>
|
||||
previousValue || (element.documentCount ?? 0) > 0),
|
||||
@@ -83,7 +78,7 @@ class _SortFieldSelectionBottomSheetState
|
||||
_buildSortOption(SortField.title),
|
||||
_buildSortOption(
|
||||
SortField.documentType,
|
||||
enabled: widget.documentTypes.values.fold<bool>(
|
||||
enabled: labelRepository.documentTypes.values.fold<bool>(
|
||||
false,
|
||||
(previousValue, element) =>
|
||||
previousValue || (element.documentCount ?? 0) > 0),
|
||||
|
||||
@@ -69,10 +69,6 @@ class SortDocumentsButton extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
correspondents: state.correspondents,
|
||||
documentTypes: state.documentTypes,
|
||||
storagePaths: state.storagePaths,
|
||||
tags: state.tags,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user