mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-08 10:07:51 -06:00
Redesigned sorting
This commit is contained in:
@@ -52,16 +52,6 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
|
||||
static const fkCreatedAt = DocumentModel.createdKey;
|
||||
static const fkAddedAt = DocumentModel.addedKey;
|
||||
|
||||
static const _sortFields = [
|
||||
SortField.created,
|
||||
SortField.added,
|
||||
SortField.modified,
|
||||
SortField.title,
|
||||
SortField.correspondentName,
|
||||
SortField.documentType,
|
||||
SortField.archiveSerialNumber
|
||||
];
|
||||
|
||||
final _formKey = GlobalKey<FormBuilderState>();
|
||||
|
||||
late final DocumentsCubit _documentsCubit;
|
||||
@@ -137,7 +127,6 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
|
||||
const SizedBox(
|
||||
height: 16.0,
|
||||
),
|
||||
_buildSortByChipsList(context, state),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(S.of(context).documentsFilterPageSearchLabel),
|
||||
@@ -448,71 +437,6 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSortByChipsList(BuildContext context, DocumentsState state) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).documentsPageOrderByLabel,
|
||||
),
|
||||
SizedBox(
|
||||
height: kToolbarHeight,
|
||||
child: ListView.separated(
|
||||
itemCount: _sortFields.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
separatorBuilder: (context, index) => const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
itemBuilder: (context, index) => _buildActionChip(
|
||||
_sortFields[index], state.filter.sortField, context),
|
||||
),
|
||||
),
|
||||
],
|
||||
).padded();
|
||||
}
|
||||
|
||||
Widget _buildActionChip(SortField sortField,
|
||||
SortField? currentlySelectedOrder, BuildContext context) {
|
||||
String text;
|
||||
switch (sortField) {
|
||||
case SortField.archiveSerialNumber:
|
||||
text = S.of(context).documentArchiveSerialNumberPropertyShortLabel;
|
||||
break;
|
||||
case SortField.correspondentName:
|
||||
text = S.of(context).documentCorrespondentPropertyLabel;
|
||||
break;
|
||||
case SortField.title:
|
||||
text = S.of(context).documentTitlePropertyLabel;
|
||||
break;
|
||||
case SortField.documentType:
|
||||
text = S.of(context).documentDocumentTypePropertyLabel;
|
||||
break;
|
||||
case SortField.created:
|
||||
text = S.of(context).documentCreatedPropertyLabel;
|
||||
break;
|
||||
case SortField.added:
|
||||
text = S.of(context).documentAddedPropertyLabel;
|
||||
break;
|
||||
case SortField.modified:
|
||||
text = S.of(context).documentModifiedPropertyLabel;
|
||||
break;
|
||||
}
|
||||
|
||||
final docBloc = BlocProvider.of<DocumentsCubit>(context);
|
||||
return ActionChip(
|
||||
label: Text(text),
|
||||
avatar: currentlySelectedOrder == sortField
|
||||
? const Icon(
|
||||
Icons.done,
|
||||
color: Colors.green,
|
||||
)
|
||||
: null,
|
||||
onPressed: () => docBloc.updateFilter(
|
||||
filter: docBloc.state.filter.copyWith(sortField: sortField)),
|
||||
);
|
||||
}
|
||||
|
||||
void _onApplyFilter() async {
|
||||
if (_formKey.currentState?.saveAndValidate() ?? false) {
|
||||
final v = _formKey.currentState!.value;
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:paperless_mobile/di_initializer.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_field.dart';
|
||||
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_order.dart';
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
|
||||
class SortFieldSelectionBottomSheet extends StatefulWidget {
|
||||
const SortFieldSelectionBottomSheet({super.key});
|
||||
|
||||
@override
|
||||
State<SortFieldSelectionBottomSheet> createState() =>
|
||||
_SortFieldSelectionBottomSheetState();
|
||||
}
|
||||
|
||||
class _SortFieldSelectionBottomSheetState
|
||||
extends State<SortFieldSelectionBottomSheet> {
|
||||
static const _sortFields = [
|
||||
SortField.created,
|
||||
SortField.added,
|
||||
SortField.modified,
|
||||
SortField.title,
|
||||
SortField.correspondentName,
|
||||
SortField.documentType,
|
||||
SortField.archiveSerialNumber
|
||||
];
|
||||
|
||||
SortField? _selectedFieldLoading;
|
||||
SortOrder? _selectedOrderLoading;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
child: BlocBuilder<DocumentsCubit, DocumentsState>(
|
||||
bloc: getIt<DocumentsCubit>(),
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).documentsPageOrderByLabel,
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
textAlign: TextAlign.start,
|
||||
).padded(EdgeInsets.symmetric(horizontal: 16, vertical: 16)),
|
||||
Column(
|
||||
children: _sortFields
|
||||
.map(
|
||||
(e) => _buildSortOption(
|
||||
e,
|
||||
state.filter.sortOrder,
|
||||
state.filter.sortField == e,
|
||||
_selectedFieldLoading == e,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSortOption(
|
||||
SortField field,
|
||||
SortOrder order,
|
||||
bool isCurrentlySelected,
|
||||
bool isNextSelected,
|
||||
) {
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
title: Text(
|
||||
_localizedSortField(field),
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
),
|
||||
trailing: isNextSelected
|
||||
? (_buildOrderIcon(_selectedOrderLoading!))
|
||||
: (_selectedOrderLoading == null && isCurrentlySelected
|
||||
? _buildOrderIcon(order)
|
||||
: null),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
_selectedFieldLoading = field;
|
||||
_selectedOrderLoading =
|
||||
isCurrentlySelected ? order.toggle() : SortOrder.descending;
|
||||
});
|
||||
BlocProvider.of<DocumentsCubit>(context)
|
||||
.updateCurrentFilter((filter) => filter.copyWith(
|
||||
sortOrder: isCurrentlySelected
|
||||
? order.toggle()
|
||||
: SortOrder.descending,
|
||||
sortField: field,
|
||||
))
|
||||
.whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_selectedFieldLoading = null;
|
||||
_selectedOrderLoading = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildOrderIcon(SortOrder order) {
|
||||
if (order == SortOrder.ascending) {
|
||||
return Icon(Icons.arrow_upward);
|
||||
}
|
||||
return Icon(Icons.arrow_downward);
|
||||
}
|
||||
|
||||
String _localizedSortField(SortField sortField) {
|
||||
switch (sortField) {
|
||||
case SortField.archiveSerialNumber:
|
||||
return S.of(context).documentArchiveSerialNumberPropertyShortLabel;
|
||||
case SortField.correspondentName:
|
||||
return S.of(context).documentCorrespondentPropertyLabel;
|
||||
case SortField.title:
|
||||
return S.of(context).documentTitlePropertyLabel;
|
||||
case SortField.documentType:
|
||||
return S.of(context).documentDocumentTypePropertyLabel;
|
||||
case SortField.created:
|
||||
return S.of(context).documentCreatedPropertyLabel;
|
||||
case SortField.added:
|
||||
return S.of(context).documentAddedPropertyLabel;
|
||||
case SortField.modified:
|
||||
return S.of(context).documentModifiedPropertyLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user