Commit 8c2c0fa
Changed files (12)
lib
components
l10n
model
screens
test
lib/components/export_item_order.dart
@@ -1,227 +0,0 @@
-
-import 'dart:async';
-
-import 'package:blood_pressure_app/model/export_import/column.dart';
-import 'package:flutter/material.dart';
-
-@Deprecated("TODO: repalace")
-class ExportItemsCustomizer extends StatefulWidget {
- final List<ExportColumn> shownItems;
- final List<ExportColumn> disabledItems;
- final FutureOr<void> Function(List<ExportColumn> exportItems, List<ExportColumn> exportAddableItems) onReorder;
-
- const ExportItemsCustomizer({super.key, required this.shownItems, required this.disabledItems,
- required this.onReorder});
-
- @override
- State<ExportItemsCustomizer> createState() => _ExportItemsCustomizerState();
-}
-
-class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
- @override
- Widget build(BuildContext context) => Text('TODO - ExportItemsCustomizer');
-/* => Consumer<ExportColumnsManager>(
- builder: (context, manager, child) => _buildAddItemBadge(context,
- child: _buildManagePresetsBadge(context, manager,
- child: _buildList(context, manager)
- )
- )
- );
-
-
- Container _buildList(BuildContext context, ExportColumnsManager manager) {
- return Container(
- margin: const EdgeInsets.all(25),
- padding: const EdgeInsets.all(20),
- height: 420,
- decoration: BoxDecoration(
- border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- ),
- clipBehavior: Clip.hardEdge,
- child: ReorderableListView(
- shrinkWrap: true,
- onReorder: _onReorderList,
- children: <Widget>[
- for (int i = 0; i < manger.shownItems.length; i += 1)
- ListTile(
- key: Key('l_${widget.shownItems[i].internalName}'),
- title: Text(widget.shownItems[i].columnTitle),
- trailing: _buildListItemTrailing( context, widget.shownItems[i], exportConfigModel),
- contentPadding: EdgeInsets.zero
- ),
- _buildListSectionDivider(context),
- for (int i = 0; i < widget.disabledItems.length; i += 1)
- (widget.disabledItems[i].hidden) ? SizedBox.shrink(key: Key('ul_${widget.disabledItems[i].internalName}'),)
- : ListTile(
- key: Key('ul_${widget.disabledItems[i].internalName}'),
- title: Opacity(
- opacity: 0.7,
- child: Text(widget.disabledItems[i].columnTitle),
- ),
- trailing: _buildListItemTrailing(context, widget.disabledItems[i], exportConfigModel),
- contentPadding: EdgeInsets.zero
- ),
- ],
- ),
- );
- }
-
- Widget _buildAddItemBadge(BuildContext context, {required Widget child}) {
- return badges.Badge(
- badgeStyle: badges.BadgeStyle(
- badgeColor: Theme.of(context).colorScheme.background,
- padding: const EdgeInsets.all(10)
- ),
- position: badges.BadgePosition.bottomEnd(bottom: 3, end: 3),
- badgeContent: Container(
- decoration: BoxDecoration(
- border: Border.all(color: Theme.of(context).colorScheme.onBackground),
- shape: BoxShape.circle
- ),
- child: IconButton(
- tooltip: AppLocalizations.of(context)!.addExportformat,
- onPressed:() {
- Navigator.of(context).push(MaterialPageRoute(builder: (context) => const EditExportColumnPage()));
- },
- icon: const Icon(Icons.add),
- ),
- ),
- child: child,
- );
- }
-
- Widget _buildManagePresetsBadge(BuildContext context, ExportColumnsManager manager, {required Widget child}) {
- final exportConfigurations = result.exportConfigurations;
- return badges.Badge(
- position: badges.BadgePosition.topEnd(top: 3, end: 3),
- badgeStyle: badges.BadgeStyle(
- badgeColor: Theme.of(context).colorScheme.background,
- padding: const EdgeInsets.all(5)
- ),
- badgeContent: PopupMenuButton<int>(
- icon: const Icon(Icons.collections_bookmark),
- itemBuilder: (BuildContext context) {
- return [
- for (var i = 0; i< exportConfigurations.length; i++)
- PopupMenuItem<int>(value: i, child: Text(exportConfigurations[i].$1)),
- ];
- },
- onSelected: (value) {
- final exportSettings = Provider.of<ExportSettings>(context, listen: false);
- if (exportSettings.exportFormat == ExportFormat.csv) {
- Provider.of<CsvExportSettings>(context, listen: false).customFields = exportConfigurations[value].$2;
- } else {
- assert(exportSettings.exportFormat == ExportFormat.pdf);
- Provider.of<PdfExportSettings>(context, listen: false).customFields = exportConfigurations[value].$2;
- }
- },
- ),
- child: child,
- );
- }
-
- Widget _buildListItemTrailing(BuildContext context, ExportColumn data, ExportConfigurationModel config) {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- if (data.editable)
- IconButton(
- onPressed: () async {
- setState(() {
- config.delete(data);
- });
- },
- tooltip: AppLocalizations.of(context)!.delete,
- icon: const Icon(Icons.delete),
- color: Colors.red,
- ),
- IconButton(
- onPressed: () {
- Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
- EditExportColumnPage(
- initialDisplayName: data.columnTitle,
- initialInternalName: data.internalName,
- initialFormatPattern: data.formatPattern,
- editable: data.editable,
- )
- ));
- },
- tooltip: AppLocalizations.of(context)!.edit,
- icon: const Icon(Icons.edit)
- ),
- const Icon(Icons.drag_handle),
- ],
- );
- }
-
- Widget _buildListSectionDivider(BuildContext context) {
- return IgnorePointer(
- key: UniqueKey(),
- child: Opacity(
- opacity: 0.7,
- child: Row(
- children: <Widget>[
- const Expanded(
- child: Divider()
- ),
- Container(
- padding: const EdgeInsets.all(10),
- child: const Icon(Icons.arrow_downward)
- ),
- Text(AppLocalizations.of(context)!.exportHiddenFields),
- Container(
- padding: const EdgeInsets.all(10),
- child: const Icon(Icons.arrow_downward)
- ),
- const Expanded(
- child: Divider()
- ),
- ]
- ),
- ),
- );
- }
-
- _onReorderList(oldIndex, newIndex) {
- /**
- * We have a list of items that is structured like the following:
- * [ exportItems.length, 1, exportAddableItems.length ]
- *
- * So oldIndex is either (0 <= oldIndex < exportItems.length) or
- * ((exportItems.length + 1) <= oldIndex < (exportItems.length + 1 + exportAddableItems.length))
- * newIndex is in the range (0 <= newIndex < (exportItems.length + 1 + exportAddableItems.length))
- *
- * In case the entry is moved upwards on the list the new position needs to have 1 subtracted because there
- * is an entry missing above it now.
- *
- * If the newIndex is (0 <= newIndex < (exportItems.length + 1)) the Item got moved above the divider.
- * The + 1 is needed to compensate for moving the item one position above the divider and thereby replacing
- * its index.
- */
- if (oldIndex < newIndex) {
- newIndex -= 1;
- }
-
- final ExportColumn item;
- if (0 <= oldIndex && oldIndex < widget.shownItems.length) {
- item = widget.shownItems.removeAt(oldIndex);
- } else if ((widget.shownItems.length + 1) <= oldIndex && oldIndex < (widget.shownItems.length + 1 + widget.disabledItems.length)) {
- item = widget.disabledItems.removeAt(oldIndex - (widget.shownItems.length + 1));
- } else {
- assert(false, 'oldIndex outside expected boundaries');
- return;
- }
-
- if (newIndex < (widget.shownItems.length + 1)) {
- widget.shownItems.insert(newIndex, item);
- } else {
- newIndex -= (widget.shownItems.length + 1);
- widget.disabledItems.insert(newIndex, item);
- }
-
- widget.onReorder(widget.shownItems, widget.disabledItems);
- }
-
- */
-}
lib/l10n/app_en.arb
@@ -470,5 +470,7 @@
"type": "String"
}
}
- }
+ },
+ "exportFieldsPreset": "Export fields preset",
+ "@exportFieldsPreset": {}
}
lib/model/export_import/export_configuration.dart
@@ -37,7 +37,9 @@ class ActiveExportColumnConfiguration extends ChangeNotifier {
'preset': _activePreset.encode()
});
- /// The last selected columns, different from [getActiveColumns].
+ /// The [UserColumn.internalIdentifier] of columns currently selected by user.
+ ///
+ /// Note that this is persistent different from [getActiveColumns].
final List<String> _userSelectedColumns;
ExportImportPreset _activePreset;
@@ -47,6 +49,26 @@ class ActiveExportColumnConfiguration extends ChangeNotifier {
notifyListeners();
}
+ /// Put the user column at [oldIndex] to [newIndex].
+ void reorderUserColumns(int oldIndex, int newIndex) {
+ assert(_activePreset == ExportImportPreset.none, 'user columns are not modifiable while another configuration is active');
+ assert(oldIndex >= 0 && oldIndex < _userSelectedColumns.length);
+ assert(newIndex >= 0 && newIndex < _userSelectedColumns.length);
+ if (oldIndex < newIndex) {
+ newIndex -= 1;
+ }
+ final item = _userSelectedColumns.removeAt(oldIndex);
+ _userSelectedColumns.insert(newIndex, item);
+ notifyListeners();
+ }
+
+ /// Add a export column to the end of user columns.
+ void addUserColumn(ExportColumn column) {
+ assert(_activePreset == ExportImportPreset.none, 'user columns are not modifiable while another configuration is active');
+ _userSelectedColumns.add(column.internalIdentifier);
+ notifyListeners();
+ }
+
/// Columns to respect for export.
UnmodifiableListView<ExportColumn> getActiveColumns(ExportColumnsManager availableColumns) => UnmodifiableListView(
switch (_activePreset) {
lib/model/export_import/legacy_column.dart
@@ -4,11 +4,11 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
/// Convert [BloodPressureRecord]s from and to strings and provide metadata about the conversion.
@Deprecated("repaced by class in column.dart")
-class ExportColumn { // TODO: change this class so it implements the interface.
+class LegacyExportColumn { // TODO: change this class so it implements the interface.
/// Create object that turns data into strings.
///
/// Example: ExportColumn(internalColumnName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: '{{$SYS-$DIA}}')
- ExportColumn({required this.internalName, required this.columnTitle, required String formatPattern, this.editable = true, this.hidden = false}) {
+ LegacyExportColumn({required this.internalName, required this.columnTitle, required String formatPattern, this.editable = true, this.hidden = false}) {
this.formatPattern = formatPattern.replaceAll('{{}}', '');
_formatter = ScriptedFormatter(formatPattern);
}
@@ -44,8 +44,8 @@ class ExportColumn { // TODO: change this class so it implements the interface.
/// doesn't show up as unused / hidden field in list
final bool hidden;
- factory ExportColumn.fromJson(Map<String, dynamic> json, [editable = true, hidden = false]) =>
- ExportColumn(
+ factory LegacyExportColumn.fromJson(Map<String, dynamic> json, [editable = true, hidden = false]) =>
+ LegacyExportColumn(
internalName: json['internalColumnName'],
columnTitle: json['columnTitle'],
formatPattern: json['formatPattern'],
@@ -82,7 +82,7 @@ class ExportColumn { // TODO: change this class so it implements the interface.
/// Type a [Formatter] can uses to indicate the kind of data returned.
///
-/// The data types returned from the deprecated [ExportColumn] may differ from the guarantees.
+/// The data types returned from the deprecated [LegacyExportColumn] may differ from the guarantees.
enum RowDataFieldType {
/// Guarantees [DateTime] is returned.
timestamp,
lib/model/storage/db/config_dao.dart
@@ -313,14 +313,14 @@ class ConfigDao {
/// Loads the current export columns from the database.
///
/// Changes will *not* be saved automatically, see [updateExportColumn].
- Future<List<ExportColumn>> loadExportColumns() async {
+ Future<List<LegacyExportColumn>> loadExportColumns() async {
final existingDbEntries = await _configDB.database.query(
ConfigDB.exportStringsTable,
columns: ['internalColumnName', 'columnTitle', 'formatPattern']
);
return [
for (final e in existingDbEntries)
- ExportColumn(
+ LegacyExportColumn(
internalName: e['internalColumnName'].toString(),
columnTitle: e['columnTitle'].toString(),
formatPattern: e['formatPattern'].toString()
@@ -328,10 +328,10 @@ class ConfigDao {
];
}
- /// Saves a [ExportColumn] to the database.
+ /// Saves a [LegacyExportColumn] to the database.
///
- /// If one with the same [ExportColumn.internalName] exists, it will get replaced by the new one regardless of content.
- Future<void> updateExportColumn(ExportColumn exportColumn) async {
+ /// If one with the same [LegacyExportColumn.internalName] exists, it will get replaced by the new one regardless of content.
+ Future<void> updateExportColumn(LegacyExportColumn exportColumn) async {
if (!_configDB.database.isOpen) return;
await _configDB.database.insert(
ConfigDB.exportStringsTable,
@@ -344,7 +344,7 @@ class ConfigDao {
);
}
- /// Deletes the [ExportColumn] where [ExportColumn.internalName] matches [internalName] from the database.
+ /// Deletes the [LegacyExportColumn] where [LegacyExportColumn.internalName] matches [internalName] from the database.
Future<void> deleteExportColumn(String internalName) async {
if (!_configDB.database.isOpen) return;
await _configDB.database.delete('exportStrings', where: 'internalColumnName = ?', whereArgs: [internalName]);
lib/model/storage/export_columns_store.dart
@@ -58,6 +58,17 @@ class ExportColumnsManager extends ChangeNotifier { // TODO: separate ExportColu
// ?? ...
}
+ /// Returns a list of all userColumns, NativeColumns and BuildInColumns defined.
+ ///
+ /// Prefer using other methods like [firstWhere] when possible.
+ UnmodifiableListView<ExportColumn> getAllColumns() {
+ final columns = <ExportColumn>[];
+ columns.addAll(NativeColumn.allColumns);
+ columns.addAll(userColumns.values);
+ columns.addAll(BuildInColumn.allColumns);
+ return UnmodifiableListView(columns);
+ }
+
String toJson() { // TODO: update from and TO json to new style
final columns = [];
for (final c in _userColumns.values) {
lib/model/export_options.dart
@@ -21,7 +21,7 @@ class ExportConfigurationModel {
final AppLocalizations localizations;
final ConfigDao _configDao; // TODO: remove after #181 is complete
- final List<ExportColumn> _availableFormats = [];
+ final List<LegacyExportColumn> _availableFormats = [];
/// Format: (title, List<internalNameOfExportFormat>)
List<(String, List<String>)> get exportConfigurations => [
@@ -48,56 +48,56 @@ class ExportConfigurationModel {
///
/// The [fieldSettings] parameter describes the settings of the current export format and should be set accordingly.
@Deprecated('not implemented anymore')
- List<ExportColumn> getActiveExportColumns(ExportFormat format, CustomFieldsSettings fieldsSettings) {
+ List<LegacyExportColumn> getActiveExportColumns(ExportFormat format, CustomFieldsSettings fieldsSettings) {
return [];
}
- List<ExportColumn> getDefaultFormates() => [
- ExportColumn(internalName: 'timestampUnixMs', columnTitle: localizations.unixTimestamp, formatPattern: r'$TIMESTAMP', editable: false),
- ExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,yyyy-MM-dd HH:mm:ss}', editable: false),
- ExportColumn(internalName: 'systolic', columnTitle: localizations.sysLong, formatPattern: r'$SYS', editable: false),
- ExportColumn(internalName: 'diastolic', columnTitle: localizations.diaLong, formatPattern: r'$DIA', editable: false),
- ExportColumn(internalName: 'pulse', columnTitle: localizations.pulLong, formatPattern: r'$PUL', editable: false),
- ExportColumn(internalName: 'notes', columnTitle: localizations.notes, formatPattern: r'$NOTE', editable: false),
- ExportColumn(internalName: 'pulsePressure', columnTitle: localizations.pulsePressure, formatPattern: r'{{$SYS-$DIA}}', editable: false),
- ExportColumn(internalName: 'color', columnTitle: localizations.color, formatPattern: r'$COLOR', editable: false),
+ List<LegacyExportColumn> getDefaultFormates() => [
+ LegacyExportColumn(internalName: 'timestampUnixMs', columnTitle: localizations.unixTimestamp, formatPattern: r'$TIMESTAMP', editable: false),
+ LegacyExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,yyyy-MM-dd HH:mm:ss}', editable: false),
+ LegacyExportColumn(internalName: 'systolic', columnTitle: localizations.sysLong, formatPattern: r'$SYS', editable: false),
+ LegacyExportColumn(internalName: 'diastolic', columnTitle: localizations.diaLong, formatPattern: r'$DIA', editable: false),
+ LegacyExportColumn(internalName: 'pulse', columnTitle: localizations.pulLong, formatPattern: r'$PUL', editable: false),
+ LegacyExportColumn(internalName: 'notes', columnTitle: localizations.notes, formatPattern: r'$NOTE', editable: false),
+ LegacyExportColumn(internalName: 'pulsePressure', columnTitle: localizations.pulsePressure, formatPattern: r'{{$SYS-$DIA}}', editable: false),
+ LegacyExportColumn(internalName: 'color', columnTitle: localizations.color, formatPattern: r'$COLOR', editable: false),
- ExportColumn(internalName: 'DATUM', columnTitle: '"My Heart" export time', formatPattern: r'$FORMAT{$TIMESTAMP,yyyy-MM-dd HH:mm:ss}', editable: false, hidden: true),
- ExportColumn(internalName: 'SYSTOLE', columnTitle: '"My Heart" export sys', formatPattern: r'$SYS', editable: false, hidden: true),
- ExportColumn(internalName: 'DIASTOLE', columnTitle: '"My Heart" export dia', formatPattern: r'$DIA', editable: false, hidden: true),
- ExportColumn(internalName: 'PULS', columnTitle: '"My Heart" export pul', formatPattern: r'$PUL', editable: false, hidden: true),
- ExportColumn(internalName: 'Beschreibung', columnTitle: '"My Heart" export description', formatPattern: r'null', editable: false, hidden: true),
- ExportColumn(internalName: 'Tags', columnTitle: '"My Heart" export tags', formatPattern: r'', editable: false, hidden: true),
- ExportColumn(internalName: 'Gewicht', columnTitle: '"My Heart" export weight', formatPattern: r'0.0', editable: false, hidden: true),
- ExportColumn(internalName: 'Sauerstoffsättigung', columnTitle: '"My Heart" export oxygen', formatPattern: r'0', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'DATUM', columnTitle: '"My Heart" export time', formatPattern: r'$FORMAT{$TIMESTAMP,yyyy-MM-dd HH:mm:ss}', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'SYSTOLE', columnTitle: '"My Heart" export sys', formatPattern: r'$SYS', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'DIASTOLE', columnTitle: '"My Heart" export dia', formatPattern: r'$DIA', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'PULS', columnTitle: '"My Heart" export pul', formatPattern: r'$PUL', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'Beschreibung', columnTitle: '"My Heart" export description', formatPattern: r'null', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'Tags', columnTitle: '"My Heart" export tags', formatPattern: r'', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'Gewicht', columnTitle: '"My Heart" export weight', formatPattern: r'0.0', editable: false, hidden: true),
+ LegacyExportColumn(internalName: 'Sauerstoffsättigung', columnTitle: '"My Heart" export oxygen', formatPattern: r'0', editable: false, hidden: true),
];
- /// Saves a new [ExportColumn] to the list of the available columns.
+ /// Saves a new [LegacyExportColumn] to the list of the available columns.
///
/// In case one with the same internal name exists it gets updated with the new values
- void addOrUpdate(ExportColumn format) {
+ void addOrUpdate(LegacyExportColumn format) {
_availableFormats.removeWhere((e) => e.internalName == format.internalName);
_availableFormats.add(format);
_configDao.updateExportColumn(format);
}
- void delete(ExportColumn format) {
+ void delete(LegacyExportColumn format) {
final existingEntries = _availableFormats.where((element) => (element.internalName == format.internalName) && element.editable);
assert(existingEntries.isNotEmpty, r"Tried to delete entry that doesn't exist or is not editable.");
_availableFormats.removeWhere((element) => element.internalName == format.internalName);
_configDao.deleteExportColumn(format.internalName);
}
- UnmodifiableListView<ExportColumn> get availableFormats => UnmodifiableListView(_availableFormats);
- UnmodifiableMapView<String, ExportColumn> get availableFormatsMap =>
+ UnmodifiableListView<LegacyExportColumn> get availableFormats => UnmodifiableListView(_availableFormats);
+ UnmodifiableMapView<String, LegacyExportColumn> get availableFormatsMap =>
UnmodifiableMapView(Map.fromIterable(_availableFormats, key: (e) => e.internalName));
/// Creates list of rows with that follow the order and format described by [activeExportColumns].
///
- /// The [createHeadline] option will create put a row at the start that contains [ExportColumn.internalName] of the
+ /// The [createHeadline] option will create put a row at the start that contains [LegacyExportColumn.internalName] of the
/// given [activeExportColumns].
- List<List<String>> createTable(Iterable<BloodPressureRecord> data, List<ExportColumn> activeExportColumns,
+ List<List<String>> createTable(Iterable<BloodPressureRecord> data, List<LegacyExportColumn> activeExportColumns,
{bool createHeadline = true,}) {
List<List<String>> items = [];
if (createHeadline) {
lib/screens/subsettings/export_column_data.dart
@@ -127,7 +127,7 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
return localizations.errNoValue;
} else if (_internalName != null && _displayName != null) {
try {
- final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: value);
+ final column = LegacyExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: value);
column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, ''));
_formatPattern = value;
} catch (e) {
@@ -142,7 +142,7 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
const SizedBox(height: 12,),
Text(localizations.result),
Text(((){try {
- final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: _formatPattern!);
+ final column = LegacyExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: _formatPattern!);
return column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, 'test'));
} catch (e) {
return '-';
@@ -170,7 +170,7 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
onPressed: (widget.editable) ? (() async {
if (_formKey.currentState?.validate() ?? false) {
final navigator = Navigator.of(context);
- exportConfigurationModel.addOrUpdate(ExportColumn(
+ exportConfigurationModel.addOrUpdate(LegacyExportColumn(
internalName: _internalName!,
columnTitle: _displayName!,
formatPattern: _formatPattern!
lib/screens/subsettings/export_import_screen.dart
@@ -7,6 +7,7 @@ import 'package:blood_pressure_app/components/diabled.dart';
import 'package:blood_pressure_app/components/display_interval_picker.dart';
import 'package:blood_pressure_app/components/settings/settings_widgets.dart';
import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/export_import/column.dart';
import 'package:blood_pressure_app/model/export_import/csv_converter.dart';
import 'package:blood_pressure_app/model/export_import/export_configuration.dart';
import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
@@ -106,9 +107,6 @@ class ExportImportScreen extends StatelessWidget {
csvExportSettings.exportHeadline = value;
}
),
- ExportFieldCustomisationSetting(
- fieldsSettings: csvExportSettings,
- ),
],
)
),
@@ -165,14 +163,14 @@ class ExportImportScreen extends StatelessWidget {
pdfExportSettings.cellFontSize = value;
},
),
- ExportFieldCustomisationSetting(
- fieldsSettings: pdfExportSettings,
- ),
],
),
]
)
),
+ ExportFieldCustomisationSetting(
+ format: settings.exportFormat,
+ ),
],
),
);
@@ -182,52 +180,96 @@ class ExportImportScreen extends StatelessWidget {
}
}
-class ExportFieldCustomisationSetting extends StatelessWidget {
- const ExportFieldCustomisationSetting({super.key, required this.fieldsSettings});
+class ExportFieldCustomisationSetting extends StatelessWidget { // TODO: consider extracting class into file
+ const ExportFieldCustomisationSetting({super.key,
+ required this.format,});
- final CustomFieldsSettings fieldsSettings;
+ final ExportFormat format;
@override
- Widget build(BuildContext context) {
+ Widget build(BuildContext context) => switch (format) {
+ ExportFormat.csv => Consumer<CsvExportSettings>(builder: _builder),
+ ExportFormat.pdf => Consumer<PdfExportSettings>(builder: _builder),
+ ExportFormat.db => const SizedBox.shrink()
+ };
+
+ Widget _builder(BuildContext context, CustomFieldsSettings settings, Widget? child) {
final localizations = AppLocalizations.of(context)!;
- return ConsistentFutureBuilder(
- future: ExportConfigurationModel.get(localizations),
- lastChildWhileWaiting: true,
- onData: (context, configurationModel) {
- return const Text('TODO - ExportFieldCustomisationSetting');
- /* TODO: rewrite with dropdown and reorderable list view, consider extracting this class into file
- return Consumer<ExportSettings>(builder: (context, settings, child) {
- final formats = configurationModel.availableFormats.toSet();
- List<ExportColumn> activeFields = configurationModel
- .getActiveExportColumns(settings.exportFormat, fieldsSettings);
- List<ExportColumn> hiddenFields = [];
- for (final internalName in fieldsSettings.customFields) {
- formats.removeWhere((e) => e.internalName == internalName);
- }
- hiddenFields = formats.toList();
+ final fieldsConfig = settings.exportFieldsConfiguration;
+ final dropdown = DropDownListTile(
+ title: Text(localizations.exportFieldsPreset),
+ value: fieldsConfig.activePreset,
+ items: ExportImportPreset.values.map(
+ (e) => DropdownMenuItem(
+ value: e,
+ child: Text(e.localize(localizations)),
+ )
+ ).toList(),
+ onChanged: (selectedPreset) {
+ if (selectedPreset != null) {
+ fieldsConfig.activePreset = selectedPreset;
+ }
+ },
+ );
- return Column(
- children: [
- SwitchListTile(
- title: Text(localizations.exportCustomEntries),
- value: fieldsSettings.exportCustomFields,
- onChanged: (value) {
- fieldsSettings.exportCustomFields = value;
- }
- ),
- if (fieldsSettings.exportCustomFields)
- ExportItemsCustomizer(
- shownItems: activeFields,
- disabledItems: hiddenFields,
- onReorder: (exportItems, exportAddableItems) {
- fieldsSettings.customFields = exportItems.map((e) => e.internalName).toList();
- },
- ),
- ],
- );
- });
- */
- }
+ if (fieldsConfig.activePreset != ExportImportPreset.none) {
+ return dropdown;
+ }
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ dropdown,
+ Container(
+ margin: const EdgeInsets.all(16),
+ height: 400,
+ decoration: BoxDecoration(
+ border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
+ borderRadius: const BorderRadius.all(Radius.circular(10)),
+ ),
+ child: Consumer<ExportColumnsManager>(
+ builder: (context, availableColumns, child) {
+ final activeColumns = fieldsConfig.getActiveColumns(availableColumns);
+ return ReorderableListView.builder(
+ itemBuilder: (context, idx) {
+ if (idx >= activeColumns.length) {
+ return ListTile(
+ key: const Key('add field'),
+ leading: const Icon(Icons.add),
+ title: Text(localizations.addEntry),
+ onTap: () async {
+ final column = await showDialog<ExportColumn?>(context: context, builder: (context) =>
+ SimpleDialog(
+ title: Text(localizations.addEntry),
+ insetPadding: EdgeInsets.symmetric(
+ vertical: 64,
+ ),
+ children: availableColumns.getAllColumns().map((column) =>
+ ListTile(
+ title: Text(column.userTitle(localizations)),
+ onTap: () => Navigator.of(context).pop(column),
+ )
+ ).toList(),
+ )
+ );
+ if (column != null) fieldsConfig.addUserColumn(column);
+ },
+ );
+ }
+ return ListTile(
+ key: Key(activeColumns[idx].internalIdentifier + idx.toString()),
+ title: Text(activeColumns[idx].userTitle(localizations)),
+ trailing: const Icon(Icons.drag_handle),
+ // TODO: removing columns
+ );
+ },
+ itemCount: activeColumns.length + 1,
+ onReorder: fieldsConfig.reorderUserColumns
+ );
+ }
+ ),
+ )
+ // TODO implement adding / editing columns => separate ColumnsManagerScreen ?
+ ],
);
}
}
pubspec.lock
@@ -41,14 +41,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
- badges:
- dependency: "direct main"
- description:
- name: badges
- sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84
- url: "https://pub.dev"
- source: hosted
- version: "3.1.2"
barcode:
dependency: transitive
description:
pubspec.yaml
@@ -24,7 +24,6 @@ dependencies:
pdf: ^3.10.4
package_info_plus: ^4.0.2
function_tree: ^0.9.0
- badges: ^3.1.1
flutter_markdown: ^0.6.17
collection: ^1.17.1