diff --git a/apps/web-mzima-client/src/app/core/services/confirm-modal.service.ts b/apps/web-mzima-client/src/app/core/services/confirm-modal.service.ts index 120e2ae19d8..6717c1290f2 100644 --- a/apps/web-mzima-client/src/app/core/services/confirm-modal.service.ts +++ b/apps/web-mzima-client/src/app/core/services/confirm-modal.service.ts @@ -8,6 +8,8 @@ interface ConfirmModalProps { buttonSuccess?: string; confirmButtonText?: string; cancelButtonText?: string; + actionButtonText?: string; + isCancelDestructive?: boolean; } @Injectable({ @@ -23,6 +25,8 @@ export class ConfirmModalService { buttonSuccess: params.buttonSuccess, confirmButtonText: params.confirmButtonText, cancelButtonText: params.cancelButtonText, + actionButtonText: params.actionButtonText, + isCancelDestructive: params.isCancelDestructive, }; return new Promise((resolve, reject) => { const dialogRef = this.dialog.open(ConfirmModalComponent, { diff --git a/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.html b/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.html index d508a76129d..49314a18843 100644 --- a/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.html +++ b/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.html @@ -144,7 +144,7 @@

{{ 'survey.tasks' | translate }}

{{ 'app.cancel' | translate }} diff --git a/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.ts b/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.ts index 2c31426ef6a..dd690157b92 100644 --- a/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.ts +++ b/apps/web-mzima-client/src/app/settings/surveys/survey-item/survey-item.component.ts @@ -4,6 +4,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { surveyHelper } from '@helpers'; +import { TranslateService } from '@ngx-translate/core'; import { LanguageInterface } from '@mzima-client/sdk'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { BreakpointService, SessionService } from '@services'; @@ -21,6 +22,7 @@ import { SurveyItemEnabledLanguages, } from '@mzima-client/sdk'; import { NotificationService } from '../../../core/services/notification.service'; +import { ConfirmModalService } from '../../../core/services/confirm-modal.service'; import { LanguageService } from '../../../core/services/language.service'; import _ from 'lodash'; @@ -38,10 +40,13 @@ export class SurveyItemComponent extends BaseComponent implements OnInit { public name: string; public form: FormGroup; public isEdit = false; + public changesMade = false; + private initialFormValue: any; public isLoading = false; roles: RoleResult[] = []; surveyId: string; additionalTasks: SurveyItemTask[] = []; + initialTasks: SurveyItemTask[] = []; mainPost: SurveyItemTask; surveyObject: any; public languages: LanguageInterface[]; @@ -64,6 +69,8 @@ export class SurveyItemComponent extends BaseComponent implements OnInit { private notification: NotificationService, private languageService: LanguageService, private location: Location, + private confirmModalService: ConfirmModalService, + private translate: TranslateService, ) { super(sessionService, breakpointService); this.checkDesktop(); @@ -124,12 +131,37 @@ export class SurveyItemComponent extends BaseComponent implements OnInit { this.updateForm(response.result); this.initLanguages(response.result.enabled_languages); this.initTasks(); + //initial state for existing survey + this.setInitialState(); }, }); } else { this.initLanguages({ available: [], default: 'en' }); this.initTasks(true); + //initial state for new survey + this.setInitialState(); } + + this.form.valueChanges.pipe(untilDestroyed(this)).subscribe(() => { + this.changesMade = true; + }); + } + + private setInitialState(): void { + this.initialFormValue = _.cloneDeep(this.form.value); + this.initialTasks = _.cloneDeep(this.form.get('tasks')?.value || []); + this.changesMade = false; + } + + private hasChanges(): boolean { + // Make sure name field is not empty before saving + // Check if form/tasks are different from initial state + const hasNonEmptyValues = !!this.form.get('name')?.value.trim(); + return ( + hasNonEmptyValues && + (!_.isEqual(this.form.value, this.initialFormValue) || + !_.isEqual(this.form.get('tasks')?.value, this.initialTasks)) + ); } private initTasks(isNew = false) { @@ -314,7 +346,27 @@ export class SurveyItemComponent extends BaseComponent implements OnInit { } } - public cancel() { + public async openConfirmModal() { + if (this.hasChanges()) { + const confirmed = await this.confirmModalService.open({ + title: this.translate.instant('notify.default.discard_changes'), + description: this.translate.instant('notify.default.survey_has_not_been_saved'), + cancelButtonText: 'Discard Changes', + actionButtonText: 'Save Changes', + isCancelDestructive: true, + }); + + if (confirmed) { + this.save(); + } else { + this.navigateBack(); + } + } else { + this.navigateBack(); + } + } + + navigateBack() { if (this.isDesktop) { this.router.navigate(['settings/surveys']); } else { diff --git a/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.html b/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.html index 8e441f2421b..5c70e8de65d 100644 --- a/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.html +++ b/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.html @@ -38,20 +38,29 @@

{{ data.title }} {{ data.cancelButtonText || ('app.cancel' | translate) }} {{ data.confirmButtonText || ('app.delete' | translate) }} + + {{ data.actionButtonText || ('app.confirm' | translate) }} + diff --git a/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.ts b/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.ts index 75f3ec7caef..7af4d13ea8f 100644 --- a/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.ts +++ b/apps/web-mzima-client/src/app/shared/components/confirm-modal/confirm-modal.component.ts @@ -7,6 +7,8 @@ export interface ConfirmDialogData { buttonSuccess?: string; confirmButtonText?: string; cancelButtonText?: string; + actionButtonText?: string; + isCancelDestructive?: boolean; } @Component({ diff --git a/apps/web-mzima-client/src/assets/locales/en.json b/apps/web-mzima-client/src/assets/locales/en.json index bdc12808689..14cce34f26a 100644 --- a/apps/web-mzima-client/src/assets/locales/en.json +++ b/apps/web-mzima-client/src/assets/locales/en.json @@ -4,6 +4,7 @@ "powered_by_ushahidi": "Powered by Ushahidi.", "support": "Ushahidi Support", "by": "by", + "confirm": "Confirm", "submit": "Submit", "anonymous": "Anonymous", "submitting": "Submitting", @@ -1722,6 +1723,8 @@ }, "default": { "data_has_not_been_saved": "The data has not been saved!", + "discard_changes": "Discard changes?", + "survey_has_not_been_saved": "The changes will be lost if you don’t save the survey", "proceed_warning": "This action cannot be undone. Please proceed with caution.", "save_success": "Saved resource", "save_error": "Unable to save resource, please try again",