Skip to content

Commit

Permalink
Merge pull request #47 from Sunbird-inQuiry/release-6.0.0
Browse files Browse the repository at this point in the history
Issue #IQ-0000 release: Merging release 6.0.0 into main branch
  • Loading branch information
sajeshkayyath authored Jul 10, 2023
2 parents b76d0cf + 4933623 commit a65b7e5
Show file tree
Hide file tree
Showing 51 changed files with 7,038 additions and 7,008 deletions.
27 changes: 17 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,36 @@ jobs:
- run:
name: Executing test cases
command: npm run test-lib-ci
- run:
name: Install Node.js v16 with build in nvm tool
command: |
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install v16 && nvm use 16 && nvm alias default 16
node -v
- run:
name: Install sonar scanner
command: npm install -g sonarqube-scanner
- run:
name: Run Sonar scanner
command: sonar-scanner
- run:
name: Publish Web component to NPM
name: Publish to NPM
command: |
if [ -z $CIRCLE_PR_NUMBER ]; then
npm run build-web-component && npm pack ./web-component
npm run build-lib && npm pack ./dist/quml-library
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
npm publish project-sunbird-sunbird-quml-player-web-component-* --access public
npm publish project-sunbird-sunbird-quml-player-*
else
npm run build-web-component && npm pack ./web-component
fi
npm run build-lib && npm pack ./dist/quml-library
fi
- run:
name: Publish to NPM
name: Publish Web component to NPM
command: |
if [ -z $CIRCLE_PR_NUMBER ]; then
npm run build-lib && npm pack ./dist/quml-library
npm run build-web-component && npm pack ./web-component
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
npm publish project-sunbird-sunbird-quml-player-*
npm publish project-sunbird-sunbird-quml-player-web-component-* --access public
else
npm run build-lib && npm pack ./dist/quml-library
fi
npm run build-web-component && npm pack ./web-component
fi
1 change: 1 addition & 0 deletions build-wc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const build = async () => {
await concat(files, "web-component/sunbird-quml-player.js");
await fs.copy("./dist/quml-player-wc/assets", "web-component/assets");
await fs.copy("./dist/quml-player-wc/styles.css", "web-component/styles.css");
await fs.copy("README.md", "web-component/README.md")

const filesNames = fs.readdirSync("dist/quml-player-wc");
const allowedFiles = [".ttf", ".woff", ".woff2"];
Expand Down
2,637 changes: 1,365 additions & 1,272 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion projects/quml-demo-app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DataService } from './services/data.service';
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
contentId = 'do_2135557748660469761931'; // do_213257772024733696115 do_2135552779830722561884 do_2135557748660469761931
contentId = 'do_21368754222912307211';
playerConfig: any;

constructor(private dataService: DataService) { }
Expand Down
6 changes: 3 additions & 3 deletions projects/quml-demo-app/src/app/app.constant.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const ApiEndPoints = {
getContent: '/api/content/v1/read/',
getQuestionSetHierarchy: '/learner/questionset/v1/hierarchy/',
questionSetRead: '/api/questionset/v1/read/',
questionList: '/api/question/v1/list',
getQuestionSetHierarchy: '/action/questionset/v2/hierarchy/',
questionSetRead: '/action/questionset/v2/read/',
questionList: '/api/question/v2/list',
}
2 changes: 2 additions & 0 deletions projects/quml-demo-app/src/app/quml-library-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ export const samplePlayerConfig = {
'showReplay': false,
'showExit': false,
},
warningTime: 75,
showWarningTimer: true,
nextContent: { name: 'Next content', identifier: 'do_231234332232' },
showDeviceOrientation: true,
},
Expand Down
10 changes: 7 additions & 3 deletions projects/quml-demo-app/src/app/services/data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ export class DataService {
}

getQuestionSet(identifier: string) {
const hierarchy = this.httpClient.get(`${ApiEndPoints.getQuestionSetHierarchy}${identifier}`);
const questionSetResponse = this.httpClient.get(`${this.baseUrl}${ApiEndPoints.questionSetRead}${identifier}?fields=instructions`);
const hierarchy = this.httpClient.get(`${this.baseUrl}${ApiEndPoints.getQuestionSetHierarchy}${identifier}`);
const questionSetResponse = this.httpClient.get(`${this.baseUrl}${ApiEndPoints.questionSetRead}${identifier}?fields=instructions,outcomeDeclaration`);
return (
forkJoin([hierarchy, questionSetResponse]).pipe(map((res: any) => {
const questionSet = res[0]?.result.questionSet;
const questionSet = res[0]?.result.questionset;
const instructions = res[1].result.questionset.instructions;
if (instructions && questionSet) {
questionSet.instructions = instructions;
}
const outcomeDeclaration = res[1].result.questionset.outcomeDeclaration
if (outcomeDeclaration && questionSet) {
questionSet.outcomeDeclaration = outcomeDeclaration;
}
return questionSet;
})
));
Expand Down
2 changes: 1 addition & 1 deletion projects/quml-demo-app/src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

export const environment = {
production: false,
baseUrl: 'https://staging.sunbirded.org/',
baseUrl: 'https://dev.inquiry.sunbird.org',
};

/*
Expand Down
8 changes: 4 additions & 4 deletions projects/quml-demo-app/src/proxy.conf.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"/api/*": {
"target": "https://staging.sunbirded.org",
"target": "https://dev.inquiry.sunbird.org",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
},
"/learner/*": {
"target": "https://staging.sunbirded.org",
"/action/*": {
"target": "https://dev.inquiry.sunbird.org",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
},
"/assets/*": {
"target": "https://staging.sunbirded.org",
"target": "https://dev.inquiry.sunbird.org",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
Expand Down
212 changes: 8 additions & 204 deletions projects/quml-library/README.md
Original file line number Diff line number Diff line change
@@ -1,210 +1,14 @@
# :diamond_shape_with_a_dot_inside: QuML-player library for Sunbird platform
The QuML player library components are powered by Angular. These components are designed to be used in sunbird consumption platforms *(mobile app, web portal, offline desktop app)* to drive reusability, maintainability, hence reducing the redundant development effort significantly.
# :diamond_shape_with_a_dot_inside: The QuML player for the Sunbird!
The QuML player library components are powered by Angular. This player is primarily designed to be used on Sunbird consumption platforms (mobile app, web portal, offline desktop app) to drive reusability and maintainability, hence reducing the redundant development effort significantly, and it can be integrated with any platform irrespective of the platforms and the frontend frameworks. It is exported not only as an angular library but also as a web component aims to make it easy to share, discover, and reuse web components. It creates a framework agnostic way of composing and repurposing code.

# :bookmark_tabs: Getting Started
For help getting started with a new Angular app, check out the [Angular CLI](https://angular.io/cli).
If you have an Angular ≥ 9 CLI project, you could simply use our schematics to add sunbird-quml-player library to it.
# :bookmark_tabs: Getting started with integration steps
The QuML player can be integrated as a web component and also as an angular library in angular application projects and it can also be integrated into any mobile framework as a web component.

For existing apps, follow the below-mentioned steps:
- [Using it as Web component](https://inquiry.sunbird.org/use/developer-installation/question-set-player/installation#use-as-web-components)
- [Using it as Angular library](https://inquiry.sunbird.org/use/developer-installation/question-set-player/installation#use-as-angular-library-in-angular-app)

## :label: Installation
Just run the following:
```red
ng add @project-sunbird/sunbird-quml-player
```
It will install sunbird-quml-player for the default application specified in your `angular.json`. If you have multiple projects, and you want to target a specific application, you could specify the `--project` option
# :bookmark_tabs: Contribution Guide
See the [official contributors' guide](https://inquiry.sunbird.org/use/developer-installation/question-set-player/installation#quml-player-contribution-guide) to learn how to contribute your code to the project.

```red
ng add @project-sunbird/sunbird-quml-player --project myProject
```
Schematics will create `question-cursor-implementation.service.ts`. Please update the `listUrl` in it. For more information, refer [question-cursor-implementation.service.ts](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/question-cursor-implementation.service.ts)
example: listUrl = "https://staging.sunbirded.org/api/question/v1/list";

### Manual installation
If you prefer not to use schematics or want to add `sunbird-quml-player` to an older project, you'll need to do the following:

<details>
<summary>Click here to show detailed instructions!</summary>

### :label: Step 1: Install Packages
These are the peer Dependencies of the library, need to be installed in order to use this library.

npm install @project-sunbird/sunbird-quml-player --save
npm install @project-sunbird/sb-styles --save
npm install @project-sunbird/client-services --save
npm install bootstrap@^4.6.2 --save
npm install jquery --save
npm install katex --save
npm install lodash-es --save
npm install ngx-bootstrap@^10.0.0 --save


Note: *As QuML library is build with angular version 15, we are using **bootstrap@^4.6.2** and **ngx-bootstrap@^10.0.0** which are the compatible versions.
For more reference Check compatibility document for ng-bootstrap [here](https://valor-software.com/ngx-bootstrap/#/documentation#compatibility)*

## :label: Step 2: Add question-cursor-implementation.service
Create a **question-cursor-implementation.service.ts** in a project and which will implement the `QuestionCursor` abstract class.
`QuestionCursor` is an abstract class, exported from the library, which needs to be implemented. Basically, it has some methods which should make an API request over HTTP

For more information refer [question-cursor-implementation.service.ts](https://github.com/Sunbird-inQuiry/player/blob/main/projects/quml-demo-app/src/app/question-cursor-implementation.service.ts) and do not forget to add your question list API URL here, for example: listUrl = "https://staging.sunbirded.org/api/question/v1/list";
### :label: Step 3: Include the styles, scripts and assets in angular.json
Add the following under `architect.build.assets` for default project
```javascript
{
...
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
...
...
"assets": [
...
...
{
"glob": "**/*.*",
"input": "./node_modules/@project-sunbird/sunbird-quml-player/lib/assets/",
"output": "/assets/"
}
],
"styles": [
...
"src/styles.css",
"./node_modules/@project-sunbird/sb-styles/assets/_styles.scss",
"./node_modules/@project-sunbird/sunbird-quml-player/lib/assets/styles/quml-carousel.css",
"./node_modules/katex/dist/katex.min.css"
],
"scripts": [
...
"./node_modules/katex/dist/katex.min.js",
"./node_modules/jquery/dist/jquery.min.js"
]
}
}
...
...
},
```

### :label: Step 4: Import the modules and components
Import the required modules such as **CarouselModule**, **QumlLibraryModule**, **HttpClientModule** and **question-cursor-implementation.service** as below:

```javascript
import { HttpClientModule } from '@angular/common/http';
import { QumlLibraryModule, QuestionCursor } from '@project-sunbird/sunbird-quml-player';
import { CarouselModule } from 'ngx-bootstrap/carousel';
import { QuestionCursorImplementationService } from './question-cursor-implementation.service';

@NgModule({
...

imports: [ QumlLibraryModule, CarouselModule.forRoot(), HttpClientModule ],
providers: [{
provide: QuestionCursor,
useClass: QuestionCursorImplementationService
}]

...
})

export class AppModule { }
```

</details>

Note: To avoid CORS errors, add proxy configuration for API's refer - [proxy.conf.json](https://github.com/Sunbird-inQuiry/player/blob/release-5.1.0/projects/quml-demo-app/src/proxy.conf.json)

## :label: Send input to render QuML player
User can get a response from the `api/questionset/v1/hierarchy/:do_id` or can use the provided mock config for demo

Use the mock config in your component to send input to QuML player as `playerConfig`
Click to see the mock - [samplePlayerConfig](https://github.com/Sunbird-inQuiry/player/blob/release-5.1.0/projects/quml-demo-app/src/app/quml-library-data.ts#L495)

```html
<quml-main-player [playerConfig]="samplePlayerConfig" ><quml-main-player>
```


## :orange_circle: Available components
|Feature| Notes| Selector|Code|Input|Output
|--|--|--|------------------------------------------------------------------------------------------|---|--|
| QuML Player | Can be used to render QuML | quml-main-player | *`<quml-main-player [playerConfig]="playerConfig"><quml-main-player>`*| playerConfig|playerEvent, telemetryEvent |

### :small_red_triangle_down: Input Parameters
playerConfig: Object - [`Required`]
```javascript
{
context: Object // Optional. Information about the telemetry and default settings for quml API requests
metadata: Object // Question hierarchy response
config: Object // default player config such as sidebar menu list
}
```
**Note:** **context** is optional, which is used for capturing the telemetry event.
If context is not passed in playerConfig telemetry event of player will not be captured.

- Here is the detailed description of playerConfig: [player-configuration](https://inquiry.sunbird.org/learn/product-and-developer-guide/question-set-player/player-configuration)

### :small_red_triangle_down: Output Events
1. playerEvent() - It provides heartbeat event for each action performed in the player.
2. telemetryEvent() - It provides the sequence of telemetry events such as `START, INTERACT, IMPRESSION, SUMMARY, END`

---

# Use as web components :earth_asia:
QuML Library can also be used as web component which means user can import this library in any web application and use these custom components.
Follow below-mentioned steps to use it in plain JavaScript project:

- Insert [library](https://github.com/Sunbird-inQuiry/player/blob/main/web-component/sunbird-quml-player.js) as below:
```javascript
<script type="text/javascript" src="sunbird-quml-player.js"></script>
```
- Create an asset folder and copy all the files from [here](https://github.com/Sunbird-inQuiry/player/tree/main/web-component/assets), library requires these assets internally to work well.

- Get sample playerConfig from here: [samplePlayerConfig](https://github.com/Sunbird-inQuiry/player/blob/release-5.1.0/projects/quml-demo-app/src/app/quml-library-data.ts)

- Pass the Question List API baseUrl for, e.g. [https://staging.sunbirded.org/api/question/v1/list](https://staging.sunbirded.org/api/question/v1/list)

- Create a custom HTML element: `sunbird-quml-player`
```javascript
const qumlPlayerElement = document.createElement('sunbird-quml-player');
```

- Pass data using `player-config`
```javascript
qumlPlayerElement.setAttribute('player-config', JSON.stringify(playerConfig));
```
**Note:** Attribute should be in **string** type
- Listen for the output events: **playerEvent** and **telemetryEvent**

```javascript
qumlPlayerElement.addEventListener('playerEvent', (event) => {
console.log("On playerEvent", event);
});
qumlPlayerElement.addEventListener('telemetryEvent', (event) => {
console.log("On telemetryEvent", event);
});
```

- Append this element to existing element
```javascript
const myPlayer = document.getElementById("my-player");
myPlayer.appendChild(qumlPlayerElement);
```
- :arrow_forward: Refer demo [example](https://github.com/Sunbird-inQuiry/player/blob/main/web-component/index.html)

---

# :bookmark_tabs: QuML Player Contribution Guide
## Repo Setup
- Install Node 14.20.x and Angular 15
- Clone the Repo with desired release-branch - https://github.com/Sunbird-inQuiry/player
- Add the baseUrl in the *environment.ts* and *proxy.conf.json* files
- If there are any changes in API endpoints, update the *app.constant.ts* file
- Change the default content ID in *app.component.ts* file if pointing to different baseUrl
- Run `npm i` in root folder
- Run `npm i` in `projects/quml-library`
- Open two terminal windows (on root folder)
- Run `npm run build` once this run completes, run the next command - let it be running on 1st terminal window
- Run `npm run serve` on second terminal window (This will copy assets from the `quml-library` to the library dist folder)
- Now it will be served on `http://localhost:4200/`
- To run the web-component `npm run build-web-component`
- To run the library run `npm run test-lib`
2 changes: 1 addition & 1 deletion projects/quml-library/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion projects/quml-library/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@project-sunbird/sunbird-quml-player",
"version": "5.7.0",
"version": "6.0.0",
"schematics": "./schematics/collection.json",
"ng-add": {
"save": "dependencies"
Expand Down
8 changes: 7 additions & 1 deletion projects/quml-library/src/lib/alert/alert.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { AlertComponent } from './alert.component';
describe('AlertComponent', () => {
let component: AlertComponent;
let fixture: ComponentFixture<AlertComponent>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [AlertComponent],
Expand Down Expand Up @@ -86,4 +85,11 @@ describe('AlertComponent', () => {
expect(document.querySelector).toHaveBeenCalled();
flush();
}));

it('Should call #close method on keydown', () => {
spyOn(component,'close').and.callThrough();
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'escape' }));
expect(component.close).toHaveBeenCalledWith('close');
});

});
Loading

0 comments on commit a65b7e5

Please sign in to comment.