Bearbeiten und Löschen von Gruppen #148

Merged
sneeex merged 20 commits from feature/118-bearbeiten-und-löschen-von-gruppen into development 2026-03-09 20:30:38 +00:00
5 changed files with 26 additions and 20 deletions
Showing only changes of commit 23d00c64ab - Show all commits

View File

@@ -3,6 +3,7 @@ import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/db/tables/group_table.dart'; import 'package:tallee/data/db/tables/group_table.dart';
import 'package:tallee/data/db/tables/player_group_table.dart'; import 'package:tallee/data/db/tables/player_group_table.dart';
import 'package:tallee/data/dto/group.dart'; import 'package:tallee/data/dto/group.dart';
import 'package:tallee/data/dto/match.dart';
import 'package:tallee/data/dto/player.dart'; import 'package:tallee/data/dto/player.dart';
part 'group_dao.g.dart'; part 'group_dao.g.dart';
@@ -171,6 +172,12 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
}); });
} }
/// Retrieves all matches associated with the given [groupId].
Future<List<Match>> getGroupMatches({required String groupId}) async {
sneeex marked this conversation as resolved Outdated

Du sollst direkt die Datenbankanfrage so gestalten, dass du nur die Matches bekommst, welche die Gruppe enthalten. Das war mein Punkt

Du sollst direkt die Datenbankanfrage so gestalten, dass du nur die Matches bekommst, welche die Gruppe enthalten. Das war mein Punkt

so wenig effort wie möglich

so wenig effort wie möglich

ja schlimm

ja schlimm

match name soll nicht nullable sein oder?

match name soll nicht nullable sein oder?
grafik.png
<img width="602" alt="grafik.png" src="attachments/052438c1-2d54-4df8-8450-db3bedd8f495">
176 KiB

Eigentlich nicht, das ist schon wieder Fusch am Bau

Eigentlich nicht, das ist schon wieder Fusch am Bau
final matches = await db.matchDao.getAllMatches();
return matches.where((match) => match.group?.id == groupId).toList();
}
/// Deletes the group with the given [id] from the database. /// Deletes the group with the given [id] from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`. /// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteGroup({required String groupId}) async { Future<bool> deleteGroup({required String groupId}) async {

View File

@@ -338,10 +338,10 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
return rowsAffected > 0; return rowsAffected > 0;
} }
/// Entfernt die Gruppen-Verknüpfung des Matches mit der gegebenen [matchId]. /// Removes the group association of the match with the given [matchId].
sneeex marked this conversation as resolved Outdated

Kommentar auf Deutsch

Kommentar auf Deutsch
/// Setzt die groupId auf null. /// Sets the groupId to null.
/// Gibt `true` zurück, wenn mehr als 0 Zeilen betroffen waren, ansonsten `false`. /// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteMatchGroup({required String matchId}) async { Future<bool> removeMatchGroup({required String matchId}) async {
flixcoo marked this conversation as resolved Outdated

Methode lieber sowas nennen removeGroupFromMatch da hier ja keine keine Gruppe gelöscht wird

Methode lieber sowas nennen `removeGroupFromMatch` da hier ja keine keine Gruppe gelöscht wird
final query = update(matchTable)..where((g) => g.id.equals(matchId)); final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write( final rowsAffected = await query.write(
const MatchTableCompanion(groupId: Value(null)), const MatchTableCompanion(groupId: Value(null)),

View File

@@ -190,11 +190,16 @@ class _CreateGroupViewState extends State<CreateGroupView> {
return (success, updatedGroup); return (success, updatedGroup);
} }
/// Removes the group association from matches that no longer belong to the edited group.
sneeex marked this conversation as resolved Outdated

Kurzen doc comment nochmal zu dieser Methode vllt

Kurzen doc comment nochmal zu dieser Methode vllt
///
sneeex marked this conversation as resolved Outdated

Lieber Methode getMatchesToGroup() in groupDao.dart, kann ggf. später auch noch einmal verwendet werden

Lieber Methode `getMatchesToGroup()` in `groupDao.dart`, kann ggf. später auch noch einmal verwendet werden

hast das auch so gemacht

hast das auch so gemacht

habs von dir kopiert

habs von dir kopiert

wo hab ich das gemacht? File und Zeile

wo hab ich das gemacht? File und Zeile

hast das auch so gemacht, group detail view
grafik.png

hast das auch so gemacht, group detail view <img width="491" alt="grafik.png" src="attachments/ae2ff61f-bc2e-45fc-baa5-62254ff3a2e1">
101 KiB

ja aber da diese vorgehensweise jetzt mehr als einmal im code ist machts erst recht sinn dafür ne methode zu schreiben und entsprechende vorkommen zu ersetzen

ja aber da diese vorgehensweise jetzt mehr als einmal im code ist machts erst recht sinn dafür ne methode zu schreiben und entsprechende vorkommen zu ersetzen
/// After updating the group's members, matches that were previously linked to
/// this group but don't have any of the newly selected players are considered
/// obsolete. For each such match, the group association is removed by setting
/// its [groupId] to null.
Future<void> deleteObsoleteMatchGroupRelations() async { Future<void> deleteObsoleteMatchGroupRelations() async {
final matches = await db.matchDao.getAllMatches(); final groupMatches = await db.groupDao.getGroupMatches(
final groupMatches = matches groupId: widget.groupToEdit!.id,
.where((match) => match.group?.id == widget.groupToEdit!.id) );
.toList();
final selectedPlayerIds = selectedPlayers.map((p) => p.id).toSet(); final selectedPlayerIds = selectedPlayers.map((p) => p.id).toSet();
final relationshipsToDelete = groupMatches.where((match) { final relationshipsToDelete = groupMatches.where((match) {
@@ -204,7 +209,7 @@ class _CreateGroupViewState extends State<CreateGroupView> {
}).toList(); }).toList();
for (var match in relationshipsToDelete) { for (var match in relationshipsToDelete) {
await db.matchDao.deleteMatchGroup(matchId: match.id); await db.matchDao.removeMatchGroup(matchId: match.id);
} }
} }

View File

@@ -194,7 +194,6 @@ class _GroupDetailViewState extends State<GroupDetailView> {
return CreateGroupView( return CreateGroupView(
groupToEdit: _group, groupToEdit: _group,
onMembersChanged: () { onMembersChanged: () {
isLoading = true;
_loadStatistics(); _loadStatistics();
sneeex marked this conversation as resolved
Review

Warum wird isLoading nicht in _loadStatistics auf true gesetzt?

Warum wird `isLoading` nicht in `_loadStatistics` auf true gesetzt?
Review

weil du's so gemacht hast großer

weil du's so gemacht hast großer
Review

Setzt es mal in der Methode anfangs auf true, so ists z.B. auch im GroupView

Setzt es mal in der Methode anfangs auf true, so ists z.B. auch im `GroupView`
}, },
); );
@@ -248,10 +247,8 @@ class _GroupDetailViewState extends State<GroupDetailView> {
/// Loads statistics for this group /// Loads statistics for this group
Future<void> _loadStatistics() async { Future<void> _loadStatistics() async {
final matches = await db.matchDao.getAllMatches(); isLoading = true;
final groupMatches = matches final groupMatches = await db.groupDao.getGroupMatches(groupId: _group.id);
.where((match) => match.group?.id == _group.id)
.toList();
setState(() { setState(() {
totalMatches = groupMatches.length; totalMatches = groupMatches.length;

View File

@@ -308,13 +308,12 @@ void main() {
expect(fetchedMatch.winner!.id, testPlayer5.id); expect(fetchedMatch.winner!.id, testPlayer5.id);
}); });
// Tests for removeMatchGroup
test( test(
sneeex marked this conversation as resolved
Review

Unnötiger Kommentar

Unnötiger Kommentar
'removeMatchGroup removes group from match with existing group', 'removeMatchGroup removes group from match with existing group',
() async { () async {
await database.matchDao.addMatch(match: testMatch1); await database.matchDao.addMatch(match: testMatch1);
final removed = await database.matchDao.deleteMatchGroup( final removed = await database.matchDao.removeMatchGroup(
matchId: testMatch1.id, matchId: testMatch1.id,
); );
expect(removed, isTrue); expect(removed, isTrue);
@@ -323,7 +322,6 @@ void main() {
matchId: testMatch1.id, matchId: testMatch1.id,
); );
expect(updatedMatch.group, null); expect(updatedMatch.group, null);
// Andere Felder bleiben unverändert
expect(updatedMatch.game.id, testMatch1.game.id); expect(updatedMatch.game.id, testMatch1.game.id);
expect(updatedMatch.name, testMatch1.name); expect(updatedMatch.name, testMatch1.name);
sneeex marked this conversation as resolved
Review

Unnötiger Kommentar & auf deutsch

Unnötiger Kommentar & auf deutsch
expect(updatedMatch.notes, testMatch1.notes); expect(updatedMatch.notes, testMatch1.notes);
@@ -335,10 +333,9 @@ void main() {
() async { () async {
await database.matchDao.addMatch(match: testMatchOnlyPlayers); await database.matchDao.addMatch(match: testMatchOnlyPlayers);
final removed = await database.matchDao.deleteMatchGroup( final removed = await database.matchDao.removeMatchGroup(
matchId: testMatchOnlyPlayers.id, matchId: testMatchOnlyPlayers.id,
); );
// Update sollte trotzdem eine Zeile betreffen
expect(removed, isTrue); expect(removed, isTrue);
final updatedMatch = await database.matchDao.getMatchById( final updatedMatch = await database.matchDao.getMatchById(
sneeex marked this conversation as resolved
Review

Unnötiger Kommentar & auf deutsch

Unnötiger Kommentar & auf deutsch
@@ -349,7 +346,7 @@ void main() {
); );
test('removeMatchGroup on non-existing match returns false', () async { test('removeMatchGroup on non-existing match returns false', () async {
final removed = await database.matchDao.deleteMatchGroup( final removed = await database.matchDao.removeMatchGroup(
matchId: 'non-existing-id', matchId: 'non-existing-id',
); );
expect(removed, isFalse); expect(removed, isFalse);