Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions demos/globe/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
66 changes: 66 additions & 0 deletions demos/globe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
This skeleton has been developed as a proof of concept using our most commmon environment.

## Key Files

#### Javascript and CSS

* `src/feature/index.js` - Frontend javascript code for developing the UI of your custom feature. All logic related to rendering your custom feature's UI should go here.

* `scss/_feature.scss` - for writing CSS styling rules to be applied to your custom feature UI.

#### JSON
* `feature.json` - REQUIRED. This file is for creating the JSON definition of your custom feature to be stored inside of Learnosity. (This JSON definition is your own definition for your own feature, similar to the JSON defition for out of the box Learnosity questions like a multiple choice quesiton.):

https://reference.learnosity.com/questions-api/questiontypes#mcq


* `question_editor_init_options.json` - OPTIONAL. Required only if you intend for new instances of your custom feature to be authorable via the Learnosity question editor UI. Please see our help article on How to Create A Custom Question Authoring Tile for more detail:

https://help.learnosity.com/hc/en-us/articles/360000755098-Authoring-Custom-Questions-Features#how-to-create-custom-question--feature-custom-tile-items

### html

* `authoring_custom_layout.html` - If you intend to make your custom feature available to authors, this file is for defining the question editor UI layout and appearance for authors who create new instances of your custom feature.

This is similar to the question editor html layout for out of the box Learnosity features, like the calculator feature:
https://reference.learnosity.com/products/questioneditor-api/downloadeditorlayout.php?widget=calculator


#### php

These php files are development scafolding files and their purpose is to emulate the Learnosity production environment during development so as to model how your custom question will behave as a first class citizen across the Learnosity ecosystem from Authoring to Assessmnet to Analytics, just like any out of the box Learnosity question type.

You can therefore think of these files as a "development-server" whose language happens to be php. You don't need to make any changes to these files unless you want to. They automatically injest the JSON you create in the above 2 files.

* `assessment.php` - For modeling how your custom question will behave in a Learnosity Assessment.
Available at `localhost:12345/assessmnet.php`.

* `authoring.php`- If you intend to make your custom question available to authors, navigate to this file to model how your custom question will behave on the Author Site or standalone Author API.
Available at `localhost:12345/authoring.php`



## Available Scripts
* Start the localhost server to start developing your custom question
```
yarn dev
```
* Bundle the production ready code of your custom question.
Once your custom question is ready, run this script and host the resulant `feature.js`, `feature.css` and `authoring_custom_layout.html` files on your server.

The paths to these files can be easily managed and aliased via the custom questions module on our self-service site, console.learnosity.com:

https://help.learnosity.com/hc/en-us/articles/360000756198-Console-Overview#custom-questions


```
yarn prod
```
* Test your scorer's behavior in the server side. Update question/response in `debugServerScorer.js` to test
```
yarn debug-server-scorer
```
* run unit tests for your custom question
```
yarn unit-tests
```
70 changes: 70 additions & 0 deletions demos/globe/assessment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
include_once '../config.php';
$featureJson = file_get_contents('./feature.json');
$featureId = "custom-$sessionId";
$request = '{
"state": "' . $state . '",
"session_id": "' . $sessionId . '",
"features": [
'.$featureJson.'
]
}';
$requestData = json_decode($request, true);
// add the feature id to the request data after it has been transformed to a php array.
$requestData['features'][0]['feature_id'] = $featureId;

$signedRequest = signAssessmentRequest($requestData);

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom Feature Skeleton</title>
<script src="//questions.learnosity.com"></script>
<style>
<?php echo(file_get_contents('../sharedStyle.css')); ?>
</style>
</head>
<body>
<div class="client-question-info">
Feature ID: <code><?php echo $featureId; ?></code>
</div>
<span class="learnosity-feature feature-<?php echo $featureId; ?>"></span>
<div class="client-save-wrapper client-hidden">
<span class="learnosity-save-button"></span>
</div>
<div id="redirect_response">
Click here to view your custom feature in
<button type="button" class="client-btn client-hidden" data-action="resume">Resume</button>
<button type="button" class="client-btn" data-action="review">Review</button> mode.
</div>
<div class="client-request-json">
<div><b>Request init options</b></div>
<textarea readonly></textarea>
</div>

<script>
window.activity = <?php echo $signedRequest; ?>;

window.questionsApp = LearnosityApp.init(activity, {
readyListener() {
console.log('questionApp.ready');
},
errorListener(e) {
console.error(e);
},
saveSuccess(responseIds) {
console.log('save success', responseIds);

// for sharedScript.js to display resume/review options
if (window.__onSaveSuccess) {
window.__onSaveSuccess(responseIds);
}
},
});

<?php echo file_get_contents('../sharedAssessmentScript.js'); ?>
</script>
</body>
</html>
66 changes: 66 additions & 0 deletions demos/globe/authoring.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
include_once '../config.php';

$init_options = file_get_contents('./question_editor_init_options.json');

$request = '
{
"config": {
"widget_templates": {
"widget_types": {
"default": "features",
"show": true
}
},
"dependencies": {
"question_editor_api": {
"init_options": '.$init_options.'
}
}
}
}
';
$signedRequest = signAuthoringRequest(json_decode($request, true));

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Author API - Skeleton</title>
<script src="//authorapi.learnosity.com"></script>
<style>
<?php echo(file_get_contents('../sharedStyle.css')); ?>
</style>
</head>
<body>
<div id="learnosity-author"></div>
<div>
<div class="client-request-json" data-type="initOptions">
<div><b>Request init options</b></div>
<textarea readonly></textarea>
</div>
<div class="client-request-json" data-type="htmlLayout">
<div><b>Custom Feature HTML Layout</b></div>
<textarea readonly></textarea>
</div>
</div>

<script>
window.activity = <?php echo $signedRequest; ?>;

window.authorApp = LearnosityAuthor.init(activity, {
readyListener() {
console.log('ready');
},
errorListener(e) {
console.error(e);
},
});

// Display the current request init options & html layout
document.querySelector('[data-type="initOptions"] > textarea').value = `${JSON.stringify(window.activity, null, 2)}`;
document.querySelector('[data-type="htmlLayout"] > textarea').value = `<?php echo (file_get_contents('dist/authoring_custom_layout.html')) ?>`;
</script>
</body>
</html>
21 changes: 21 additions & 0 deletions demos/globe/authoring_custom_layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="lrn-lrn-qe-edit-form">
<h4 data-lrn-qe-heading>Globe Appearance Options:</h4>
<div class="lrn-qe-row-flex" data-lrn-qe-layout-wrapper>
<div class="lrn-qe-col-xs-12 lrn-qe-col-sm-6">
<!-- UI label and input for the "land_texture" property in your editor schema JSON -->
<span data-lrn-qe-input="land_texture" class="lrn-qe-inline-block"></span>
<span data-lrn-qe-label="land_texture" class="lrn-qe-inline-block"></span>
</div>
<div class="lrn-qe-col-xs-12 lrn-qe-col-sm-6">
<!-- UI label and input for the "show_countries" property in your editor schema JSON -->
<span data-lrn-qe-input="show_countries" class="lrn-qe-inline-block"></span>
<span data-lrn-qe-label="show_countries" class="lrn-qe-inline-block"></span>
</div>
<div class="lrn-qe-col-xs-12 lrn-qe-col-sm-6">

<!-- UI label and input for the "show_lines" property in your editor schema JSON -->
<span data-lrn-qe-input="show_lines" class="lrn-qe-inline-block"></span>
<span data-lrn-qe-label="show_lines" class="lrn-qe-inline-block"></span>
</div>
</div>
</div>
4 changes: 4 additions & 0 deletions demos/globe/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file is meant for Jest test suite only
module.exports = {
presets: ['@babel/preset-env']
};
9 changes: 9 additions & 0 deletions demos/globe/feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "customfeature",
"name": "globe",
"land_texture": true,
"show_countries": true,
"show_lines": true,
"js": "/dist/feature.js",
"css": "/dist/feature.css"
}
14 changes: 14 additions & 0 deletions demos/globe/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const path = require('path');

module.exports = {
testEnvironment: 'jsdom',
setupFiles: [
'<rootDir>/tests/units/jest.setup.js',
],
modulePaths: [
path.resolve(__dirname, 'src'),
],
testMatch: [
'<rootDir>/tests/units/**/*.+(spec|test).+(ts|tsx|js)',
]
};
37 changes: 37 additions & 0 deletions demos/globe/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"devDependencies": {
"@babel/core": "^7.15.8",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-object-rest-spread": "^7.15.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-react-jsx": "^7.14.9",
"@babel/preset-env": "^7.15.8",
"@babel/preset-react": "^7.14.5",
"babel-jest": "^27.5.1",
"babel-loader": "^8.2.3",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.4.0",
"event-emitter": "^0.3.5",
"jest": "^27.5.1",
"mini-css-extract-plugin": "^2.4.2",
"sass": "^1.43.3",
"sass-loader": "^12.2.0",
"sinon": "^13.0.1",
"style-loader": "^3.3.0",
"webpack": "^5.59.1",
"webpack-bundle-analyzer": "^4.9.1",
"webpack-cli": "^4.9.1"
},
"scripts": {
"dev": "yarn install && php -S localhost:12345 & webpack watch --mode development --devtool eval-source-map",
"prod": "yarn install && webpack --mode production",
"debug-server-scorer": "node ./debugServerScorer.js",
"unit-tests": "jest",
"unit-tests-watch": "jest --watch"
},
"dependencies": {
"globe.gl": "^2.29.2",
"topojson-client": "^3.1.0",
"world-atlas": "^2.0.2"
}
}
38 changes: 38 additions & 0 deletions demos/globe/question_editor_init_options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"custom_feature_types": [
{
"custom_type": "globe",
"name": "Custom 3D Globe Feature",
"js": "/dist/feature.js",
"css": "/dist/feature.css",
"version": "v0.0.1",
"editor_layout": "/dist/authoring_custom_layout.html",
"editor_schema": {
"hidden_question": false,
"properties": {
"land_texture": {
"name": "Use natural land texture",
"description": "Whether to use a natural land texture for the globe or not",
"type": "boolean",
"required": true,
"default": true
},
"show_countries": {
"name": "Show countries and country names",
"description": "If enabled, will show countries and their names with a hover tooltip on the globe for the learner",
"type": "boolean",
"required": true,
"default": true
},
"show_lines": {
"name": "Show latitude and longitude lines",
"description": "If enabled, will show latitude and longitude lines on the globe for the learner",
"type": "boolean",
"required": true,
"default": false
}
}
}
}
]
}
42 changes: 42 additions & 0 deletions demos/globe/scss/_feature.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*********************************************************
Write any CSS styling rules for your custom question HERE.
There is no need to create your own file called question.css
Based on the CSS you write here, the question.css file will be generated
automatically for you by webpack when you build the production version of your question by running yarn-prod.
************************************************************/

.flex-column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.globe-wrapper {
canvas {
cursor: grab;
}
.country-tooltip {
background-color: black;
padding: 1rem;
border-radius: 1rem;
}
}

.globe-toggle-btn {
outline: none;
border: none;
padding: .6em 1.2em;
background-color: #eaeaea;
color: #333;
display: flex;
justify-content: center;
align-items: center;
gap: 0.5em;
}
.globe-toggle-btn::before {
content: "\1F310";
font-size: 2em;
}


1 change: 1 addition & 0 deletions demos/globe/scss/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$prefix: lrn-custom-globe-feature-;
4 changes: 4 additions & 0 deletions demos/globe/scss/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "variables";
.lrn-custom-globe-feature {
@import "feature";
}
9 changes: 9 additions & 0 deletions demos/globe/src/feature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Feature from './feature/index';
import '../scss/main.scss';

/*global LearnosityAmd*/
LearnosityAmd.define([], function () {
return {
Feature
};
});
Loading