Commit 97bf77a

derdilla <derdilla06@gmail.com>
2023-08-02 12:06:44
fix todos
1 parent e26f182
lib/components/export_item_order.dart
@@ -45,11 +45,11 @@ class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
                 shape: BoxShape.circle
             ),
             child: IconButton(
-              tooltip: 'add exportformat',
-              onPressed:() {// TODO move outside of potential reusable thing
+              tooltip: AppLocalizations.of(context)!.addExportformat,
+              onPressed:() {
                 Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
                   EditExportColumnPage(onValidSubmit: (value) {
-                    result.add(value); 
+                    result.addOrUpdate(value);
                   },)
                 ));
               },
@@ -106,8 +106,10 @@ class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
                   initialDisplayName: data.columnTitle,
                   initialInternalName: data.internalName,
                   initialFormatPattern: data.formatPattern,
-                  onValidSubmit: (value) {
-                    // TODO save
+                  editable: data.editable,
+                  onValidSubmit: (value) async {
+                    final config = await ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), AppLocalizations.of(context)!);
+                    config.addOrUpdate(value);
                   },
                 )
             ));
lib/components/settings_widgets.dart
@@ -164,10 +164,7 @@ class SwitchSettingsTile extends StatelessWidget {
       leading: leading,
       description: description,
       disabled: disabled,
-      trailing: Theme(
-        data: Theme.of(context).copyWith(useMaterial3: true),
-        child: s
-      ),
+      trailing: s,
     );
   }
 }
lib/l10n/app_en.arb
@@ -368,5 +368,12 @@
   "fieldFormat": "Field format",
   "@fieldFormat": {},
   "result": "Result:",
-  "@result": {}
+  "@result": {},
+  "pulsePressure": "Pulse pressure",
+  "@pulsePressure": {},
+  "unixTimestamp" : "Unix timestamp",
+  "@unixTimestamp": {},
+  "errCantEditThis": "You can't edit this. Feel free to look at the values for creating a new entry.",
+  "addExportformat": "Add exportformat",
+  "@addExportformat": {}
 }
lib/model/export_import.dart
@@ -26,6 +26,7 @@ extension PdfCompatability on Color {
   }
 }
 
+// TODO: respect new export columns
 class ExportFileCreator {
   final Settings settings;
   final AppLocalizations localizations;
lib/model/export_options.dart
@@ -48,17 +48,31 @@ class ExportConfigurationModel {
     return _instance!;
   }
 
-  List<ExportColumn> _getDefaultFormates() => [ // TODO: localizations
-    ExportColumn(internalName: 'timestampUnixMs', columnTitle: 'Unix timestamp', formatPattern: r'$TIMESTAMP'),
-    ExportColumn(internalName: 'formattedTimestamp', columnTitle: 'Time', formatPattern: '\$FORMAT{\$TIMESTAMP,${settings.dateFormatString}}'),
-    ExportColumn(internalName: 'systolic', columnTitle: 'Systolic', formatPattern: r'$SYS'),
-    ExportColumn(internalName: 'diastolic', columnTitle: 'Diastolic', formatPattern: r'$DIA'),
-    ExportColumn(internalName: 'pulse', columnTitle: 'Pulse', formatPattern: r'$PUL'),
-    ExportColumn(internalName: 'notes', columnTitle: 'Notes', formatPattern: r'$NOTE'),
-    ExportColumn(internalName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: r'{{$SYS-$DIA}}')
+  List<ExportColumn> _getDefaultFormates() => [
+    ExportColumn(internalName: 'timestampUnixMs', columnTitle: localizations.unixTimestamp, formatPattern: r'$TIMESTAMP', editable: false),
+    ExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,${settings.dateFormatString}}', 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)
   ];
 
-  void add(ExportColumn format) {
+  void addOrUpdate(ExportColumn format) {
+    final existingEntries = _availableFormats.where((element) => element.internalName == format.internalName);
+    if (existingEntries.isNotEmpty) {
+      assert(existingEntries.length == 1);
+      if (!existingEntries.first.editable) {
+        assert(false, 'Attempted to update non editable field. While this doesn\'t cause any direct issues, it should not be made possible through the UI.');
+        return;
+      }
+      _availableFormats.remove(existingEntries.first);
+      _availableFormats.add(format);
+      _database.update('exportStrings', {
+        'columnTitle': format.columnTitle,
+        'formatPattern': format.formatPattern
+      }, where: 'internalColumnName = ?', whereArgs: [format.internalName]);
+    }
     _availableFormats.add(format);
     _database.insert('exportStrings', {
       'internalColumnName': format.internalName,
@@ -67,7 +81,8 @@ class ExportConfigurationModel {
     },);
   }
 
-  UnmodifiableMapView<String, ExportColumn> get availableFormats =>
+  UnmodifiableListView<ExportColumn> get availableFormats => UnmodifiableListView(_availableFormats);
+  UnmodifiableMapView<String, ExportColumn> get availableFormatsMap =>
       UnmodifiableMapView(Map.fromIterable(_availableFormats, key: (e) => e.internalName));
 }
 
@@ -76,7 +91,7 @@ class ExportColumn {
   late final String internalName;
   /// Display title of the column. Possibly localized
   late final String columnTitle;
-  /// Pattern to create the field contents from: TODO implement user input and documentation
+  /// Pattern to create the field contents from: TODO documentation
   /// It supports inserting values for $TIMESTAMP, $SYS $DIA $PUL and $NOTE. Where $TIMESTAMP is the time since unix epoch in milliseconds.
   /// To format a timestamp in the same format as the $TIMESTAMP variable, $FORMAT(<timestamp>, <formatString>).
   /// It is supported to use basic mathematics inside of double brackets ("{{}}"). In case one of them is not present in the record, -1 is provided.
@@ -93,16 +108,18 @@ class ExportColumn {
   /// 3. Date format
   late final String formatPattern;
 
+  final bool editable;
+
   /// Example: ExportColumn(internalColumnName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: '{{$SYS-$DIA}}')
-  ExportColumn({required this.internalName, required this.columnTitle, required String formatPattern}) {
+  ExportColumn({required this.internalName, required this.columnTitle, required String formatPattern, this.editable = true}) {
     this.formatPattern = formatPattern.replaceAll('{{}}', '');
   }
 
-  ExportColumn.fromJson(Map<String, dynamic> json) {
+  ExportColumn.fromJson(Map<String, dynamic> json, [this.editable = true]) {
     ExportColumn(
       internalName: json['internalColumnName'],
       columnTitle: json['columnTitle'],
-      formatPattern: json['formatPattern']
+      formatPattern: json['formatPattern'],
     );
   }
 
lib/model/ram_only_implementations.dart
@@ -62,7 +62,6 @@ class RamSettings extends ChangeNotifier implements Settings {
   ExportFormat _exportFormat = ExportFormat.csv;
   String _csvFieldDelimiter = ',';
   String _csvTextDelimiter = '"';
-  List<String> _exportAddableItems = ['isoUTCTime'];
   bool _exportCsvHeadline = true;
   bool _exportCustomEntries = false;
   List<String> _exportItems = ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes'];
@@ -301,15 +300,6 @@ class RamSettings extends ChangeNotifier implements Settings {
     notifyListeners();
   }
 
-  @override
-  List<String> get exportAddableItems => _exportAddableItems;
-
-  @override
-  set exportAddableItems(List<String> value) {
-    _exportAddableItems = value;
-    notifyListeners();
-  }
-
   @override
   bool get exportCsvHeadline => _exportCsvHeadline;
 
lib/model/settings_store.dart
@@ -42,6 +42,9 @@ class Settings extends ChangeNotifier {
     if (keys.contains('exportDataRangeEndEpochMs')) {
       toAwait.add(_prefs.remove('exportDataRangeEndEpochMs'));
     }
+    if (keys.contains('exportAddableItems')) {
+      toAwait.add(_prefs.remove('exportAddableItems'));
+    }
 
     for (var e in toAwait) {
       await e;
@@ -443,15 +446,7 @@ class Settings extends ChangeNotifier {
     _prefs.setBool('exportCustomEntries', value);
     notifyListeners();
   }
-  
-  List<String> get exportAddableItems {
-    return _prefs.getStringList('exportAddableItems') ?? ['isoUTCTime'];
-  }
 
-  set exportAddableItems(List<String> value) {
-    _prefs.setStringList('exportAddableItems', value);
-    notifyListeners();
-  }
   List<String> get exportItems {
     return _prefs.getStringList('exportItems') ?? ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes'];
   }
lib/screens/subsettings/export_column_data.dart
@@ -8,9 +8,10 @@ class  EditExportColumnPage extends StatefulWidget {
   final String? initialDisplayName;
   final String? initialFormatPattern;
   final void Function(ExportColumn) onValidSubmit;
+  final bool editable;
   
   const EditExportColumnPage({super.key, this.initialDisplayName, this.initialInternalName, 
-    this.initialFormatPattern, required this.onValidSubmit});
+    this.initialFormatPattern, required this.onValidSubmit, this.editable = true});
 
   @override
   State<EditExportColumnPage> createState() => _EditExportColumnPageState();
@@ -48,78 +49,91 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
               child: Column(
                 mainAxisSize: MainAxisSize.min,
                 children: [
-                  TextFormField(
-                    key: const Key('displayName'),
-                    initialValue: _displayName,
-                    decoration: InputDecoration(hintText: localizations.displayTitle),
-                    onChanged: (String? value) {
-                      if (value != null && value.isNotEmpty) {
-                        setState(() {
-                          _displayName = value;
-                        });
-                        if (_editedInternalName) return;
-                        final asciiName = value.replaceAll(RegExp(r'[^A-Za-z0-9 ]'), '');
-                        final internalName = asciiName.replaceAllMapped(RegExp(r' (.)'), (match) {
-                          return match.group(1)!.toUpperCase();
-                        }).replaceAll(' ', '');
-                        setState(() {
-                          _internalNameKeyNr++;
-                          _internalName = internalName;
-                        });
-                      }
-                    },
-                  ),
-                  TextFormField(
-                    key: Key('internalName$_internalNameKeyNr'), // it should update when display name is changed without unfocussing on edit
-                    initialValue: _internalName,
-                    decoration: InputDecoration(hintText: localizations.internalName),
-                    validator: (String? value) {
-                      if (value == null || value.isEmpty || RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
-                        return localizations.errOnlyLatinCharactersAndArabicNumbers;
-                      } // TODO: check if one with this name already exists
-                      return null;
-                    },
-                    onChanged: (String? value) {
-                      if (value != null && value.isNotEmpty && !RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
-                        setState(() {
-                          _internalName = value;
-                          _editedInternalName = true;
-                        });
-                      }
-                    },
-                  ),
-                  TextFormField( // TODO: documentation
-                    key: const Key('formatPattern'),
-                    initialValue: _formatPattern,
-                    decoration: InputDecoration(hintText: localizations.fieldFormat),
-                    maxLines: 6,
-                    minLines: 1,
-                    validator: (String? value) {
-                      if (value == null || value.isEmpty) {
-                        return AppLocalizations.of(context)!.errNoValue;
-                      } else if (_internalName != null && _displayName != null) {
-                        try {
-                          final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: value);
-                          column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, ''));
-                          _formatPattern = value;
-                        } catch (e) {
-                          _formatPattern = null;
-                          return e.toString();
-                        }
-                      }
-                      return null;
-                    },
-                    onChanged: (value) => setState(() {_formatPattern = value;}),
+                  if (!widget.editable)
+                    Text(localizations.errCantEditThis),
+                  Opacity(
+                    opacity: widget.editable ? 1 : 0.7,
+                    child: IgnorePointer(
+                      ignoring: !widget.editable,
+                      child: Column(
+                        mainAxisSize: MainAxisSize.min,
+                        children: [
+                          TextFormField(
+                            key: const Key('displayName'),
+                            initialValue: _displayName,
+                            decoration: InputDecoration(hintText: localizations.displayTitle),
+                            onChanged: (String? value) {
+                              if (value != null && value.isNotEmpty) {
+                                setState(() {
+                                  _displayName = value;
+                                });
+                                if (_editedInternalName) return;
+                                final asciiName = value.replaceAll(RegExp(r'[^A-Za-z0-9 ]'), '');
+                                final internalName = asciiName.replaceAllMapped(RegExp(r' (.)'), (match) {
+                                  return match.group(1)!.toUpperCase();
+                                }).replaceAll(' ', '');
+                                setState(() {
+                                  _internalNameKeyNr++;
+                                  _internalName = internalName;
+                                });
+                              }
+                            },
+                          ),
+                          TextFormField(
+                            key: Key('internalName$_internalNameKeyNr'), // it should update when display name is changed without unfocussing on edit
+                            initialValue: _internalName,
+                            decoration: InputDecoration(hintText: localizations.internalName),
+                            validator: (String? value) {
+                              if (value == null || value.isEmpty || RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
+                                return localizations.errOnlyLatinCharactersAndArabicNumbers;
+                              } // TODO: check if one with this name already exists
+                              return null;
+                            },
+                            onChanged: (String? value) {
+                              if (value != null && value.isNotEmpty && !RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
+                                setState(() {
+                                  _internalName = value;
+                                  _editedInternalName = true;
+                                });
+                              }
+                            },
+                          ),
+                          TextFormField( // TODO: documentation
+                            key: const Key('formatPattern'),
+                            initialValue: _formatPattern,
+                            decoration: InputDecoration(hintText: localizations.fieldFormat),
+                            maxLines: 6,
+                            minLines: 1,
+                            validator: (String? value) {
+                              if (value == null || value.isEmpty) {
+                                return AppLocalizations.of(context)!.errNoValue;
+                              } else if (_internalName != null && _displayName != null) {
+                                try {
+                                  final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: value);
+                                  column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, ''));
+                                  _formatPattern = value;
+                                } catch (e) {
+                                  _formatPattern = null;
+                                  return e.toString();
+                                }
+                              }
+                              return null;
+                            },
+                            onChanged: (value) => setState(() {_formatPattern = value;}),
+                          ),
+                          const SizedBox(height: 12,),
+                          Text(localizations.result),
+                          Text(((){try {
+                            final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: _formatPattern!);
+                            return column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, 'test'));
+                          } catch (e) {
+                            return '-';
+                          }})()),
+                          const SizedBox(height: 24,),
+                        ],
+                      ),
+                    ),
                   ),
-                  const SizedBox(height: 12,),
-                  Text(localizations.result),
-                  Text(((){try {
-                  final column = ExportColumn(internalName: _internalName!, columnTitle: _displayName!, formatPattern: _formatPattern!);
-                    return column.formatRecord(BloodPressureRecord(DateTime.now(), 100, 80, 60, 'test'));
-                  } catch (e) {
-                    return '-';
-                  }})()),
-                  const SizedBox(height: 24,),
                   Row(
                     children: [
                       TextButton(
@@ -135,7 +149,7 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
                         key: const Key('btnSave'),
                         icon: const Icon(Icons.save),
                         label: Text(AppLocalizations.of(context)!.btnSave),
-                        onPressed: () async {
+                        onPressed: (widget.editable) ? (() async {
                           if (_formKey.currentState?.validate() ?? false) {
                             widget.onValidSubmit(ExportColumn(
                                 internalName: _internalName!,
@@ -144,7 +158,7 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
                             ));
                             Navigator.of(context).pop();
                           }
-                        },
+                        }) : null,
                       )
                     ],
                   )
lib/screens/subsettings/export_import_screen.dart
@@ -29,8 +29,8 @@ class ExportImportScreen extends StatelessWidget {
               const ExportWarnBanner(),
               const SizedBox(height: 15,),
               Opacity(
-                opacity: (settings.exportFormat == ExportFormat.db) ? 0.5 : 1, // TODO: centralize opacity when restyle
-                child: const IntervalPicker(),
+                opacity: (settings.exportFormat == ExportFormat.db) ? 0.7 : 1,
+                child: IgnorePointer(ignoring: (settings.exportFormat == ExportFormat.db), child: const IntervalPicker()),
               ),
               SettingsTile(
                 title: Text(AppLocalizations.of(context)!.exportDir),
@@ -125,16 +125,14 @@ class _ExportFieldCustomisationSettingState extends State<ExportFieldCustomisati
       future: _future!,
       onData: (context, result) {
         return Consumer<Settings>(builder: (context, settings, child) {
-          final formats = result.availableFormats;
+          final formats = result.availableFormats.toSet();
           List<ExportColumn> activeFields = [];
           List<ExportColumn> hiddenFields = [];
-          formats.forEach((internalName, e) { // todo: maintain ordering of exportItems
-            if (settings.exportItems.contains(internalName)) {
-              activeFields.add(e);
-            } else {
-              hiddenFields.add(e);
-            }
-          });
+          for (final internalName in settings.exportItems) {
+            activeFields.add(formats.singleWhere((e) => e.internalName == internalName));
+            formats.removeWhere((e) => e.internalName == internalName);
+          }
+          hiddenFields = formats.toList();
           
           return Column(
             children: [
@@ -152,7 +150,6 @@ class _ExportFieldCustomisationSettingState extends State<ExportFieldCustomisati
                   hiddenItems: hiddenFields,
                   onReorder: (exportItems, exportAddableItems) {
                     settings.exportItems = exportItems.map((e) => e.internalName).toList();
-                    //settings.exportAddableItems = exportAddableItems; // todo remove from data
                   },
                 ) : const SizedBox.shrink()
             ],
lib/screens/add_measurement.dart
@@ -130,9 +130,11 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                             return null;
                           }
                       ),
-                      ValueInput(// TODO: multiline input (minlines and maxlines)
+                      ValueInput(
                           key: const Key('txtPul'),
                           initialValue: (_pulse ?? '').toString(),
+                          minLines: 1,
+                          maxLines: 4,
                           hintText: AppLocalizations.of(context)!.pulLong,
                           basicValidation: !settings.allowMissingValues,
                           preValidation: (v) => _pulse = int.tryParse(v ?? ''),
@@ -216,9 +218,11 @@ class ValueInput extends StatelessWidget {
   final bool basicValidation;
   final void Function(String?)? preValidation;
   final FormFieldValidator<String> additionalValidator;
+  final int? minLines;
+  final int? maxLines;
 
   const ValueInput({super.key, required this.initialValue, required this.hintText, this.focusNode, this.basicValidation = true,
-    this.preValidation, required this.additionalValidator});
+    this.preValidation, required this.additionalValidator, this.minLines, this.maxLines});
 
   @override
   Widget build(BuildContext context) {
@@ -226,6 +230,8 @@ class ValueInput extends StatelessWidget {
       return TextFormField(
         initialValue: initialValue,
         decoration: InputDecoration(hintText: hintText),
+        minLines: minLines,
+        maxLines: maxLines,
         keyboardType: TextInputType.number,
         inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
         focusNode: focusNode,
lib/main.dart
@@ -18,6 +18,7 @@ void main() async {
   ], child: const AppRoot()));
 }
 
+// TODO: centralize disabling
 class AppRoot extends StatelessWidget {
   const AppRoot({super.key});
 
@@ -36,8 +37,6 @@ class AppRoot extends StatelessWidget {
       return MaterialApp(
         title: 'Blood Pressure App',
         onGenerateTitle: (context) => AppLocalizations.of(context)!.title,
-        // TODO: Use Material 3 everywhere. Some components like the add button on the start page and the settings
-        // switches already use it, so they need to get this theme override removed
         theme: ThemeData(
             colorScheme: ColorScheme.fromSeed(
                 seedColor: settings.accentColor,
test/model/settings_test.dart
@@ -43,7 +43,6 @@ void main() {
       expect(s.csvFieldDelimiter, ',');
       expect(s.csvTextDelimiter, '"');
       expect(s.exportItems, ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes']);
-      expect(s.exportAddableItems, ['isoUTCTime']);
       expect(s.exportCsvHeadline, true);
       expect(s.exportMimeType, MimeType.csv);
       expect(s.defaultExportDir.isEmpty, true);
@@ -87,7 +86,6 @@ void main() {
       s.graphTitlesCount = 7;
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
-      s.exportAddableItems = ['timestampUnixMs'];
       s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportMimeType = MimeType.pdf;
@@ -116,7 +114,6 @@ void main() {
       expect(s.csvFieldDelimiter, '|');
       expect(s.csvTextDelimiter, '\'');
       expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime']);
-      expect(s.exportAddableItems, ['timestampUnixMs']);
       expect(s.exportCsvHeadline, false);
       expect(s.exportMimeType, MimeType.pdf);
       expect(s.defaultExportDir, '/storage/emulated/0/Android/data/com.derdilla.bloodPressureApp/files/file.csv');
@@ -154,7 +151,6 @@ void main() {
       s.graphTitlesCount = 2;
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
-      s.exportAddableItems = ['timestampUnixMs'];
       s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportMimeType = MimeType.pdf;
@@ -163,7 +159,7 @@ void main() {
       s.allowMissingValues = true;
       s.language = const Locale('de');
 
-      expect(i, 29);
+      expect(i, 28);
     });
   });
 
@@ -199,7 +195,6 @@ void main() {
       expect(s.csvFieldDelimiter, ',');
       expect(s.csvTextDelimiter, '"');
       expect(s.exportItems, ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes']);
-      expect(s.exportAddableItems, ['isoUTCTime']);
       expect(s.exportCsvHeadline, true);
       expect(s.exportMimeType, MimeType.csv);
       expect(s.defaultExportDir.isEmpty, true);
@@ -243,7 +238,6 @@ void main() {
       s.graphTitlesCount = 7;
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
-      s.exportAddableItems = ['timestampUnixMs'];
       s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportMimeType = MimeType.pdf;
@@ -272,7 +266,6 @@ void main() {
       expect(s.csvFieldDelimiter, '|');
       expect(s.csvTextDelimiter, '\'');
       expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime']);
-      expect(s.exportAddableItems, ['timestampUnixMs']);
       expect(s.exportCsvHeadline, false);
       expect(s.exportMimeType, MimeType.pdf);
       expect(s.defaultExportDir, '/storage/emulated/0/Android/data/com.derdilla.bloodPressureApp/files/file.csv');
@@ -310,7 +303,6 @@ void main() {
       s.graphTitlesCount = 2;
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
-      s.exportAddableItems = ['timestampUnixMs'];
       s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportMimeType = MimeType.pdf;
@@ -319,7 +311,7 @@ void main() {
       s.allowMissingValues = true;
       s.language = const Locale('de');
 
-      expect(i, 29);
+      expect(i, 28);
     });
   });
 }