From b633ced0fa9332943a3e1efa5c70098ef5d35ddc Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Thu, 8 Feb 2024 19:44:12 +0530 Subject: [PATCH 1/6] Quml-player offline play --- .../section-player.component.ts | 14 ++-- .../viewer-service/viewer-service.spec.ts | 27 ++++---- .../services/viewer-service/viewer-service.ts | 69 ++++++++++++++++--- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/projects/quml-library/src/lib/section-player/section-player.component.ts b/projects/quml-library/src/lib/section-player/section-player.component.ts index d79551bc..9fe9c8b3 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.ts @@ -242,9 +242,9 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.jumpToQuestion) { this.goToQuestion(this.jumpToQuestion); } else if (this.threshold === 1) { - this.viewerService.getQuestion(); + this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); } else if (this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (!this.sectionConfig.metadata?.children?.length) { @@ -362,16 +362,16 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.myCarousel.getCurrentSlideIndex() > 0 && ((this.threshold * this.noOfTimesApiCalled) - 1) === this.myCarousel.getCurrentSlideIndex() && this.threshold * this.noOfTimesApiCalled >= this.questions.length && this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (this.myCarousel.getCurrentSlideIndex() > 0 && this.questions[this.myCarousel.getCurrentSlideIndex()] === undefined && this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (this.threshold === 1 && this.myCarousel.getCurrentSlideIndex() >= 0) { - this.viewerService.getQuestion(); + this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); } } @@ -767,7 +767,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.questions[index - 1] === undefined) { this.showQuestions = false; - this.viewerService.getQuestions(0, index); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0, index); this.currentSlideIndex = index; } else if (this.questions[index - 1] !== undefined) { this.myCarousel.selectSlide(index); @@ -783,7 +783,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.disableNext = false; this.initializeTimer = true; const index = event.questionNo; - this.viewerService.getQuestions(0, index); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0 , index); this.currentSlideIndex = index; this.myCarousel.selectSlide(index); this.highlightQuestion(); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts index f35e9a65..f37df96e 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts @@ -5,6 +5,7 @@ import { QumlLibraryService } from '../../quml-library.service'; import { UtilService } from '../../util-service'; import { QuestionCursor } from '../../quml-question-cursor.service'; import { of, throwError } from 'rxjs'; +import { TransformationService } from '../transformation-service/transformation.service'; describe('ViewerService', () => { class MockQuestionCursor { @@ -205,7 +206,7 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(of([{ id: 'do_123' }, { id: 'do_124' }] as any)); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -216,7 +217,7 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -226,18 +227,20 @@ describe('ViewerService', () => { const qumlLibraryService = TestBed.inject(QumlLibraryService); service.identifiers = []; spyOn(service.questionCursor, 'getQuestion'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.questionCursor.getQuestion).not.toHaveBeenCalled(); }); it('should call getQuestions', () => { const service = TestBed.inject(ViewerService); - service.parentIdentifier = 'do_555'; - service.identifiers = ['do_123', 'do_124']; - spyOn(service.questionCursor, 'getQuestions').and.returnValue(of([{ id: 'do_123' }] as any)); - spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestions(0, 1) - expect(service.questionCursor.getQuestions).toHaveBeenCalled(); + service.parentIdentifier = 'do_21348431528472576011'; + service.identifiers = ['do_21348431559137689613', 'do_21348431640099225615']; + spyOn(service, 'getSectionQuestionData').and.returnValue(of([{ id: 'do_21348431559137689613' }] as any)); + const getTransformedQuestionMetadata = TestBed.inject(TransformationService); + spyOn(getTransformedQuestionMetadata, 'getTransformedQuestionMetadata').and.returnValue({questions: [{ id: 'do_21348431559137689613' }], count: 1}) + spyOn(service.qumlQuestionEvent, 'emit').and.callFake(() => {}); + service.getQuestions(mockData.playerConfig.metadata.children, 0, 1) + expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); @@ -246,10 +249,10 @@ describe('ViewerService', () => { service.parentIdentifier = 'do_555'; service.identifiers = ['do_123', 'do_124']; service.threshold = 3; - spyOn(service.questionCursor, 'getQuestions').and.returnValue(throwError('Error')); + spyOn(service, 'getSectionQuestionData').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestions() - expect(service.questionCursor.getQuestions).toHaveBeenCalled(); + service.getQuestions(mockData.playerConfig.metadata.children) + expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts index 0e251129..2469258d 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts @@ -6,7 +6,8 @@ import { TransformationService } from '../transformation-service/transformation. import { eventName, TelemetryType } from '../../telemetry-constants'; import { QuestionCursor } from '../../quml-question-cursor.service'; import * as _ from 'lodash-es'; -import { forkJoin } from 'rxjs'; +import { forkJoin, of } from 'rxjs'; +import { switchMap, map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -231,8 +232,42 @@ export class ViewerService { this.qumlLibraryService.error(stacktrace, { err: errorCode, errtype: errorType }); } + getSectionQuestionData(sectionChildren, questionIdArr) { + const availableQuestions = []; + let questionsIdNotHavingCompleteData = []; + if (_.isEmpty(sectionChildren)) { + questionsIdNotHavingCompleteData = questionIdArr; + } else { + const foundQuestions = sectionChildren.filter(child => questionIdArr.includes(child.identifier)); + for (const question of foundQuestions) { + if (_.has(question, 'body')) { + availableQuestions.push(question); + } else { + questionsIdNotHavingCompleteData.push(question.identifier); + } + } + } + + if (!_.isEmpty(questionsIdNotHavingCompleteData)) { + return this.fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData); + } else { + const allQuestions$ = of({ questions: availableQuestions, count: availableQuestions.length }); + return allQuestions$; + } + } + + fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData) { + return this.questionCursor.getQuestions(questionsIdNotHavingCompleteData, this.parentIdentifier).pipe( + switchMap((questionData: any) => { + const fetchedQuestions = questionData.questions; + const allQuestions = _.concat(availableQuestions, fetchedQuestions); + return of({ questions: allQuestions, count: allQuestions.length }); + }) + ); + } + - getQuestions(currentIndex?: number, index?: number) { + getQuestions(sectionChildren, currentIndex?: number, index?: number) { let indentifersForQuestions; if (currentIndex !== undefined && index) { indentifersForQuestions = this.identifiers.splice(currentIndex, index); @@ -240,10 +275,10 @@ export class ViewerService { indentifersForQuestions = this.identifiers.splice(0, this.threshold); } if (!_.isEmpty(indentifersForQuestions)) { - const requests = []; + let requests: any; const chunkArray = _.chunk(indentifersForQuestions, 10); _.forEach(chunkArray, (value) => { - requests.push(this.questionCursor.getQuestions(value, this.parentIdentifier)); + requests = this.getSectionQuestionData(sectionChildren, value) }); forkJoin(requests).subscribe(questions => { _.forEach(questions, (value) => { @@ -258,16 +293,28 @@ export class ViewerService { } } - getQuestion() { + getQuestion(sectionChildren) { if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); - this.questionCursor.getQuestion(questionIdentifier[0]).subscribe((question) => { - this.qumlQuestionEvent.emit(question); - }, (error) => { - this.qumlQuestionEvent.emit({ - error: error + const getObjectByIdentifier = (identifier: string): any => { + return _.find(sectionChildren, { identifier }); + }; + const fetchedQuestion = getObjectByIdentifier(questionIdentifier); + if (_.has(fetchedQuestion, 'body')) { + const fetchedQuestionData = {questions: [fetchedQuestion], count: 1 }; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + } else { + this.questionCursor.getQuestion(questionIdentifier[0]).subscribe((question) => { + const fetchedQuestionData = question; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + }, (error) => { + this.qumlQuestionEvent.emit({ + error: error + }); }); - }); + } } } From b687c5ef05d8a752b94a480a24c2b48144721eb8 Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Fri, 9 Feb 2024 13:37:34 +0530 Subject: [PATCH 2/6] Issue #IQ-674 fix: Enhancing the web-component to accept the config from Parent App --- .../viewer-service/viewer-service.spec.ts | 20 +++++++++++++++++++ .../services/viewer-service/viewer-service.ts | 8 +++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts index f37df96e..6406a83c 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts @@ -231,6 +231,26 @@ describe('ViewerService', () => { expect(service.questionCursor.getQuestion).not.toHaveBeenCalled(); }); + it('should return available questions if sectionChildren is not empty', () => { + const service = TestBed.inject(ViewerService); + const sectionChildren = [{ identifier: '1', body: 'Question 1' }, { identifier: '2', body: 'Question 2' }]; + const questionIdArr = ['1', '2']; + service.getSectionQuestionData(sectionChildren, questionIdArr).subscribe(result => { + expect(result.questions.length).toBe(2); + expect(result.count).toBe(2); + }); + }); + + it('should return questionsIdNotHavingCompleteData if sectionChildren is empty', () => { + const service = TestBed.inject(ViewerService); + const sectionChildren = []; + const questionIdArr = ['1', '2']; + spyOn(service, 'fetchIncompleteQuestionsData').and.returnValue(of({questions: [{ identifier: '1', body: 'Question 1' }, { identifier: '2', body: 'Question 2' }], count: 2})) + service.getSectionQuestionData(sectionChildren, questionIdArr).subscribe(result => { + expect(result.questions.length).toBe(2); + }); + }); + it('should call getQuestions', () => { const service = TestBed.inject(ViewerService); service.parentIdentifier = 'do_21348431528472576011'; diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts index 2469258d..9ff2552a 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts @@ -7,7 +7,7 @@ import { eventName, TelemetryType } from '../../telemetry-constants'; import { QuestionCursor } from '../../quml-question-cursor.service'; import * as _ from 'lodash-es'; import { forkJoin, of } from 'rxjs'; -import { switchMap, map } from 'rxjs/operators'; +import { switchMap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -296,10 +296,8 @@ export class ViewerService { getQuestion(sectionChildren) { if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); - const getObjectByIdentifier = (identifier: string): any => { - return _.find(sectionChildren, { identifier }); - }; - const fetchedQuestion = getObjectByIdentifier(questionIdentifier); + const fetchedQuestion = _.find(sectionChildren, (question) => _.includes(questionIdentifier, question.identifier)); + if (_.has(fetchedQuestion, 'body')) { const fetchedQuestionData = {questions: [fetchedQuestion], count: 1 }; const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); From c93c3cfe4d17834e01a8e0a4a210e2012c967318 Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Fri, 9 Feb 2024 14:52:45 +0530 Subject: [PATCH 3/6] Issue #IQ-674 fix: Enhancing the web-component to accept the config from Parent App --- .../viewer-service/viewer-service.spec.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts index 6406a83c..9b389552 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts @@ -211,6 +211,18 @@ describe('ViewerService', () => { expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); + it('should emit transformed question metadata if question body is available', () => { + const service = TestBed.inject(ViewerService); + const sectionChildren = [{ identifier: '1', body: 'Question 1' }]; + const fetchedQuestionData = { questions: [{ identifier: '1', body: 'Question 1' }], count: 1 }; + spyOn(service.transformationService, 'getTransformedQuestionMetadata').and.returnValue(fetchedQuestionData); + spyOn(service.qumlQuestionEvent, 'emit').and.callFake(() => {}); + service.threshold = 1; + service.identifiers = ['1']; + service.getQuestion(sectionChildren); + expect(service.qumlQuestionEvent.emit).toHaveBeenCalledWith(fetchedQuestionData); + }); + it('should call getQuestion and return the error', () => { const service = TestBed.inject(ViewerService); const qumlLibraryService = TestBed.inject(QumlLibraryService); @@ -251,6 +263,18 @@ describe('ViewerService', () => { }); }); + it('should fetch incomplete questions data and return combined questions', () => { + const service = TestBed.inject(ViewerService); + const availableQuestions = [{ identifier: '1', body: 'Question 1' }]; + const questionsIdNotHavingCompleteData = ['2']; + const questionData = { identifier: '2', body: 'Question 2' } + spyOn(service.questionCursor, 'getQuestions').and.returnValue(of([{ questions: [questionData], count: 1 }] as any)) + service.fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData).subscribe(result => { + expect(result.questions.length).toBe(2); + expect(result.count).toBe(2); + }); + }); + it('should call getQuestions', () => { const service = TestBed.inject(ViewerService); service.parentIdentifier = 'do_21348431528472576011'; From 86fb8a81a702719bff800ffcef80e9ca4bc44564 Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Mon, 12 Feb 2024 11:33:48 +0530 Subject: [PATCH 4/6] Issue #IQ-674 fix: Enhancing the web-component to accept the config from Parent App --- .../section-player/section-player.component.ts | 15 ++++++++------- .../viewer-service/viewer-service.spec.ts | 18 ++++++++++++------ .../services/viewer-service/viewer-service.ts | 10 ++++++---- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/projects/quml-library/src/lib/section-player/section-player.component.ts b/projects/quml-library/src/lib/section-player/section-player.component.ts index 9fe9c8b3..b7c8d0b4 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.ts @@ -104,6 +104,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (changes && Object.values(changes)[0].firstChange) { this.subscribeToEvents(); } + this.viewerService.sectionConfig = this.sectionConfig; this.setConfig(); } @@ -242,9 +243,9 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.jumpToQuestion) { this.goToQuestion(this.jumpToQuestion); } else if (this.threshold === 1) { - this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); + this.viewerService.getQuestion(); } else if (this.threshold > 1) { - this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); + this.viewerService.getQuestions(); } if (!this.sectionConfig.metadata?.children?.length) { @@ -362,16 +363,16 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.myCarousel.getCurrentSlideIndex() > 0 && ((this.threshold * this.noOfTimesApiCalled) - 1) === this.myCarousel.getCurrentSlideIndex() && this.threshold * this.noOfTimesApiCalled >= this.questions.length && this.threshold > 1) { - this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); + this.viewerService.getQuestions(); } if (this.myCarousel.getCurrentSlideIndex() > 0 && this.questions[this.myCarousel.getCurrentSlideIndex()] === undefined && this.threshold > 1) { - this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); + this.viewerService.getQuestions(); } if (this.threshold === 1 && this.myCarousel.getCurrentSlideIndex() >= 0) { - this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); + this.viewerService.getQuestion(); } } @@ -767,7 +768,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.questions[index - 1] === undefined) { this.showQuestions = false; - this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0, index); + this.viewerService.getQuestions(0, index); this.currentSlideIndex = index; } else if (this.questions[index - 1] !== undefined) { this.myCarousel.selectSlide(index); @@ -783,7 +784,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.disableNext = false; this.initializeTimer = true; const index = event.questionNo; - this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0 , index); + this.viewerService.getQuestions(0 , index); this.currentSlideIndex = index; this.myCarousel.selectSlide(index); this.highlightQuestion(); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts index 9b389552..564b2375 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts @@ -206,7 +206,8 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(of([{ id: 'do_123' }, { id: 'do_124' }] as any)); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(mockData.playerConfig.metadata.children); + service.sectionConfig = mockData.playerConfig; + service.getQuestion(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -219,7 +220,8 @@ describe('ViewerService', () => { spyOn(service.qumlQuestionEvent, 'emit').and.callFake(() => {}); service.threshold = 1; service.identifiers = ['1']; - service.getQuestion(sectionChildren); + service.sectionConfig = {metadata:{children: sectionChildren}}; + service.getQuestion(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalledWith(fetchedQuestionData); }); @@ -229,7 +231,8 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(mockData.playerConfig.metadata.children); + service.sectionConfig = mockData.playerConfig; + service.getQuestion(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -239,7 +242,8 @@ describe('ViewerService', () => { const qumlLibraryService = TestBed.inject(QumlLibraryService); service.identifiers = []; spyOn(service.questionCursor, 'getQuestion'); - service.getQuestion(mockData.playerConfig.metadata.children); + service.sectionConfig = mockData.playerConfig; + service.getQuestion(); expect(service.questionCursor.getQuestion).not.toHaveBeenCalled(); }); @@ -283,7 +287,8 @@ describe('ViewerService', () => { const getTransformedQuestionMetadata = TestBed.inject(TransformationService); spyOn(getTransformedQuestionMetadata, 'getTransformedQuestionMetadata').and.returnValue({questions: [{ id: 'do_21348431559137689613' }], count: 1}) spyOn(service.qumlQuestionEvent, 'emit').and.callFake(() => {}); - service.getQuestions(mockData.playerConfig.metadata.children, 0, 1) + service.sectionConfig = mockData.playerConfig; + service.getQuestions(0, 1) expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); @@ -295,7 +300,8 @@ describe('ViewerService', () => { service.threshold = 3; spyOn(service, 'getSectionQuestionData').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestions(mockData.playerConfig.metadata.children) + service.sectionConfig = mockData.playerConfig; + service.getQuestions() expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts index 9ff2552a..59cd8e55 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts @@ -6,7 +6,7 @@ import { TransformationService } from '../transformation-service/transformation. import { eventName, TelemetryType } from '../../telemetry-constants'; import { QuestionCursor } from '../../quml-question-cursor.service'; import * as _ from 'lodash-es'; -import { forkJoin, of } from 'rxjs'; +import { Subject, forkJoin, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @Injectable({ @@ -36,7 +36,7 @@ export class ViewerService { questionSetId: string; parentIdentifier: string; sectionQuestions = []; - + sectionConfig:any; constructor( public qumlLibraryService: QumlLibraryService, public utilService: UtilService, @@ -267,7 +267,8 @@ export class ViewerService { } - getQuestions(sectionChildren, currentIndex?: number, index?: number) { + getQuestions(currentIndex?: number, index?: number) { + const sectionChildren = this.sectionConfig?.metadata?.children; let indentifersForQuestions; if (currentIndex !== undefined && index) { indentifersForQuestions = this.identifiers.splice(currentIndex, index); @@ -293,7 +294,8 @@ export class ViewerService { } } - getQuestion(sectionChildren) { + getQuestion() { + const sectionChildren = this.sectionConfig?.metadata?.children; if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); const fetchedQuestion = _.find(sectionChildren, (question) => _.includes(questionIdentifier, question.identifier)); From 07f88090a2c56935f4cd6c17af847143bd43fc75 Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Mon, 12 Feb 2024 11:47:14 +0530 Subject: [PATCH 5/6] Issue #IQ-674 fix: Enhancing the web-component to accept the config from Parent App --- .../src/lib/services/viewer-service/viewer-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts index 59cd8e55..6fcc8482 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts @@ -6,7 +6,7 @@ import { TransformationService } from '../transformation-service/transformation. import { eventName, TelemetryType } from '../../telemetry-constants'; import { QuestionCursor } from '../../quml-question-cursor.service'; import * as _ from 'lodash-es'; -import { Subject, forkJoin, of } from 'rxjs'; +import { forkJoin, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @Injectable({ From e92bb84481d4cbdf82ffc7e4cf4598d73a867167 Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Mon, 12 Feb 2024 14:53:00 +0530 Subject: [PATCH 6/6] Issue #IQ-674 fix: Enhancing the web-component to accept the config from Parent App --- .../section-player.component.ts | 2 +- web-component/package.json | 2 +- web-component/sunbird-quml-player.js | 150 ++++++++++++++++-- 3 files changed, 135 insertions(+), 19 deletions(-) diff --git a/projects/quml-library/src/lib/section-player/section-player.component.ts b/projects/quml-library/src/lib/section-player/section-player.component.ts index b7c8d0b4..03c37503 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.ts @@ -784,7 +784,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.disableNext = false; this.initializeTimer = true; const index = event.questionNo; - this.viewerService.getQuestions(0 , index); + this.viewerService.getQuestions(0, index); this.currentSlideIndex = index; this.myCarousel.selectSlide(index); this.highlightQuestion(); diff --git a/web-component/package.json b/web-component/package.json index fc8925de..831f54e6 100644 --- a/web-component/package.json +++ b/web-component/package.json @@ -1,6 +1,6 @@ { "name": "@project-sunbird/sunbird-quml-player-web-component", - "version": "3.0.2", + "version": "3.0.3", "description": "The web component package for the sunbird QuML player", "main": "sunbird-quml-player.js", "scripts": { diff --git a/web-component/sunbird-quml-player.js b/web-component/sunbird-quml-player.js index 52482ab3..1d60db46 100644 --- a/web-component/sunbird-quml-player.js +++ b/web-component/sunbird-quml-player.js @@ -77175,6 +77175,65 @@ function cloneDeep(value) { /***/ }), +/***/ 6480: +/*!******************************************!*\ + !*** ./node_modules/lodash-es/concat.js ***! + \******************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_arrayPush.js */ 2784); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_baseFlatten.js */ 3932); +/* harmony import */ var _copyArray_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_copyArray.js */ 7331); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isArray.js */ 7191); + + + + + +/** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + while (index--) { + args[index - 1] = arguments[index]; + } + return (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_isArray_js__WEBPACK_IMPORTED_MODULE_1__["default"])(array) ? (0,_copyArray_js__WEBPACK_IMPORTED_MODULE_2__["default"])(array) : [array], (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_3__["default"])(args, 1)); +} +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (concat); + +/***/ }), + /***/ 9005: /*!********************************************!*\ !*** ./node_modules/lodash-es/constant.js ***! @@ -85442,7 +85501,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "QumlLibraryService": () => (/* binding */ QumlLibraryService) /* harmony export */ }); -/* harmony import */ var _home_ttpl_rt_66_Documents_inQuiry_player_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 1670); +/* harmony import */ var _home_ttpl_rt_171_Documents_inQuiry_player_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 1670); /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/core */ 2560); /* harmony import */ var _project_sunbird_client_services_telemetry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @project-sunbird/client-services/telemetry */ 4635); /* harmony import */ var _project_sunbird_client_services_telemetry__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_project_sunbird_client_services_telemetry__WEBPACK_IMPORTED_MODULE_1__); @@ -85463,7 +85522,7 @@ class QumlLibraryService { } initializeTelemetry(config, parentConfig) { var _this = this; - return (0,_home_ttpl_rt_66_Documents_inQuiry_player_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { + return (0,_home_ttpl_rt_171_Documents_inQuiry_player_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () { if (!lodash_es__WEBPACK_IMPORTED_MODULE_4__["default"](config, 'context') || lodash_es__WEBPACK_IMPORTED_MODULE_5__["default"](config, 'context')) { return; } @@ -86763,6 +86822,7 @@ class SectionPlayerComponent { if (changes && Object.values(changes)[0].firstChange) { this.subscribeToEvents(); } + this.viewerService.sectionConfig = this.sectionConfig; this.setConfig(); } ngAfterViewInit() { @@ -88003,9 +88063,15 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _telemetry_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../telemetry-constants */ 7930); /* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lodash-es */ 8163); /* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lodash-es */ 4607); -/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lodash-es */ 3089); -/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! lodash-es */ 9724); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs */ 4350); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lodash-es */ 2941); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! lodash-es */ 6480); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! lodash-es */ 3089); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! lodash-es */ 9724); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! lodash-es */ 7732); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! lodash-es */ 3795); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 4139); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs */ 4350); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 9095); /* harmony import */ var _quml_library_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../quml-library.service */ 5669); /* harmony import */ var _util_service__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../util-service */ 2025); /* harmony import */ var _quml_question_cursor_service__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../quml-question-cursor.service */ 8659); @@ -88019,6 +88085,7 @@ __webpack_require__.r(__webpack_exports__); + class ViewerService { constructor(qumlLibraryService, utilService, questionCursor, transformationService) { this.qumlLibraryService = qumlLibraryService; @@ -88209,7 +88276,43 @@ class ViewerService { errtype: errorType }); } + getSectionQuestionData(sectionChildren, questionIdArr) { + const availableQuestions = []; + let questionsIdNotHavingCompleteData = []; + if (lodash_es__WEBPACK_IMPORTED_MODULE_7__["default"](sectionChildren)) { + questionsIdNotHavingCompleteData = questionIdArr; + } else { + const foundQuestions = sectionChildren.filter(child => questionIdArr.includes(child.identifier)); + for (const question of foundQuestions) { + if (lodash_es__WEBPACK_IMPORTED_MODULE_8__["default"](question, 'body')) { + availableQuestions.push(question); + } else { + questionsIdNotHavingCompleteData.push(question.identifier); + } + } + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_7__["default"](questionsIdNotHavingCompleteData)) { + return this.fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData); + } else { + const allQuestions$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.of)({ + questions: availableQuestions, + count: availableQuestions.length + }); + return allQuestions$; + } + } + fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData) { + return this.questionCursor.getQuestions(questionsIdNotHavingCompleteData, this.parentIdentifier).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.switchMap)(questionData => { + const fetchedQuestions = questionData.questions; + const allQuestions = lodash_es__WEBPACK_IMPORTED_MODULE_11__["default"](availableQuestions, fetchedQuestions); + return (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.of)({ + questions: allQuestions, + count: allQuestions.length + }); + })); + } getQuestions(currentIndex, index) { + const sectionChildren = this.sectionConfig?.metadata?.children; let indentifersForQuestions; if (currentIndex !== undefined && index) { indentifersForQuestions = this.identifiers.splice(currentIndex, index); @@ -88217,13 +88320,13 @@ class ViewerService { indentifersForQuestions = this.identifiers.splice(0, this.threshold); } if (!lodash_es__WEBPACK_IMPORTED_MODULE_7__["default"](indentifersForQuestions)) { - const requests = []; - const chunkArray = lodash_es__WEBPACK_IMPORTED_MODULE_8__["default"](indentifersForQuestions, 10); - lodash_es__WEBPACK_IMPORTED_MODULE_9__["default"](chunkArray, value => { - requests.push(this.questionCursor.getQuestions(value, this.parentIdentifier)); + let requests; + const chunkArray = lodash_es__WEBPACK_IMPORTED_MODULE_12__["default"](indentifersForQuestions, 10); + lodash_es__WEBPACK_IMPORTED_MODULE_13__["default"](chunkArray, value => { + requests = this.getSectionQuestionData(sectionChildren, value); }); - (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.forkJoin)(requests).subscribe(questions => { - lodash_es__WEBPACK_IMPORTED_MODULE_9__["default"](questions, value => { + (0,rxjs__WEBPACK_IMPORTED_MODULE_14__.forkJoin)(requests).subscribe(questions => { + lodash_es__WEBPACK_IMPORTED_MODULE_13__["default"](questions, value => { const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(value); this.qumlQuestionEvent.emit(transformedquestionsList); }); @@ -88235,15 +88338,28 @@ class ViewerService { } } getQuestion() { + const sectionChildren = this.sectionConfig?.metadata?.children; if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); - this.questionCursor.getQuestion(questionIdentifier[0]).subscribe(question => { - this.qumlQuestionEvent.emit(question); - }, error => { - this.qumlQuestionEvent.emit({ - error: error + const fetchedQuestion = lodash_es__WEBPACK_IMPORTED_MODULE_15__["default"](sectionChildren, question => lodash_es__WEBPACK_IMPORTED_MODULE_16__["default"](questionIdentifier, question.identifier)); + if (lodash_es__WEBPACK_IMPORTED_MODULE_8__["default"](fetchedQuestion, 'body')) { + const fetchedQuestionData = { + questions: [fetchedQuestion], + count: 1 + }; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + } else { + this.questionCursor.getQuestion(questionIdentifier[0]).subscribe(question => { + const fetchedQuestionData = question; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + }, error => { + this.qumlQuestionEvent.emit({ + error: error + }); }); - }); + } } } generateMaxAttemptEvents(currentattempt, maxLimitExceeded, isLastAttempt) {