From 793b547e2da9978fac203adc8bc9fb2c0deb73fc Mon Sep 17 00:00:00 2001 From: chaw Date: Tue, 25 Jul 2023 12:30:55 +0800 Subject: [PATCH 1/8] [CORE-5930] save indicator --- .../assessment/assessment.component.html | 10 +++++++ .../assessment/assessment.component.scss | 1 + .../assessment/assessment.component.ts | 27 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/projects/v3/src/app/components/assessment/assessment.component.html b/projects/v3/src/app/components/assessment/assessment.component.html index 4e7ebfd44..173196fee 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.html +++ b/projects/v3/src/app/components/assessment/assessment.component.html @@ -4,6 +4,16 @@ +
+ + +
+ +asdasdad +

{{ savingMessage$ | async }}

diff --git a/projects/v3/src/app/components/assessment/assessment.component.scss b/projects/v3/src/app/components/assessment/assessment.component.scss index b9fe895d1..fa46ac3aa 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.scss +++ b/projects/v3/src/app/components/assessment/assessment.component.scss @@ -181,3 +181,4 @@ ion-footer { margin-left: auto; margin-right: auto; } + diff --git a/projects/v3/src/app/components/assessment/assessment.component.ts b/projects/v3/src/app/components/assessment/assessment.component.ts index 38d96f3d3..68b1b770b 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.ts +++ b/projects/v3/src/app/components/assessment/assessment.component.ts @@ -7,6 +7,7 @@ import { BrowserStorageService } from '@v3/services/storage.service'; import { SharedService } from '@v3/services/shared.service'; import { BehaviorSubject, Observable, of, Subject, Subscription, throwError } from 'rxjs'; import { concatMap, delay, tap } from 'rxjs/operators'; +import { trigger, state, style, animate, transition } from '@angular/animations'; // const SAVE_PROGRESS_TIMEOUT = 10000; - AV2-1326 @@ -14,6 +15,14 @@ import { concatMap, delay, tap } from 'rxjs/operators'; selector: 'app-assessment', templateUrl: './assessment.component.html', styleUrls: ['./assessment.component.scss'], + animations: [ + trigger('tickAnimation', [ + state('visible', style({ transform: 'scale(1)', opacity: 1 })), + state('hidden', style({ transform: 'scale(0)', opacity: 0 })), + transition('hidden => visible', animate('200ms ease-out')), + transition('visible => hidden', animate('100ms ease-in')), + ]), + ], }) export class AssessmentComponent implements OnChanges, OnDestroy { /** @@ -47,6 +56,24 @@ export class AssessmentComponent implements OnChanges, OnDestroy { // continue to the next task @Output() continue = new EventEmitter(); + saved: boolean = false; + + onAutoSaveSuccess() { + this.saved = true; + } + change() { + this.saved = !this.saved; + } + + onAnimationEnd(event) { + if (event.toState === 'visible') { + // Animation has ended with the tick being visible, now toggle the saved flag after a short delay + setTimeout(() => { + this.saved = false; + }, 1000); // Adjust the delay as per your preference (in milliseconds) + } + } + submitActions = new Subject<{ saveInProgress: boolean; goBack: boolean; From cf0011721f716248a9e322f847c12eb6f8f3429c Mon Sep 17 00:00:00 2001 From: chaw Date: Wed, 26 Jul 2023 10:15:08 +0800 Subject: [PATCH 2/8] [CORE-5930] save indicates on new edit --- .../assessment/assessment.component.html | 21 ++++++++------- .../assessment/assessment.component.scss | 6 +++++ .../assessment/assessment.component.ts | 26 +++++++++++-------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/projects/v3/src/app/components/assessment/assessment.component.html b/projects/v3/src/app/components/assessment/assessment.component.html index 173196fee..c66df9f60 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.html +++ b/projects/v3/src/app/components/assessment/assessment.component.html @@ -4,16 +4,6 @@
-
- - -
- -asdasdad -

{{ savingMessage$ | async }}

@@ -153,6 +143,17 @@

{{ group.name }}

+ + +
+ + +
+ { > + ; @Input() question; @@ -33,17 +35,19 @@ export class MultipleComponent implements ControlValueAccessor, OnInit { @Input() doReview: Boolean; // FormControl that is passed in from parent component @Input() control: AbstractControl; - // answer field for submitter & reviewer - @ViewChild('answer') answerRef: ElementRef; // comment field for reviewer @ViewChild('commentEle') commentRef: ElementRef; + autosave$ = new Subject(); + // the value of answer innerValue: any; comment: string; // validation errors array errors: Array = []; + subscriptions: Subscription[] = []; + constructor( private utils: UtilsService, ) {} @@ -52,6 +56,46 @@ export class MultipleComponent implements ControlValueAccessor, OnInit { this._showSavedAnswers(); } + ngAfterViewInit() { + this.autosave$.pipe( + debounceTime(800), + ).subscribe(() => { + const action: { + saveInProgress?: boolean; + goBack?: boolean; + questionSave?: {}; + reviewSave?: {}; + } = { + saveInProgress: true, + goBack: false, + }; + + if (this.doReview === true) { + action.reviewSave = { + reviewId: this.reviewId, + submissionId: this.submissionId, + questionId: this.question.id, + answer: this.innerValue.answer, + comment: this.innerValue.comment, + }; + } + + if (this.doAssessment === true) { + action.questionSave = { + submissionId: this.submissionId, + questionId: this.question.id, + answer: this.innerValue, + }; + } + + this.submitActions$.next(action); + }); + } + + ngOnDestroy() { + this.subscriptions.forEach(sub => sub.unsubscribe()); + } + // propagate changes into the form control propagateChange = (_: any) => {}; @@ -98,35 +142,7 @@ export class MultipleComponent implements ControlValueAccessor, OnInit { } } - const action: { - saveInProgress?: boolean; - goBack?: boolean; - questionSave?: {}; - reviewSave?: {}; - } = { - saveInProgress: true, - goBack: false, - }; - - if (this.doReview === true) { - action.reviewSave = { - reviewId: this.reviewId, - submissionId: this.submissionId, - questionId: this.question.id, - answer: this.innerValue.answer, - comment: this.innerValue.comment, - }; - } - - if (this.doAssessment === true) { - action.questionSave = { - submissionId: this.submissionId, - questionId: this.question.id, - answer: this.innerValue, - }; - } - - this.submitActions$.next(action); + this.autosave$.next(); } // From ControlValueAccessor interface diff --git a/projects/v3/src/app/components/oneof/oneof.component.ts b/projects/v3/src/app/components/oneof/oneof.component.ts index e868be038..ae07d5fe4 100644 --- a/projects/v3/src/app/components/oneof/oneof.component.ts +++ b/projects/v3/src/app/components/oneof/oneof.component.ts @@ -1,6 +1,7 @@ -import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ElementRef, OnInit } from '@angular/core'; -import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormControl, AbstractControl } from '@angular/forms'; +import { Component, Input, forwardRef, ViewChild, ElementRef, OnInit } from '@angular/core'; +import { NG_VALUE_ACCESSOR, ControlValueAccessor, AbstractControl } from '@angular/forms'; import { Subject } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; @Component({ selector: 'app-oneof', @@ -43,12 +44,50 @@ export class OneofComponent implements ControlValueAccessor, OnInit { // validation errors array errors: Array = []; + autosave$ = new Subject(); + constructor() {} ngOnInit() { this._showSavedAnswers(); } + ngAfterViewInit() { + this.autosave$.pipe( + debounceTime(800), + ).subscribe(() => { + const action: { + saveInProgress?: boolean; + goBack?: boolean; + questionSave?: {}; + reviewSave?: {}; + } = { + saveInProgress: true, + goBack: false, + }; + + if (this.doReview === true) { + action.reviewSave = { + reviewId: this.reviewId, + submissionId: this.submissionId, + questionId: this.question.id, + answer: this.innerValue.answer, + comment: this.innerValue.comment, + }; + } + + if (this.doAssessment === true) { + action.questionSave = { + submissionId: this.submissionId, + questionId: this.question.id, + answer: this.innerValue, + }; + } + + this.submitActions$.next(action); + }); + } + // propagate changes into the form control propagateChange = (_: any) => {}; @@ -83,35 +122,7 @@ export class OneofComponent implements ControlValueAccessor, OnInit { } } - const action: { - saveInProgress?: boolean; - goBack?: boolean; - questionSave?: {}; - reviewSave?: {}; - } = { - saveInProgress: true, - goBack: false, - }; - - if (this.doReview === true) { - action.reviewSave = { - reviewId: this.reviewId, - submissionId: this.submissionId, - questionId: this.question.id, - answer: this.innerValue.answer, - comment: this.innerValue.comment, - }; - } - - if (this.doAssessment === true) { - action.questionSave = { - submissionId: this.submissionId, - questionId: this.question.id, - answer: this.innerValue, - }; - } - - this.submitActions$.next(action); + this.autosave$.next(); } // From ControlValueAccessor interface diff --git a/projects/v3/src/app/components/text/text.component.ts b/projects/v3/src/app/components/text/text.component.ts index 1d78d3efe..3624a7a8b 100644 --- a/projects/v3/src/app/components/text/text.component.ts +++ b/projects/v3/src/app/components/text/text.component.ts @@ -1,7 +1,7 @@ import { Component, Input, forwardRef, ViewChild, ElementRef, OnInit, AfterViewInit, OnDestroy } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormControl, AbstractControl } from '@angular/forms'; import { IonTextarea } from '@ionic/angular'; -import { AssessmentService, Question } from '@v3/services/assessment.service'; +import { Question } from '@v3/services/assessment.service'; import { Subject, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; @@ -48,9 +48,7 @@ export class TextComponent implements ControlValueAccessor, OnInit, AfterViewIni // validation errors array errors: Array = []; - constructor( - private assessmentService: AssessmentService, - ) {} + constructor() {} ngOnInit() { this._showSavedAnswers(); @@ -60,8 +58,8 @@ export class TextComponent implements ControlValueAccessor, OnInit, AfterViewIni if (this.answerRef?.ionInput) { this.subcriptions.push(this.answerRef.ionInput.pipe( map(e => (e.target as HTMLInputElement).value), - filter(text => text.length > 0), - debounceTime(1250), + filter(text => text.length >= 0), + debounceTime(800), distinctUntilChanged(), ).subscribe(_data => { const action: { From 46a45246bc2e14e0bb82f16b01d68271b71ba19c Mon Sep 17 00:00:00 2001 From: chaw Date: Tue, 29 Aug 2023 01:53:09 +0800 Subject: [PATCH 6/8] [CORE-5930] bad merge leftover --- .../review-rating/review-rating.component.ts | 2 +- .../v3/src/app/services/utils.service.spec.ts | 33 ------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/projects/v3/src/app/components/review-rating/review-rating.component.ts b/projects/v3/src/app/components/review-rating/review-rating.component.ts index 2e44ea85b..cd94f80fe 100644 --- a/projects/v3/src/app/components/review-rating/review-rating.component.ts +++ b/projects/v3/src/app/components/review-rating/review-rating.component.ts @@ -135,7 +135,7 @@ export class ReviewRatingComponent implements OnInit { } addOrRemoveTags(tag) { - this.ratingData.tags = this.utils.addOrRemove(this.ratingData.tags, tag); + this.ratingData.tags = this.utils.addOrRemove(this.ratingData.tags, tag); } rateMood(mood: number): void { diff --git a/projects/v3/src/app/services/utils.service.spec.ts b/projects/v3/src/app/services/utils.service.spec.ts index abc345876..f969a9383 100644 --- a/projects/v3/src/app/services/utils.service.spec.ts +++ b/projects/v3/src/app/services/utils.service.spec.ts @@ -123,39 +123,6 @@ describe('UtilsService', () => { expect(result.length).toEqual(0); expect(result.length).not.toEqual(1); }); - - it('should accept object and remove subject from it', () => { - const result = service.addOrRemove({ - subject1: 'new subject 1', - subject2: 'new subject 2', - subject3: 'new subject 3', - subject4: 'new subject 4', - subject5: 'new subject 5', - }, 'new subject 3'); - - expect(result).toEqual({ - subject1: 'new subject 1', - subject2: 'new subject 2', - subject4: 'new subject 4', - subject5: 'new subject 5', - }); - }); - - - it('should add value if the subject is not already available in the provided object', () => { - const result = service.addOrRemove({ - subject1: 'new subject 1', - subject2: 'new subject 2', - subject3: 'new subject 3', - }, 'new subject 4'); - - expect(result).toEqual({ - subject1: 'new subject 1', - subject2: 'new subject 2', - subject3: 'new subject 3', - 4: 'new subject 4', - }); - }); }); describe('changeThemeColor()', () => { From 7501d54ffdf020fc42b646d60826a09ba7999401 Mon Sep 17 00:00:00 2001 From: chaw Date: Tue, 5 Sep 2023 08:35:17 +0800 Subject: [PATCH 7/8] [CORE-5930] loading indicator --- .../components/assessment/assessment.component.html | 10 ++++++++-- .../app/components/assessment/assessment.component.ts | 11 ++++++++--- .../branding-logo/branding-logo.component.html | 2 +- .../branding-logo/branding-logo.component.ts | 4 +++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/projects/v3/src/app/components/assessment/assessment.component.html b/projects/v3/src/app/components/assessment/assessment.component.html index b2e96588a..e9c98a282 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.html +++ b/projects/v3/src/app/components/assessment/assessment.component.html @@ -147,11 +147,17 @@

{{ group.name }}

- + +
diff --git a/projects/v3/src/app/components/assessment/assessment.component.ts b/projects/v3/src/app/components/assessment/assessment.component.ts index da5e9961d..2814edacf 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.ts +++ b/projects/v3/src/app/components/assessment/assessment.component.ts @@ -55,6 +55,9 @@ export class AssessmentComponent implements OnChanges, OnDestroy { // continue to the next task @Output() continue = new EventEmitter(); + autosaving: { + [key: number]: boolean + } = {}; saved: { [key:number]: boolean } = {}; @@ -63,7 +66,7 @@ export class AssessmentComponent implements OnChanges, OnDestroy { if (event.toState === 'visible') { // Animation has ended with the tick being visible, now toggle the saved flag after a short delay timer(1000).pipe(take(1)).subscribe(() => { - this.saved[questionId] = false; + this.autosaving[questionId] = false; }); } } @@ -126,7 +129,8 @@ export class AssessmentComponent implements OnChanges, OnDestroy { return this.saveReviewAnswer(request.reviewSave); } if (request?.questionSave) { - this.saved[request.questionSave.questionId] = true; + this.autosaving[request.questionSave.questionId] = true; + this.saved[request.questionSave.questionId] = false; return this.saveQuestionAnswer(request.questionSave); } return of(request); @@ -196,7 +200,8 @@ export class AssessmentComponent implements OnChanges, OnDestroy { answer, ).pipe( tap((_res) => { - this.saved[questionInput.questionId] = false; + this.autosaving[questionInput.questionId] = false; + this.saved[questionInput.questionId] = true; }), delay(800) ); diff --git a/projects/v3/src/app/components/branding-logo/branding-logo.component.html b/projects/v3/src/app/components/branding-logo/branding-logo.component.html index cdc48b1ec..4dbb2d8e7 100644 --- a/projects/v3/src/app/components/branding-logo/branding-logo.component.html +++ b/projects/v3/src/app/components/branding-logo/branding-logo.component.html @@ -1 +1 @@ - + diff --git a/projects/v3/src/app/components/branding-logo/branding-logo.component.ts b/projects/v3/src/app/components/branding-logo/branding-logo.component.ts index 57b7550d3..b9df6abe8 100644 --- a/projects/v3/src/app/components/branding-logo/branding-logo.component.ts +++ b/projects/v3/src/app/components/branding-logo/branding-logo.component.ts @@ -9,5 +9,7 @@ export class BrandingLogoComponent { @Input() logo: string; @Input() name?: string; - constructor(public storage: BrowserStorageService) {} + constructor(public storage: BrowserStorageService) { + this.logo = this.logo || this.storage.getConfig().logo; + } } From 1285a55c8d9c1214ed797da378e51891177748fc Mon Sep 17 00:00:00 2001 From: chaw Date: Tue, 5 Sep 2023 10:38:04 +0800 Subject: [PATCH 8/8] [CORE-5930] --- .../src/app/components/assessment/assessment.component.html | 2 -- .../v3/src/app/components/assessment/assessment.component.ts | 4 ---- 2 files changed, 6 deletions(-) diff --git a/projects/v3/src/app/components/assessment/assessment.component.html b/projects/v3/src/app/components/assessment/assessment.component.html index e9c98a282..c4165efdf 100644 --- a/projects/v3/src/app/components/assessment/assessment.component.html +++ b/projects/v3/src/app/components/assessment/assessment.component.html @@ -144,8 +144,6 @@

{{ group.name }}

- -