Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

Contains QuestionSet Editor library components powered by angular. These components are designed to be used in the sunbirdEd portal and coKreat reference web portal to drive reusability, maintainability hence reducing the redundant development effort significantly.

Getting Started

For help getting started with a new Angular app, check out the Angular CLI. For existing apps, follow these steps to begin using .

Step 1: Install the packages

npm i @project-sunbird/sunbird-collection-editor-v9 --save
npm i common-form-elements-web-v9 --save
npm i ng2-semantic-ui-v9 --save
npm i ngx-infinite-scroll --save
npm i lodash-es --save
npm i jquery.fancytree --save
npm i angular2-uuid --save
npm i @project-sunbird/client-services --save
npm i export-to-csv --save
npm i moment --save
npm i @project-sunbird/ckeditor-build-classic --save
npm i @project-sunbird/sunbird-pdf-player-v9 --save
npm i @project-sunbird/sunbird-epub-player-v9 --save
npm i @project-sunbird/sunbird-video-player-v9 --save
npm i @project-sunbird/sunbird-quml-player-v9 --save
npm i ngx-bootstrap@6.0.0 --save
npm i ng2-cache-service --save
npm i fine-uploader --save
npm i ngx-chips@2.2.0 --save
npm i epubjs --save
npm i videojs-contrib-quality-levels --save
npm i videojs-http-source-selector --save
npm i jquery --save
npm i express-http-proxy --save
npm i mathjax-full --save
npm i svg2img --save
npm i font-awesome --save
npm i @project-sunbird/sb-styles

Note: As QuestionSet Editor library is build with angular version 9, we are using ngx-bootstrap@6.0.0 and ngx-chips@2.2.0 which are the compatible versions.
For more reference Check compatibility document for ng-bootstrap here

Step 2: Add editor-cursor-implementation.service

Remember EditorCursor is to be imported like this

import { EditorCursor } from '@project-sunbird/sunbird-collection-editor-v9';

  • Create a data.ts file which contains the questionSetEditorConfig Refer: data.ts

Note: questionSetEditorConfigin data.ts contains the mock config used in component to send it as input to QuestionSet Editor. We need only questionSetEditorConfig

Step 3: Include the styles, scripts and assets in angular.json

{
  ...
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      ...
      ...
      "aot": false,
      "assets": [
        ...
        ...
              {
                "glob": "**/*",
                "input": "node_modules/@project-sunbird/sunbird-pdf-player-v9/lib/assets/",
                "output": "/assets/"
              },
              {
                "glob": "**/*",
                "input": "node_modules/@project-sunbird/sunbird-video-player-v9/lib/assets/",
                "output": "/assets/"
              },
              {
                "glob": "**/*",
                "input": "node_modules/@project-sunbird/sunbird-collection-editor-v9/lib/assets",
                "output": "/assets/"
              },
              {
                "glob": "**/*",
                "input": "node_modules/@project-sunbird/sunbird-quml-player-v9/lib/assets/",
                "output": "/assets/"
              }
      ],
      "styles": [
        ...
        "src/assets/quml-styles/quml-carousel.css",
        "node_modules/@project-sunbird/sb-styles/assets/_styles.scss",
        "src/assets/lib/semantic/semantic.min.css",
        "src/assets/styles/styles.scss",
        "node_modules/font-awesome/css/font-awesome.css",
        "node_modules/video.js/dist/video-js.min.css",
        "node_modules/@project-sunbird/sunbird-video-player-v9/lib/assets/videojs.markers.min.css",
        "node_modules/videojs-http-source-selector/dist/videojs-http-source-selector.css"
      ],
      "scripts": [
        ...
        "node_modules/epubjs/dist/epub.js",
        "src/assets/libs/iziToast/iziToast.min.js",
        "node_modules/jquery/dist/jquery.min.js",
        "node_modules/jquery.fancytree/dist/jquery.fancytree-all-deps.min.js",
        "src/assets/lib/dimmer.min.js",
        "src/assets/lib/transition.min.js",
        "src/assets/lib/modal.min.js",
        "src/assets/lib/semantic-ui-tree-picker.js",
        "node_modules/@project-sunbird/client-services/index.js",
        "node_modules/video.js/dist/video.js",
        "node_modules/@project-sunbird/sunbird-video-player-v9/lib/assets/videojs-markers.js",
        "node_modules/videojs-contrib-quality-levels/dist/videojs-contrib-quality-levels.min.js",
        "node_modules/videojs-http-source-selector/dist/videojs-http-source-selector.min.js"
      ]
    }
  }
  ...
  ...
}

Step 4: Change in package.json

{
    ...
    ...
    "scripts": {
      "ng": "ng",
      "start": "ng serve --proxy-config proxy.conf.json",
      ...
      ...
    },
    ...
    "dependencies": {
    ...
    ...
    },
    "devDependencies": {
    ...
    ...
    }
  }
  

Step 5: Import the modules and components

Import the required modules such as below:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CollectionEditorLibraryModule, EditorCursor } from '@project-sunbird/sunbird-collection-editor-v9';
import { RouterModule } from '@angular/router';
import { QuestionCursor } from '@project-sunbird/sunbird-quml-player-v9';
import { EditorCursorImplementationService } from './editor-cursor-implementation.service';

  @NgModule({
   ...

   imports: [ 
      CollectionEditorLibraryModule,
      BrowserAnimationsModule,
      RouterModule.forRoot([])
      ],
   providers: [
    { provide: QuestionCursor, useExisting: EditorCursorImplementationService },
    { provide: EditorCursor, useExisting: EditorCursorImplementationService }
   ]

   ...
  })

 export class AppModule { }

Add the questionset editor config in component

...
import { questionSetEditorConfig } from './data';
@Component({
  ...
  ...
  ...
})

export class AppComponent {
  ...
  public editorConfig: any = questionSetEditorConfig;
}

Step 6: Send input to render QuestionSet Editor

<lib-editor [editorConfig]="editorConfig"></lib-editor>

Step 7: Set the auth token and questionset identifier

From the root directory - go to server.js file

Update the host variable to which env your pointing. example if you are pointing sunbird dev instance update variable like below
const BASE_URL = 'dev.sunbirded.org'
const API_AUTH_TOKEN = 'XXXX'
const PORTAL_COOKIES= 'YYYY'

Note: API_AUTH_TOKEN and PORTAL_COOKIES should be of same user with which you are creating the questionset in portal. PORTAL_COOKIES you can get from the network tab in any XHR API call header

If you are pointing to sunbird dev (dev.sunbirded.org), create a Question Set in sunbird dev, copy the questionset_id from the browser url and set the do_id of Question Set in data.ts file

export const questionSetEditorConfig = {
  context: {
    ...
    ...
    ...
    },
    identifier: 'do_id', // identifier of questionset created in sunbird dev
    ...
    ...
  };

Setp 8: Run the application

From the root directory - Start the server (Open terminal in root folder and start the application) as:

  npm run start

The app will launch at http://localhost:4200

Run Node server to proxy the APIs (Open another terminal in root folder and run the server.js ) as:

  nodemon server.js

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Questionset Editor Contribution Guide

Repo Setup

Fork the project

  https://github.com/Sunbird-Ed/sunbird-collection-editor.git

Go to the root directory

  cd sunbird-collection-editor

Install dependencies

  npm install

Build the library

  npm run build-lib

It will create a /dist/collection-editor-library folder at the root directory and also copy all the required assets.

Starting up the Sample application

A sample angular application is included as part of this repo

In another terminal tab -

From the root directory - Start the server

  npm run start

The demo app will launch at http://localhost:4200

Set the auth token and questionset identifier

From the root directory - go to server.js file

Update the host variable to which env your pointing. example if you are pointing sunbird dev instance update variable like below
const BASE_URL = 'dev.sunbirded.org'
const API_AUTH_TOKEN = 'XXXX'
const PORTAL_COOKIES= 'YYYY'

Note: API_AUTH_TOKEN and PORTAL_COOKIES should be of same user with which you are creating the questionset in portal. PORTAL_COOKIES you can get from the network tab in any XHR API call header

If you are pointing to sunbird dev (dev.sunbirded.org), create a Question Set in sunbird dev and set the do_id of Question Set in data.ts file

export const questionSetEditorConfig = {
  context: {
    ...
    ...
    ...
    },
    identifier: 'do_id', // identifier of questionset created in sunbird dev
    ...
    ...
  };

Run Node server to proxy the APIs (Open one more terminal in root folder and run the server.js ) as:

  nodemon server.js

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Configuration Documentation - QuestionSet Editor

Questionset Editor is an angular library built with Angular version 9, and it exports some modules and components.

Component: editor

This is the main editor Component that accepts some configuration (here editorConfig) based on it loads the editor.  

Let's deep dive into the player input configuration:

  export interface questionSetEditorConfig = {
    context: Context;
    config: Config;
  }
  1. Context - Required

This Required property from the questionSetEditorConfig provides the context to the questionset editor mostly in terms of the telemetry.

Along with this it also provides the channel level config, if available.

export interface Context {
    programId?: string;
    contributionOrgId?: string;
    user: User;
    identifier?: string;
    mode?: string;
    authToken?: string;
    sid: string;
    did: string;
    uid: string;
    channel: string;
    pdata: Pdata;
    contextRollup: ContextRollup;
    tags: string[];
    cdata?: Cdata[];
    timeDiff?: number;
    objectRollup?: ObjectRollup;
    host?: string;
    endpoint?: string;
    userData?: {
        firstName: string;
        lastName: string;
    };
    env: string;
    defaultLicense?: any;
    board?: any;
    medium?: any;
    gradeLevel?: any;
    subject?: any;
    topic?: any;
    framework: string;
    cloudStorageUrls?: string[];
    additionalCategories?: any[];
    labels?: any;
    actor?: any;
    channelData?: any;
    correctionComments?: any;
    sourcingResourceStatus?: string;
    sourcingResourceStatusClass?: string;
    collectionIdentifier?: string;
    unitIdentifier?: string;
    collectionObjectType?: string;
    collectionPrimaryCategory?: string;
    targetFWIds?: string[];
}

Description of the properties for the context

Property

Required

Description

programId

false

program id in which questionset is created.

contributionOrgId

false

Organisation id of the contributor.

user

true

User object which contains users id, fullName, lastName, orgIds.

identifier

false

identifier of questionset

authToken

false

Authentication token

sid

true

session id of the requestor stamped by portal

did

true

uuid of the device

channel

true

Channel which has produced the event

pdata

true

Producer of the event

contextRollup

true

Context Rollups upto level 4

tags

true

Encrypted dimension tags passed by respective channels

cdata

false

Correlation data

timeDiff

false

Last player duration

objectRollup

false

Object Rollup up to level 4

host

false

Host URL

endpoint

false

Telemetry API endpoint

userData.firstName

false

User's first name

userData.lastName

false

User's last name

env

true

type of editor , in case of questionset editor its questionset_editor

defaultLicense

false

default license of questionset

board

false

medium

false

gradeLevel

false

subject

false

topic

false

framework

true

Organisation framework id

cloudStorageUrls

false

Array of cloud storage urls

additionalCategories

false

Array of objects of additional categories

labels

false

Additional labels to be used in editor

2. Config - Required
This Required property from the questionsetEditorConfig provides the configuration for the questionset editor to enable/disable some functionalities.  

config: {
    mode: 'string', //ex: 'edit'/'review'/'read'/'sourcingReview'/'orgReview'
    editableFields: {
      sourcingreview: string[],
      orgreview: string[],
      review: string[],
    },
    maxDepth: number, //ex: 1
    objectType: 'QuestionSet',
    primaryCategory: 'Practice Question Set',
    isRoot: boolean, //ex: true
    iconClass: 'string', //ex: 'fa fa-book'
    showAddCollaborator: boolean,
    hideSubmitForReviewBtn: boolean,
    children: {
      Question: [
        'Multiple Choice Question',
        'Subjective Question'
      ]
    },
    hierarchy: {
      level1: {
        name: '', //ex: 'Section'
        type: '', //ex: 'Unit'
        mimeType: 'application/vnd.sunbird.questionset',
        primaryCategory: 'string', //ex: 'Practice Question Set'
        iconClass: 'string' //ex: 'fa fa-folder-o',
        children: {}
      },
      level2: {
        name: 'string', //ex: 'Sub Section'
        ...
        ...
      },
      level3: {
      ...
      ...
      }
    },
    contentPolicyUrl: 'string' //ex: '/term-of-use.html' 
  }

Description of the properties for the config:

  • mode:

Property

Default Value

Required

Description

mode

true

Defines the mode in editor is to be loaded loaded.

mode: edit (all the fields will be enable to edit for questionset creator)

mode: sourcingReview (all those fields will be enabled whatever will be present in editableFields.sourcingreview)

Note: In above case editableFields.sourcingreview: ['instructions'] so only instruction field is enabled for sourcing reviewer while reviewing the questionset.

  • editableFields:

Property

Default Value

Required

Description

editableFields

{

sourcingreview: [], orgreview: [], review: [],

}

false

Defines which fields is to be enabled when mode of questionset is

review / sourcingReview / orgReview

Its object for different types of mode based on which some fields get enabled.

editableFields: {
    "sourcingreview": [
        "instructions"
    ],
    "orgreview": [
        "name",
        "instructions",
        "learningOutcome"
    ],
    "review": [
        "name",
        "description"
    ]
}

In sourcingreview, we have “instructions”, so when the mode of editor is sourcingReview in that case instruction will be only enabled.

  • enableQuestionCreation:

Property

Default Value

Required

Description

enableQuestionCreation

true

true

allows or disallow creation of question in questionset.

When enableQuestionCreation: false “Create New” button gets disabled

-------------------------------------------------------------------

Property

Default Value

Required

Description

mode

true

Defines the mode in editor is to be loaded loaded.

editableFields

{

sourcingreview: [], orgreview: [], review: [],

}

false

Defines which fields fields to be enabled for reviewer when questionset is sent for review.

maxDepth

0

true

Defines the depth to which the questionset is to be created. If the depth is 1, hierarchy should have level1 described.

objectType

'QuestionSet'

true

Defines the object type

primaryCategory

'Practice Question Set'

true

Defines the primary category

isRoot

true

true

Defines the node is root node.

iconClass

'fa fa-book'

true

Defines the icon of root node

showAddCollaborator

false

false

This is to enable/disable the functionality of add collaborator in questionset. If it is true add collobrorator button will be enabled and created can add the collolaborator to collaborate in questionset.

hideSubmitForReviewBtn

true

false

children

{ Question: [ 'Multiple Choice Question', 'Subjective Question' ] }

false

If maxdepth is 0 this children inside the root node defines the template of questions.

hierarchy

{}

false

If maxdepth is > 0 then hierarchy should have definiton of the levels.

questionSet. maxQuestionsLimit

null

false

It defines the limit of total number of question to be created inside questionset.

  • No labels