Skip to content

Commit

Permalink
feat: Differentiate Save and Generate Bouts from Lineups (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Jan 16, 2024
1 parent 91712f7 commit a26798f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 59 deletions.
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"optionSelect": "Auswählen",
"edit": "Bearbeite",
"save": "Speichern",
"saveAndGenerate": "Speichern & Generieren",
"add": "Hinzufügen",
"remove": "Entfernen",
"cancel": "Abbrechen",
Expand All @@ -47,6 +48,7 @@
"noWebSocketConnection": "Die Verbindung zum Server konnte nicht aufgebaut werden oder wurde unterbrochen.",
"notFoundException": "Element wurde nicht gefunden :/",
"invalidParameterException": "Die Änderung war nicht erfolgreich, bitte überprüfe deine Eingabeparameter.",
"warningBoutGenerate": "Diese Aktion überschreibt alle existierenden Kämpfe dieser Begegnung. Um einzelne Kämpfe zu bearbeiten, nutze die Seite zur Kampf-Bearbeitung. Bist du sicher, dass du fortfahren möchtest?",
"retry": "Erneut versuchen",

"date": "Datum",
Expand Down
2 changes: 2 additions & 0 deletions wrestling_scoreboard_client/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"optionSelect": "select",
"edit": "Edit",
"save": "Save",
"saveAndGenerate": "Save & Generate",
"add": "Add",
"remove": "Remove",
"cancel": "Cancel",
Expand All @@ -50,6 +51,7 @@
"noWebSocketConnection": "The connection to the server could not be established or was interrupted.",
"notFoundException": "Element was not found :/",
"invalidParameterException": "The change was not successful, please check your input parameters.",
"warningBoutGenerate": "This action overrides all existing bouts of this match. To edit single bouts, use the bout editing page. Are you sure, you want to continue?",
"retry": "Retry",

"date": "Date",
Expand Down
137 changes: 97 additions & 40 deletions wrestling_scoreboard_client/lib/ui/components/edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,49 @@ class EditWidget extends StatelessWidget {
final Future<void> Function() onSubmit;
final List<Widget> items;

const EditWidget({super.key, required this.typeLocalization, required this.onSubmit, required this.items, this.id});
const EditWidget({
super.key,
required this.typeLocalization,
required this.onSubmit,
required this.items,
this.id,
});

List<Widget> _buildActions(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return [
EditAction(
icon: const Icon(Icons.save),
label: Text(localizations.save),
onSubmit: onSubmit,
),
];
}

@override
Widget build(BuildContext context) {
return CustomizableEditWidget(
typeLocalization: typeLocalization,
items: items,
id: id,
buildActions: _buildActions,
);
}
}

class CustomizableEditWidget extends StatelessWidget {
final String typeLocalization;
final int? id;
final List<Widget> Function(BuildContext context) buildActions;
final List<Widget> items;

const CustomizableEditWidget({
super.key,
required this.typeLocalization,
required this.items,
this.id,
required this.buildActions,
});

@override
Widget build(BuildContext context) {
Expand All @@ -32,49 +74,64 @@ class EditWidget extends StatelessWidget {
),
],
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
child: ElevatedButton.icon(
icon: const Icon(Icons.save),
onPressed: () async {
try {
await onSubmit();
} on RestException catch (e) {
developer.log(e.message);
if (context.mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
children: [
Text(localizations.invalidParameterException),
Text(
e.message,
style: TextStyle(color: Theme.of(context).disabledColor, fontSize: 10),
),
],
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(localizations.ok),
),
],
),
);
}
}
},
label: Text(localizations.save),
))
],
actions: buildActions(context),
),
body: ResponsiveColumn(
children: items,
),
);
}
}

class EditAction extends StatelessWidget {
final Widget icon;
final Widget label;
final Future<void> Function() onSubmit;

const EditAction({super.key, required this.icon, required this.label, required this.onSubmit});

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
child: ElevatedButton.icon(
icon: icon,
onPressed: () => _handleSubmit(context),
label: label,
),
);
}

void _handleSubmit(BuildContext context) async {
final localizations = AppLocalizations.of(context)!;
try {
await onSubmit();
} on RestException catch (e) {
developer.log(e.message);
if (context.mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
children: [
Text(localizations.invalidParameterException),
Text(
e.message,
style: TextStyle(color: Theme.of(context).disabledColor, fontSize: 10),
),
],
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(localizations.ok),
),
],
),
);
}
}
}
}
63 changes: 45 additions & 18 deletions wrestling_scoreboard_client/lib/ui/edit/lineup_edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:wrestling_scoreboard_client/data/wrestling_style.dart';
import 'package:wrestling_scoreboard_client/ui/components/dropdown.dart';
import 'package:wrestling_scoreboard_client/ui/components/edit.dart';
import 'package:wrestling_scoreboard_client/ui/components/font.dart';
import 'package:wrestling_scoreboard_client/ui/components/ok_dialog.dart';
import 'package:wrestling_scoreboard_client/util/network/data_provider.dart';
import 'package:wrestling_scoreboard_common/common.dart';

Expand All @@ -15,14 +16,14 @@ class LineupEdit extends StatefulWidget {
final List<WeightClass> weightClasses;
final List<Participation> participations;

final Function()? onSubmit;
final Function()? onSubmitGenerate;

const LineupEdit({
super.key,
required this.lineup,
required this.weightClasses,
required this.participations,
this.onSubmit,
this.onSubmitGenerate,
});

@override
Expand All @@ -40,13 +41,25 @@ class LineupEditState extends State<LineupEdit> {
final HashSet<Participation> _deleteParticipations = HashSet();
final HashSet<Participation> _createOrUpdateParticipations = HashSet();

@override
void initState() {
super.initState();
_leader = widget.lineup.leader;
_coach = widget.lineup.coach;
_participations = Map.fromEntries(widget.weightClasses.map((e) {
final weightParticipations = widget.participations.where((participation) => participation.weightClass == e);
final participation = weightParticipations.isEmpty ? null : weightParticipations.single;
return MapEntry(e, participation);
}));
}

Future<List<Membership>> filterMemberships(String? filter) async {
memberships ??= await dataProvider.readMany<Membership, Club>(filterObject: widget.lineup.team.club);
return (filter == null ? memberships! : memberships!.where((element) => element.person.fullName.contains(filter)))
.toList();
}

Future<void> handleSubmit(NavigatorState navigator) async {
Future<void> handleSubmit(NavigatorState navigator, {void Function()? onSubmitGenerate}) async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
await dataProvider
Expand All @@ -55,34 +68,48 @@ class LineupEditState extends State<LineupEdit> {
_deleteParticipations, (Participation element) => dataProvider.deleteSingle<Participation>(element));
await Future.forEach(
_createOrUpdateParticipations, (Participation element) => dataProvider.createOrUpdateSingle(element));
if (widget.onSubmit != null) widget.onSubmit!();
if (onSubmitGenerate != null) onSubmitGenerate();
navigator.pop();
}
}

@override
void initState() {
super.initState();
_leader = widget.lineup.leader;
_coach = widget.lineup.coach;
_participations = Map.fromEntries(widget.weightClasses.map((e) {
final weightParticipations = widget.participations.where((participation) => participation.weightClass == e);
final participation = weightParticipations.isEmpty ? null : weightParticipations.single;
return MapEntry(e, participation);
}));
List<Widget> _buildActions(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final navigator = Navigator.of(context);
return [
EditAction(
icon: const Icon(Icons.save),
label: Text(localizations.save),
onSubmit: () => handleSubmit(navigator),
),
EditAction(
icon: const Icon(Icons.autorenew),
label: Text(localizations.saveAndGenerate),
onSubmit: () async {
final hasConfirmed = await showDialog(
context: context,
builder: (context) => OkDialog(
getResult: () => true,
child: Text(localizations.warningBoutGenerate),
),
);
if (hasConfirmed == true) {
await handleSubmit(navigator, onSubmitGenerate: widget.onSubmitGenerate);
}
},
),
];
}

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final navigator = Navigator.of(context);

return Form(
key: _formKey,
child: EditWidget(
child: CustomizableEditWidget(
typeLocalization: localizations.lineup,
id: widget.lineup.id,
onSubmit: () => handleSubmit(navigator),
buildActions: _buildActions,
items: [
ListTile(title: HeadingText(widget.lineup.team.name)),
ListTile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class TeamMatchOverview extends StatelessWidget {
weightClasses: weightClasses,
participations: participations,
lineup: lineup,
onSubmit: () {
onSubmitGenerate: () {
dataProvider.generateBouts<TeamMatch>(match, false);
},
);
Expand Down

0 comments on commit a26798f

Please sign in to comment.