refactor(job): Implement polymorphic behavior on creation for jobs #134
|
@ -24,14 +24,13 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
final ServicesCubit servicesCubit;
|
||||
|
||||
void addJob(final ClientJob job) {
|
||||
final List<ClientJob> newJobsList = [];
|
||||
if (state is JobsStateWithJobs) {
|
||||
final JobsStateWithJobs jobsState = state as JobsStateWithJobs;
|
||||
newJobsList.addAll(jobsState.clientJobList);
|
||||
final jobs = currentJobList;
|
||||
if (job.canAddTo(jobs)) {
|
||||
_updateJobsState([
|
||||
...jobs,
|
||||
...[job],
|
||||
]);
|
||||
}
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
}
|
||||
|
||||
void removeJob(final String id) {
|
||||
|
@ -39,37 +38,18 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
emit(newState);
|
||||
}
|
||||
|
||||
void createOrRemoveServiceToggleJob(final ToggleJob job) {
|
||||
final List<ClientJob> newJobsList = <ClientJob>[];
|
||||
List<ClientJob> get currentJobList {
|
||||
final List<ClientJob> jobs = <ClientJob>[];
|
||||
if (state is JobsStateWithJobs) {
|
||||
newJobsList.addAll((state as JobsStateWithJobs).clientJobList);
|
||||
}
|
||||
final bool needToRemoveJob = newJobsList
|
||||
.any((final el) => el is ServiceToggleJob && el.id == job.id);
|
||||
if (needToRemoveJob) {
|
||||
final ClientJob removingJob = newJobsList.firstWhere(
|
||||
(final el) => el is ServiceToggleJob && el.id == job.id,
|
||||
);
|
||||
removeJob(removingJob.id);
|
||||
} else {
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
jobs.addAll((state as JobsStateWithJobs).clientJobList);
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
void createShhJobIfNotExist(final CreateSSHKeyJob job) {
|
||||
final List<ClientJob> newJobsList = <ClientJob>[];
|
||||
if (state is JobsStateWithJobs) {
|
||||
newJobsList.addAll((state as JobsStateWithJobs).clientJobList);
|
||||
}
|
||||
final bool isExistInJobList =
|
||||
newJobsList.any((final el) => el is CreateSSHKeyJob);
|
||||
if (!isExistInJobList) {
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
}
|
||||
void _updateJobsState(final List<ClientJob> newJobs) {
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobs));
|
||||
}
|
||||
|
||||
Future<void> rebootServer() async {
|
||||
|
|
|
@ -17,6 +17,7 @@ abstract class ClientJob extends Equatable {
|
|||
final String title;
|
||||
final String id;
|
||||
|
||||
bool canAddTo(final List<ClientJob> jobs) => true;
|
||||
void execute(final JobsCubit cubit);
|
||||
|
||||
@override
|
||||
|
@ -25,10 +26,14 @@ abstract class ClientJob extends Equatable {
|
|||
|
||||
class RebuildServerJob extends ClientJob {
|
||||
RebuildServerJob({
|
||||
required final super.title,
|
||||
final super.id,
|
||||
required super.title,
|
||||
super.id,
|
||||
});
|
||||
|
||||
@override
|
||||
bool canAddTo(final List<ClientJob> jobs) =>
|
||||
!jobs.any((final job) => job is RebuildServerJob);
|
||||
inex marked this conversation as resolved
Outdated
|
||||
|
||||
@override
|
||||
void execute(final JobsCubit cubit) async {
|
||||
await cubit.upgradeServer();
|
||||
|
@ -74,6 +79,11 @@ class DeleteUserJob extends ClientJob {
|
|||
|
||||
final User user;
|
||||
|
||||
@override
|
||||
bool canAddTo(final List<ClientJob> jobs) => !jobs.any(
|
||||
(final job) => job is DeleteUserJob && job.user.login == user.login,
|
||||
);
|
||||
|
||||
@override
|
||||
void execute(final JobsCubit cubit) async {
|
||||
await cubit.usersCubit.deleteUser(user);
|
||||
|
@ -83,33 +93,30 @@ class DeleteUserJob extends ClientJob {
|
|||
List<Object> get props => [id, title, user];
|
||||
}
|
||||
|
||||
abstract class ToggleJob extends ClientJob {
|
||||
ToggleJob({
|
||||
required final this.service,
|
||||
required final super.title,
|
||||
});
|
||||
|
||||
final Service service;
|
||||
|
||||
@override
|
||||
List<Object> get props => [...super.props, service];
|
||||
}
|
||||
|
||||
class ServiceToggleJob extends ToggleJob {
|
||||
class ServiceToggleJob extends ClientJob {
|
||||
ServiceToggleJob({
|
||||
required super.service,
|
||||
required this.service,
|
||||
required this.needToTurnOn,
|
||||
}) : super(
|
||||
title:
|
||||
'${needToTurnOn ? "jobs.service_turn_on".tr() : "jobs.service_turn_off".tr()} ${service.displayName}',
|
||||
);
|
||||
|
||||
final bool needToTurnOn;
|
||||
final Service service;
|
||||
|
||||
@override
|
||||
bool canAddTo(final List<ClientJob> jobs) => !jobs.any(
|
||||
(final job) => job is ServiceToggleJob && job.service.id == service.id,
|
||||
);
|
||||
|
||||
@override
|
||||
void execute(final JobsCubit cubit) async {
|
||||
await cubit.api.switchService(service.id, needToTurnOn);
|
||||
}
|
||||
|
||||
final bool needToTurnOn;
|
||||
@override
|
||||
List<Object> get props => [...super.props, service];
|
||||
}
|
||||
|
||||
class CreateSSHKeyJob extends ClientJob {
|
||||
|
@ -139,6 +146,14 @@ class DeleteSSHKeyJob extends ClientJob {
|
|||
final User user;
|
||||
final String publicKey;
|
||||
|
||||
@override
|
||||
bool canAddTo(final List<ClientJob> jobs) => !jobs.any(
|
||||
(final job) =>
|
||||
job is DeleteSSHKeyJob &&
|
||||
job.publicKey == publicKey &&
|
||||
job.user.login == user.login,
|
||||
);
|
||||
|
||||
@override
|
||||
void execute(final JobsCubit cubit) async {
|
||||
await cubit.usersCubit.deleteSshKey(user, publicKey);
|
||||
|
|
|
@ -10,7 +10,6 @@ class _ServerSettings extends StatefulWidget {
|
|||
class _ServerSettingsState extends State<_ServerSettings> {
|
||||
bool? allowAutoUpgrade;
|
||||
bool? rebootAfterUpgrade;
|
||||
bool? didSomethingChange;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
|
@ -25,18 +24,14 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
rebootAfterUpgrade = serverDetailsState.autoUpgradeSettings.allowReboot;
|
||||
}
|
||||
|
||||
didSomethingChange ??= false;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
SwitchListTile(
|
||||
value: allowAutoUpgrade ?? false,
|
||||
onChanged: (final switched) {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
context
|
||||
.read<ServerDetailsCubit>()
|
||||
.repository
|
||||
|
@ -48,7 +43,6 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
);
|
||||
setState(() {
|
||||
allowAutoUpgrade = switched;
|
||||
didSomethingChange = true;
|
||||
});
|
||||
},
|
||||
title: Text('server.allow_autoupgrade'.tr()),
|
||||
|
@ -60,11 +54,9 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
SwitchListTile(
|
||||
value: rebootAfterUpgrade ?? false,
|
||||
onChanged: (final switched) {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
context
|
||||
.read<ServerDetailsCubit>()
|
||||
.repository
|
||||
|
@ -76,7 +68,6 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
);
|
||||
setState(() {
|
||||
rebootAfterUpgrade = switched;
|
||||
didSomethingChange = true;
|
||||
});
|
||||
},
|
||||
title: Text('server.reboot_after_upgrade'.tr()),
|
||||
|
@ -91,14 +82,9 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
serverDetailsState.serverTimezone.toString(),
|
||||
),
|
||||
onTap: () {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
didSomethingChange = true;
|
||||
});
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
Navigator.of(context).push(
|
||||
materialRoute(
|
||||
const SelectTimezone(),
|
||||
|
|
|
@ -89,7 +89,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
ListTile(
|
||||
iconColor: Theme.of(context).colorScheme.onBackground,
|
||||
onTap: () => {
|
||||
context.read<JobsCubit>().createOrRemoveServiceToggleJob(
|
||||
context.read<JobsCubit>().addJob(
|
||||
ServiceToggleJob(
|
||||
service: service,
|
||||
needToTurnOn: serviceDisabled,
|
||||
|
|
|
@ -157,8 +157,7 @@ class _Card extends StatelessWidget {
|
|||
|
||||
return BrandSwitch(
|
||||
value: isActive,
|
||||
onChanged: (final value) =>
|
||||
jobsCubit.createOrRemoveServiceToggleJob(
|
||||
onChanged: (final value) => jobsCubit.addJob(
|
||||
ServiceToggleJob(
|
||||
service: service,
|
||||
needToTurnOn: value,
|
||||
|
|
Loading…
Reference in New Issue
These validations look awful. We have
equatable
in our project for that.https://pub.dev/packages/equatable
This library is used in all of our cubits state to compare if they are the same. Should we use it here too?
We can't use equatable for it, because it bears different semantics. Even its documentation page says
What
canAddTo
does is not simple checking for equality, if you read these checks again you will see they have different meaning, none of them is checking for absolute equality of job instances, at least because jobs have unique ids.The issue is the looks of the solution and I actually don't know how to avoid this. I mean, previously these checks were in JobsCubit, now they are in the jobs themselves, the same approach.
Equatable covers exactly same logic you see using in these checks. Just drop to
props
fields you want to check, and that's it.Ah, well, I see that during check you do not construct a Job object, and you nave nothing to compare yet.Nope, just pass
this