Commit c28f01c
Changed files (2)
lib
l10n
screens
subsettings
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