Commit c28f01c

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-11-03 17:50:55
protect overriding existing export columns
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent b67166d
Changed files (2)
lib
l10n
screens
lib/l10n/app_en.arb
@@ -439,5 +439,7 @@
   "fileDeleted": "File deleted",
   "@fileDeleted": {},
   "fileAlreadyDeleted": "File already deleted",
-  "@fileAlreadyDeleted": {}
+  "@fileAlreadyDeleted": {},
+  "errExportColumnWithThisNameAlreadyExists": "Export column with this name already exists.",
+  "@errExportColumnWithThisNameAlreadyExists": {}
 }
lib/screens/subsettings/export_column_data.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_field_format_documentation.dart';
@@ -39,146 +40,153 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
-    return Scaffold(
-      body: Center(
-        child: Padding(
-          padding: const EdgeInsets.all(60.0),
-          child: Form(
-            key: _formKey,
-            child: SingleChildScrollView(
-              child: Column(
-                mainAxisSize: MainAxisSize.min,
-                children: [
-                  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(label: Text(localizations.displayTitle)),
-                            onChanged: (String? value) {
-                              if (value != null && value.isNotEmpty) {
-                                setState(() {
-                                  _displayName = value;
-                                });
-                                if (_editedInternalName || (widget.initialInternalName != null)) 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(label: Text(localizations.internalName)),
-                            enabled: (widget.initialInternalName == null),
-                            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(
-                            key: const Key('formatPattern'),
-                            initialValue: _formatPattern,
-                            decoration: InputDecoration(
-                              label: Text(localizations.fieldFormat),
-                              suffixIcon: IconButton(
-                                  onPressed: () {
-                                    Navigator.of(context).push(MaterialPageRoute(
-                                        builder: (context) => InformationScreen(text: localizations.exportFieldFormatDocumentation)));
-                                  },
-                                  icon: const Icon(Icons.info_outline)
-                              ),
+    return ConsistentFutureBuilder(
+      future: ExportConfigurationModel.get(localizations),
+      lastChildWhileWaiting: true,
+      onData: (BuildContext context, ExportConfigurationModel exportConfigurationModel) => Scaffold(
+        body: Center(
+          child: Padding(
+            padding: const EdgeInsets.all(60.0),
+            child: Form(
+              key: _formKey,
+              child: SingleChildScrollView(
+                child: Column(
+                  mainAxisSize: MainAxisSize.min,
+                  children: [
+                    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(label: Text(localizations.displayTitle)),
+                              onChanged: (String? value) {
+                                if (value != null && value.isNotEmpty) {
+                                  setState(() {
+                                    _displayName = value;
+                                  });
+                                  if (_editedInternalName || (widget.initialInternalName != null)) 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;
+                                  });
+                                }
+                              },
                             ),
-                            maxLines: 6,
-                            minLines: 1,
-                            validator: (String? value) {
-                              if (value == null || value.isEmpty) {
-                                return localizations.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();
+                            TextFormField(
+                              key: Key('internalName$_internalNameKeyNr'), // it should update when display name is changed without unfocussing on edit
+                              initialValue: _internalName,
+                              decoration: InputDecoration(label: Text(localizations.internalName)),
+                              enabled: (widget.initialInternalName == null),
+                              validator: (String? value) {
+                                if (value == null || value.isEmpty || RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
+                                  return localizations.errOnlyLatinCharactersAndArabicNumbers;
                                 }
-                              }
-                              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,),
-                        ],
+                                if (exportConfigurationModel.availableFormatsMap.keys.contains(value)) {
+                                  return localizations.errExportColumnWithThisNameAlreadyExists;
+                                }
+                                return null;
+                              },
+                              onChanged: (String? value) {
+                                if (value != null && value.isNotEmpty && !RegExp(r'[^A-Za-z0-9]').hasMatch(value)) {
+                                  setState(() {
+                                    _internalName = value;
+                                    _editedInternalName = true;
+                                  });
+                                }
+                              },
+                            ),
+                            TextFormField(
+                              key: const Key('formatPattern'),
+                              initialValue: _formatPattern,
+                              decoration: InputDecoration(
+                                label: Text(localizations.fieldFormat),
+                                suffixIcon: IconButton(
+                                    onPressed: () {
+                                      Navigator.of(context).push(MaterialPageRoute(
+                                          builder: (context) => InformationScreen(text: localizations.exportFieldFormatDocumentation)));
+                                    },
+                                    icon: const Icon(Icons.info_outline)
+                                ),
+                              ),
+                              maxLines: 6,
+                              minLines: 1,
+                              validator: (String? value) {
+                                if (value == null || value.isEmpty) {
+                                  return localizations.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,),
+                          ],
+                        ),
                       ),
                     ),
-                  ),
-                  Row(
-                    children: [
-                      TextButton(
-                          key: const Key('btnCancel'),
-                          onPressed: () {
-                            Navigator.of(context).pop();
-                          },
+                    Row(
+                      children: [
+                        TextButton(
+                            key: const Key('btnCancel'),
+                            onPressed: () {
+                              Navigator.of(context).pop();
+                            },
 
-                          child: Text(localizations.btnCancel)
-                      ),
-                      const Spacer(),
-                      FilledButton.icon(
-                        key: const Key('btnSave'),
-                        icon: const Icon(Icons.save),
-                        label: Text(localizations.btnSave),
-                        onPressed: (widget.editable) ? (() async {
-                          if (_formKey.currentState?.validate() ?? false) {
-                            final navigator = Navigator.of(context);
-                            (await ExportConfigurationModel.get(localizations)).addOrUpdate(ExportColumn(
-                                internalName: _internalName!,
-                                columnTitle: _displayName!,
-                                formatPattern: _formatPattern!
-                            ));
-                            navigator.pop();
-                          }
-                        }) : null,
-                      )
-                    ],
-                  )
-                ],
+                            child: Text(localizations.btnCancel)
+                        ),
+                        const Spacer(),
+                        FilledButton.icon(
+                          key: const Key('btnSave'),
+                          icon: const Icon(Icons.save),
+                          label: Text(localizations.btnSave),
+                          onPressed: (widget.editable) ? (() async {
+                            if (_formKey.currentState?.validate() ?? false) {
+                              final navigator = Navigator.of(context);
+                              exportConfigurationModel.addOrUpdate(ExportColumn(
+                                  internalName: _internalName!,
+                                  columnTitle: _displayName!,
+                                  formatPattern: _formatPattern!
+                              ));
+                              navigator.pop();
+                            }
+                          }) : null,
+                        )
+                      ],
+                    )
+                  ],
+                ),
               ),
             ),
           ),
-        ),
-      )
+        )
+      ),
     );
   }
 }
\ No newline at end of file