refactor(job): Implement polymorphic predicate for job accessibility

Now every job type can impement canAddTo function to make JobsCubit know whether it can be applied or not
pull/134/head
NaiJi ✨ 2022-10-07 17:50:18 +00:00
parent db2f5c1342
commit 7bad11967a
5 changed files with 46 additions and 57 deletions

View File

@ -24,10 +24,13 @@ class JobsCubit extends Cubit<JobsState> {
final ServicesCubit servicesCubit; final ServicesCubit servicesCubit;
void addJob(final ClientJob job) { void addJob(final ClientJob job) {
_updateJobsState([ final jobs = currentJobList;
...currentJobList, if (job.canAddTo(jobs)) {
...[job] _updateJobsState([
]); ...jobs,
...[job],
]);
}
} }
void removeJob(final String id) { void removeJob(final String id) {
@ -35,25 +38,6 @@ class JobsCubit extends Cubit<JobsState> {
emit(newState); emit(newState);
} }
void createOrRemoveServiceToggleJob(final ToggleJob job) {
final List<ClientJob> newJobsList = <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));
}
}
List<ClientJob> get currentJobList { List<ClientJob> get currentJobList {
final List<ClientJob> jobs = <ClientJob>[]; final List<ClientJob> jobs = <ClientJob>[];
if (state is JobsStateWithJobs) { if (state is JobsStateWithJobs) {
@ -68,17 +52,6 @@ class JobsCubit extends Cubit<JobsState> {
emit(JobsStateWithJobs(newJobs)); emit(JobsStateWithJobs(newJobs));
} }
void addUniqueJob<J extends ClientJob>(final J job) {
final List<ClientJob> jobs = currentJobList;
final bool exists = jobs.any((final el) => el is J);
if (!exists) {
_updateJobsState([
...jobs,
...[job]
]);
}
}
Future<void> rebootServer() async { Future<void> rebootServer() async {
emit(JobsStateLoading()); emit(JobsStateLoading());
final bool isSuccessful = await api.reboot(); final bool isSuccessful = await api.reboot();

View File

@ -17,6 +17,7 @@ abstract class ClientJob extends Equatable {
final String title; final String title;
final String id; final String id;
bool canAddTo(final List<ClientJob> jobs) => true;
void execute(final JobsCubit cubit); void execute(final JobsCubit cubit);
@override @override
@ -25,10 +26,14 @@ abstract class ClientJob extends Equatable {
class RebuildServerJob extends ClientJob { class RebuildServerJob extends ClientJob {
RebuildServerJob({ RebuildServerJob({
required final super.title, required super.title,
final super.id, super.id,
}); });
@override
bool canAddTo(final List<ClientJob> jobs) =>
super.canAddTo(jobs) && !jobs.any((final job) => job is RebuildServerJob);
@override @override
void execute(final JobsCubit cubit) async { void execute(final JobsCubit cubit) async {
await cubit.upgradeServer(); await cubit.upgradeServer();
@ -74,6 +79,12 @@ class DeleteUserJob extends ClientJob {
final User user; final User user;
@override
bool canAddTo(final List<ClientJob> jobs) =>
super.canAddTo(jobs) &&
!jobs.any(
(final job) => job is DeleteUserJob && job.user.login == user.login);
@override @override
void execute(final JobsCubit cubit) async { void execute(final JobsCubit cubit) async {
await cubit.usersCubit.deleteUser(user); await cubit.usersCubit.deleteUser(user);
@ -83,33 +94,31 @@ class DeleteUserJob extends ClientJob {
List<Object> get props => [id, title, user]; List<Object> get props => [id, title, user];
} }
abstract class ToggleJob extends ClientJob { class ServiceToggleJob 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 {
ServiceToggleJob({ ServiceToggleJob({
required super.service, required this.service,
required this.needToTurnOn, required this.needToTurnOn,
}) : super( }) : super(
title: title:
'${needToTurnOn ? "jobs.service_turn_on".tr() : "jobs.service_turn_off".tr()} ${service.displayName}', '${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) =>
super.canAddTo(jobs) &&
!jobs.any((final job) =>
job is ServiceToggleJob && job.service.id == service.id);
@override @override
void execute(final JobsCubit cubit) async { void execute(final JobsCubit cubit) async {
await cubit.api.switchService(service.id, needToTurnOn); await cubit.api.switchService(service.id, needToTurnOn);
} }
final bool needToTurnOn; @override
List<Object> get props => [...super.props, service];
} }
class CreateSSHKeyJob extends ClientJob { class CreateSSHKeyJob extends ClientJob {
@ -139,6 +148,14 @@ class DeleteSSHKeyJob extends ClientJob {
final User user; final User user;
final String publicKey; final String publicKey;
@override
bool canAddTo(final List<ClientJob> jobs) =>
super.canAddTo(jobs) &&
!jobs.any((final job) =>
job is DeleteSSHKeyJob &&
job.publicKey == publicKey &&
job.user.login == user.login);
@override @override
void execute(final JobsCubit cubit) async { void execute(final JobsCubit cubit) async {
await cubit.usersCubit.deleteSshKey(user, publicKey); await cubit.usersCubit.deleteSshKey(user, publicKey);

View File

@ -29,7 +29,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
SwitchListTile( SwitchListTile(
value: allowAutoUpgrade ?? false, value: allowAutoUpgrade ?? false,
onChanged: (final switched) { onChanged: (final switched) {
context.read<JobsCubit>().addUniqueJob( context.read<JobsCubit>().addJob(
RebuildServerJob(title: 'jobs.upgrade_server'.tr()), RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
); );
context context
@ -54,7 +54,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
SwitchListTile( SwitchListTile(
value: rebootAfterUpgrade ?? false, value: rebootAfterUpgrade ?? false,
onChanged: (final switched) { onChanged: (final switched) {
context.read<JobsCubit>().addUniqueJob( context.read<JobsCubit>().addJob(
RebuildServerJob(title: 'jobs.upgrade_server'.tr()), RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
); );
context context
@ -82,7 +82,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
serverDetailsState.serverTimezone.toString(), serverDetailsState.serverTimezone.toString(),
), ),
onTap: () { onTap: () {
context.read<JobsCubit>().addUniqueJob( context.read<JobsCubit>().addJob(
RebuildServerJob(title: 'jobs.upgrade_server'.tr()), RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
); );
Navigator.of(context).push( Navigator.of(context).push(

View File

@ -89,7 +89,7 @@ class _ServicePageState extends State<ServicePage> {
ListTile( ListTile(
iconColor: Theme.of(context).colorScheme.onBackground, iconColor: Theme.of(context).colorScheme.onBackground,
onTap: () => { onTap: () => {
context.read<JobsCubit>().createOrRemoveServiceToggleJob( context.read<JobsCubit>().addJob(
ServiceToggleJob( ServiceToggleJob(
service: service, service: service,
needToTurnOn: serviceDisabled, needToTurnOn: serviceDisabled,

View File

@ -157,8 +157,7 @@ class _Card extends StatelessWidget {
return BrandSwitch( return BrandSwitch(
value: isActive, value: isActive,
onChanged: (final value) => onChanged: (final value) => jobsCubit.addJob(
jobsCubit.createOrRemoveServiceToggleJob(
ServiceToggleJob( ServiceToggleJob(
service: service, service: service,
needToTurnOn: value, needToTurnOn: value,