mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-08 08:07:56 -06:00
feat: Implement bulk label forms (except tags)
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/features/document_bulk_action/cubit/document_bulk_action_cubit.dart';
|
||||
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/bulk_edit_label_bottom_sheet.dart';
|
||||
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/bulk_edit_tags_bottom_sheet.dart';
|
||||
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_label_form_field.dart';
|
||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
@@ -65,12 +66,106 @@ class DocumentSelectionSliverAppBar extends StatelessWidget {
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
_buildBulkEditCorrespondentChip(context)
|
||||
.paddedOnly(left: 8, right: 4),
|
||||
_buildBulkEditDocumentTypeChip(context)
|
||||
.paddedOnly(left: 4, right: 4),
|
||||
_buildBulkEditStoragePathChip(context)
|
||||
.paddedOnly(left: 4, right: 4),
|
||||
ActionChip(
|
||||
label: Text(S.of(context)!.correspondent),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: BlocBuilder<DocumentBulkActionCubit,
|
||||
DocumentBulkActionState>(
|
||||
builder: (context, state) {
|
||||
return FullscreenBulkEditLabelFormField(
|
||||
options: state.correspondents,
|
||||
selection: state.selection,
|
||||
labelMapper: (document) => document.correspondent,
|
||||
leadingIcon: const Icon(Icons.person_outline),
|
||||
hintText: S.of(context)!.startTyping,
|
||||
onSubmit: context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyCorrespondent,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).paddedOnly(left: 8, right: 4),
|
||||
ActionChip(
|
||||
label: Text(S.of(context)!.documentType),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: BlocBuilder<DocumentBulkActionCubit,
|
||||
DocumentBulkActionState>(
|
||||
builder: (context, state) {
|
||||
return FullscreenBulkEditLabelFormField(
|
||||
options: state.documentTypes,
|
||||
selection: state.selection,
|
||||
labelMapper: (document) => document.documentType,
|
||||
leadingIcon:
|
||||
const Icon(Icons.description_outlined),
|
||||
hintText: S.of(context)!.startTyping,
|
||||
onSubmit: context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyDocumentType,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).paddedOnly(left: 8, right: 4),
|
||||
ActionChip(
|
||||
label: Text(S.of(context)!.storagePath),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: BlocBuilder<DocumentBulkActionCubit,
|
||||
DocumentBulkActionState>(
|
||||
builder: (context, state) {
|
||||
return FullscreenBulkEditLabelFormField(
|
||||
options: state.storagePaths,
|
||||
selection: state.selection,
|
||||
labelMapper: (document) => document.storagePath,
|
||||
leadingIcon: const Icon(Icons.folder_outlined),
|
||||
hintText: S.of(context)!.startTyping,
|
||||
onSubmit: context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyStoragePath,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).paddedOnly(left: 8, right: 4),
|
||||
_buildBulkEditTagsChip(context).paddedOnly(left: 4, right: 4),
|
||||
],
|
||||
),
|
||||
@@ -79,150 +174,6 @@ class DocumentSelectionSliverAppBar extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBulkEditCorrespondentChip(BuildContext context) {
|
||||
return ActionChip(
|
||||
label: Text(S.of(context)!.correspondent),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () {
|
||||
final initialValue = state.selection.every((element) =>
|
||||
element.correspondent == state.selection.first.correspondent)
|
||||
? state.selection.first.correspondent
|
||||
: null;
|
||||
showModalBottomSheet(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
isScrollControlled: false,
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: Builder(builder: (context) {
|
||||
return BulkEditLabelBottomSheet<Correspondent>(
|
||||
initialValue: initialValue,
|
||||
title: "Bulk edit correspondent",
|
||||
availableOptionsSelector: (state) => state.correspondents,
|
||||
formFieldLabel: S.of(context)!.correspondent,
|
||||
formFieldPrefixIcon: const Icon(Icons.person_outline),
|
||||
onSubmit: (selectedId) async {
|
||||
await context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyCorrespondent(selectedId);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBulkEditDocumentTypeChip(BuildContext context) {
|
||||
return ActionChip(
|
||||
label: Text(S.of(context)!.documentType),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () {
|
||||
final initialValue = state.selection.every((element) =>
|
||||
element.documentType == state.selection.first.documentType)
|
||||
? state.selection.first.documentType
|
||||
: null;
|
||||
showModalBottomSheet(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
isScrollControlled: false,
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: Builder(builder: (context) {
|
||||
return BulkEditLabelBottomSheet<DocumentType>(
|
||||
initialValue: initialValue,
|
||||
title: "Bulk edit document type",
|
||||
availableOptionsSelector: (state) => state.documentTypes,
|
||||
formFieldLabel: S.of(context)!.documentType,
|
||||
formFieldPrefixIcon: const Icon(Icons.person_outline),
|
||||
onSubmit: (selectedId) async {
|
||||
await context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyDocumentType(selectedId);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBulkEditStoragePathChip(BuildContext context) {
|
||||
return ActionChip(
|
||||
label: Text(S.of(context)!.storagePath),
|
||||
avatar: const Icon(Icons.edit),
|
||||
onPressed: () {
|
||||
final initialValue = state.selection.every((element) =>
|
||||
element.storagePath == state.selection.first.storagePath)
|
||||
? state.selection.first.storagePath
|
||||
: null;
|
||||
showModalBottomSheet(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
isScrollControlled: false,
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return BlocProvider(
|
||||
create: (context) => DocumentBulkActionCubit(
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
selection: state.selection,
|
||||
),
|
||||
child: Builder(builder: (context) {
|
||||
return BulkEditLabelBottomSheet<StoragePath>(
|
||||
initialValue: initialValue,
|
||||
title: "Bulk edit storage path",
|
||||
availableOptionsSelector: (state) => state.storagePaths,
|
||||
formFieldLabel: S.of(context)!.storagePath,
|
||||
formFieldPrefixIcon: const Icon(Icons.folder_open_outlined),
|
||||
onSubmit: (selectedId) async {
|
||||
await context
|
||||
.read<DocumentBulkActionCubit>()
|
||||
.bulkModifyStoragePath(selectedId);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBulkEditTagsChip(BuildContext context) {
|
||||
return ActionChip(
|
||||
label: Text(S.of(context)!.tags),
|
||||
|
||||
Reference in New Issue
Block a user