Skip to content

Commit

Permalink
feat: delete schedules
Browse files Browse the repository at this point in the history
  • Loading branch information
inpt333 authored and borgoat committed Nov 19, 2024
1 parent 9346f79 commit dfd8f69
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 19 deletions.
14 changes: 14 additions & 0 deletions lib/epics/schedules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:rxdart/rxdart.dart';
createSchedulesEpics(SchedulesRepository schedules) => combineEpics<AppState>([
_createRetrieveGroupSchedulesEpic(schedules),
_createCreateOneScheduleEpic(schedules),
_createDeleteOneScheduleEpic(schedules),
]);

/// Fetch all schedules for a group
Expand All @@ -24,6 +25,7 @@ Epic<AppState> _createRetrieveGroupSchedulesEpic(
);
}

/// When the user requests to create a new schedule
Epic<AppState> _createCreateOneScheduleEpic(SchedulesRepository schedules) {
return (Stream<dynamic> actions, EpicStore<AppState> store) => actions
.whereType<RequestCreateOne<Schedule>>()
Expand All @@ -35,3 +37,15 @@ Epic<AppState> _createCreateOneScheduleEpic(SchedulesRepository schedules) {
FailCreateOne<Schedule>(entity: action.entity, error: error)),
);
}

/// When the user requests to delete one schedule
Epic<AppState> _createDeleteOneScheduleEpic(SchedulesRepository schedules) {
return (Stream<dynamic> actions, EpicStore<AppState> store) =>
actions.whereType<RequestDeleteOne<Schedule>>().asyncMap(
(action) => schedules
.deleteSchedule(action.id)
.then<dynamic>((_) => SuccessDeleteOne<Schedule>(action.id))
.catchError((error) =>
FailDeleteOne<Schedule>(id: action.id, error: error)),
);
}
2 changes: 2 additions & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"delete": "Löschen",
"deleteProfile": "Profil löschen",
"deleteProfileConfirmation": "Bist du sicher, dass du dein Profil löschen möchtest?",
"deleteSchedule": "Event löschen",
"deleteScheduleConfirmation": "Bist du sicher, dass du dieses Event löschen möchtest?",
"details": "Einzelheiten",
"enterGroupDescription": "Du kannst eine optionale Gruppenbeschreibung eingeben",
"enterGroupName": "Gib einen Gruppennamen ein",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"delete": "Delete",
"deleteProfile": "Delete profile",
"deleteProfileConfirmation": "Are you sure you want to delete your profile?",
"deleteSchedule": "Delete event",
"deleteScheduleConfirmation": "Are you sure you want to delete this event?",
"details": "Details",
"enterGroupDescription": "You may enter an optional group description",
"enterGroupName": "Enter a group name",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"delete": "Eliminar",
"deleteProfile": "Eliminar perfil",
"deleteProfileConfirmation": "¿Estás seguro de que quieres eliminar tu perfil?",
"deleteSchedule": "Eliminar evento",
"deleteScheduleConfirmation": "¿Estás seguro de que quieres eliminar este evento?",
"details": "Detalles",
"enterGroupDescription": "Puedes poner una descripción del grupo si quieres",
"enterGroupName": "Ponle un nombre al grupo",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"delete": "Supprime",
"deleteProfile": "Supprime le profil",
"deleteProfileConfirmation": "Es-tu sûr de vouloir supprimer ton profil?",
"deleteSchedule": "Supprime l'événement",
"deleteScheduleConfirmation": "Es-tu sûr de vouloir supprimer cet événement?",
"details": "Détails",
"enterGroupDescription": "Tu peux entrer une description de groupe si tu veux",
"enterGroupName": "Entre un nom de groupe",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/app_it.arb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"delete": "Elimina",
"deleteProfile": "Elimina il profilo",
"deleteProfileConfirmation": "Sei sicuro di voler eliminare il tuo profilo?",
"deleteSchedule": "Elimina evento",
"deleteScheduleConfirmation": "Sei sicuro di voler eliminare questo evento?",
"details": "Dettagli",
"enterGroupDescription": "Puoi inserire una descrizione del gruppo se vuoi",
"enterGroupName": "Inserisci il nome del gruppo",
Expand Down
5 changes: 5 additions & 0 deletions lib/presentation/containers/group_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class GroupEventsContainer extends StatelessWidget {
group: vm.group,
schedules: vm.schedules,
onCreate: vm.onScheduleCreate,
onDelete: vm.onScheduleDelete,
rrulel10n: vm.rrulel10n,
),
);
Expand All @@ -41,6 +42,7 @@ sealed class _ViewModel with _$ViewModel {
Group? group,
Iterable<Schedule>? schedules,
ValueSetter<Schedule>? onScheduleCreate,
ValueSetter<Schedule>? onScheduleDelete,
Future<RruleL10n>? rrulel10n,
}) = __ViewModel;

Expand All @@ -59,6 +61,9 @@ sealed class _ViewModel with _$ViewModel {
onScheduleCreate: (schedule) => store.dispatch(
RequestCreateOne<Schedule>(schedule),
),
onScheduleDelete: (schedule) => store.dispatch(
RequestDeleteOne<Schedule>(schedule.id.toString()),
),
rrulel10n: rruleL10nSelector(store.state),
);
}
Expand Down
25 changes: 24 additions & 1 deletion lib/presentation/containers/group_events.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ mixin _$ViewModel {
Iterable<Schedule>? get schedules => throw _privateConstructorUsedError;
ValueSetter<Schedule>? get onScheduleCreate =>
throw _privateConstructorUsedError;
ValueSetter<Schedule>? get onScheduleDelete =>
throw _privateConstructorUsedError;
Future<RruleL10n>? get rrulel10n => throw _privateConstructorUsedError;

/// Create a copy of _ViewModel
Expand All @@ -41,6 +43,7 @@ abstract class _$ViewModelCopyWith<$Res> {
Group? group,
Iterable<Schedule>? schedules,
ValueSetter<Schedule>? onScheduleCreate,
ValueSetter<Schedule>? onScheduleDelete,
Future<RruleL10n>? rrulel10n});

$GroupCopyWith<$Res>? get group;
Expand All @@ -65,6 +68,7 @@ class __$ViewModelCopyWithImpl<$Res, $Val extends _ViewModel>
Object? group = freezed,
Object? schedules = freezed,
Object? onScheduleCreate = freezed,
Object? onScheduleDelete = freezed,
Object? rrulel10n = freezed,
}) {
return _then(_value.copyWith(
Expand All @@ -84,6 +88,10 @@ class __$ViewModelCopyWithImpl<$Res, $Val extends _ViewModel>
? _value.onScheduleCreate
: onScheduleCreate // ignore: cast_nullable_to_non_nullable
as ValueSetter<Schedule>?,
onScheduleDelete: freezed == onScheduleDelete
? _value.onScheduleDelete
: onScheduleDelete // ignore: cast_nullable_to_non_nullable
as ValueSetter<Schedule>?,
rrulel10n: freezed == rrulel10n
? _value.rrulel10n
: rrulel10n // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -119,6 +127,7 @@ abstract class _$$_ViewModelImplCopyWith<$Res>
Group? group,
Iterable<Schedule>? schedules,
ValueSetter<Schedule>? onScheduleCreate,
ValueSetter<Schedule>? onScheduleDelete,
Future<RruleL10n>? rrulel10n});

@override
Expand All @@ -142,6 +151,7 @@ class __$$_ViewModelImplCopyWithImpl<$Res>
Object? group = freezed,
Object? schedules = freezed,
Object? onScheduleCreate = freezed,
Object? onScheduleDelete = freezed,
Object? rrulel10n = freezed,
}) {
return _then(_$_ViewModelImpl(
Expand All @@ -161,6 +171,10 @@ class __$$_ViewModelImplCopyWithImpl<$Res>
? _value.onScheduleCreate
: onScheduleCreate // ignore: cast_nullable_to_non_nullable
as ValueSetter<Schedule>?,
onScheduleDelete: freezed == onScheduleDelete
? _value.onScheduleDelete
: onScheduleDelete // ignore: cast_nullable_to_non_nullable
as ValueSetter<Schedule>?,
rrulel10n: freezed == rrulel10n
? _value.rrulel10n
: rrulel10n // ignore: cast_nullable_to_non_nullable
Expand All @@ -177,6 +191,7 @@ class _$_ViewModelImpl implements __ViewModel {
this.group,
this.schedules,
this.onScheduleCreate,
this.onScheduleDelete,
this.rrulel10n});

@override
Expand All @@ -188,11 +203,13 @@ class _$_ViewModelImpl implements __ViewModel {
@override
final ValueSetter<Schedule>? onScheduleCreate;
@override
final ValueSetter<Schedule>? onScheduleDelete;
@override
final Future<RruleL10n>? rrulel10n;

@override
String toString() {
return '_ViewModel(loading: $loading, group: $group, schedules: $schedules, onScheduleCreate: $onScheduleCreate, rrulel10n: $rrulel10n)';
return '_ViewModel(loading: $loading, group: $group, schedules: $schedules, onScheduleCreate: $onScheduleCreate, onScheduleDelete: $onScheduleDelete, rrulel10n: $rrulel10n)';
}

@override
Expand All @@ -205,6 +222,8 @@ class _$_ViewModelImpl implements __ViewModel {
const DeepCollectionEquality().equals(other.schedules, schedules) &&
(identical(other.onScheduleCreate, onScheduleCreate) ||
other.onScheduleCreate == onScheduleCreate) &&
(identical(other.onScheduleDelete, onScheduleDelete) ||
other.onScheduleDelete == onScheduleDelete) &&
(identical(other.rrulel10n, rrulel10n) ||
other.rrulel10n == rrulel10n));
}
Expand All @@ -216,6 +235,7 @@ class _$_ViewModelImpl implements __ViewModel {
group,
const DeepCollectionEquality().hash(schedules),
onScheduleCreate,
onScheduleDelete,
rrulel10n);

/// Create a copy of _ViewModel
Expand All @@ -233,6 +253,7 @@ abstract class __ViewModel implements _ViewModel {
final Group? group,
final Iterable<Schedule>? schedules,
final ValueSetter<Schedule>? onScheduleCreate,
final ValueSetter<Schedule>? onScheduleDelete,
final Future<RruleL10n>? rrulel10n}) = _$_ViewModelImpl;

@override
Expand All @@ -244,6 +265,8 @@ abstract class __ViewModel implements _ViewModel {
@override
ValueSetter<Schedule>? get onScheduleCreate;
@override
ValueSetter<Schedule>? get onScheduleDelete;
@override
Future<RruleL10n>? get rrulel10n;

/// Create a copy of _ViewModel
Expand Down
68 changes: 52 additions & 16 deletions lib/presentation/widgets/group_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,18 @@ class GroupEvents extends StatelessWidget {
final Group? group; // TODO is this needed?
final Iterable<Schedule>? schedules;
final ValueSetter<Schedule>? onCreate;
final ValueSetter<Schedule>? onDelete;
final Future<RruleL10n>? rrulel10n;

const GroupEvents({
super.key,
this.group,
this.schedules,
this.onCreate,
this.onDelete,
this.rrulel10n,
});

_createNewEvent(BuildContext context) async {
final result = await GroupScheduleCreateRoute(groupId: group!.id.toString())
.push(context);

if (result is! Schedule) {
// TODO error handling
return;
}

final newSchedule = result.copyWith(groupId: group!.id);
onCreate?.call(newSchedule);
}

@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
Expand All @@ -52,9 +41,10 @@ class GroupEvents extends StatelessWidget {
}
return Text(l10n.loading);
}),
onTap: () {
// TODO Go to schedule edit form
},
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _deleteEvent(context, schedule),
),
);
},
)
Expand All @@ -73,4 +63,50 @@ class GroupEvents extends StatelessWidget {
),
);
}

_createNewEvent(BuildContext context) async {
final result = await GroupScheduleCreateRoute(groupId: group!.id.toString())
.push(context);

if (result is! Schedule) {
// TODO error handling
return;
}

final newSchedule = result.copyWith(groupId: group!.id);
onCreate?.call(newSchedule);
}

_deleteEvent(BuildContext context, Schedule schedule) async {
final doDelete = await showAdaptiveDialog<bool>(
context: context,
builder: (context) {
final l10n = AppLocalizations.of(context)!;
final theme = Theme.of(context);
final nav = Navigator.of(context);

return AlertDialog.adaptive(
icon: const Icon(Icons.logout),
title: Text(l10n.deleteSchedule),
content: Text(l10n.deleteScheduleConfirmation),
actions: [
TextButton(
onPressed: () => nav.pop(false),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () => nav.pop(true),
style: TextButton.styleFrom(
foregroundColor: theme.colorScheme.error,
),
child: Text(l10n.delete),
),
],
);
});

if (doDelete == null || !doDelete) return;

onDelete?.call(schedule);
}
}
2 changes: 1 addition & 1 deletion lib/repositories/members.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class MembersRepository extends SupabaseRepository with Postgrest {
.withConverter(Member.fromJson);
}

Future<void> removeMember(int memberId) async {
Future<void> deleteMember(int memberId) async {
return table().delete().eq('id', memberId);
}

Expand Down
4 changes: 4 additions & 0 deletions lib/repositories/schedules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ class SchedulesRepository extends SupabaseRepository with Postgrest {
.eq('group_id', groupId)
.withConverter((data) => data.map(Schedule.fromJson));
}

Future<void> deleteSchedule(String scheduleId) async {
return table().delete().eq('id', scheduleId);
}
}
2 changes: 1 addition & 1 deletion test/repositories_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void main() {
final updatedGuest = await membersRepository.updateMember(
memberId: guest.id, displayNameOverride: 'A guest with a name');

await membersRepository.removeMember(updatedGuest.id);
await membersRepository.deleteMember(updatedGuest.id);
}),
),
);
Expand Down

0 comments on commit dfd8f69

Please sign in to comment.