Skip to content

Commit

Permalink
Merge branch 'master' into feature/theme-by-config
Browse files Browse the repository at this point in the history
  • Loading branch information
zubairslamdien authored Mar 22, 2023
2 parents 2ae1e63 + c817162 commit df51bcf
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 50 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
14 changes: 14 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"env": {
"browser": false,
"node": true,
"commonjs": false,
"es2020": true
},
"extends": [
"standard"
],
"parserOptions": {
"ecmaVersion": 2020
}
}
55 changes: 55 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Bug Report
description: File a bug report
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: description
attributes:
label: What happened?
description: Please describe the issue
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: Tell us what should have happened
- type: textarea
id: repro-steps
attributes:
label: Steps to reproduce
description: Tell us how to reproduce the issue
validations:
required: true
- type: input
id: aat-version
attributes:
label: Authoring tool version
description: What version of the Adapt authoring tool are you running?
validations:
required: true
- type: input
id: fw-version
attributes:
label: Framework version
description: What version of the Adapt framework are you running?
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on?
multiple: true
options:
- Firefox
- Chrome
- Safari
- Microsoft Edge
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: sh
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Feature request
description: Request a new feature
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to request a new feature in the Adapt authoring tool! The Adapt team will consider all new feature requests, but unfortunately cannot commit to every one.
- type: textarea
id: description
attributes:
label: Feature description
description: Please describe your feature request
validations:
required: true
- type: checkboxes
id: contribute
attributes:
label: Can you work on this feature?
description: If you are able to commit your own time to work on this feature, it will greatly increase the liklihood of it being implemented by the core dev team. Otherwise, it will be triaged and prioritised alongside the core team's current priorities.
options:
- label: I can contribute
25 changes: 25 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[//]: # (Please title your PR according to eslint commit conventions)
[//]: # (See https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-eslint#eslint-convention for details)

[//]: # (Add a link to the original issue)

[//]: # (Delete as appropriate)
### Fix
* A sentence describing each fix

### Update
* A sentence describing each udpate

### New
* A sentence describing each new feature

### Breaking
* A sentence describing each breaking change

[//]: # (List appropriate steps for testing if needed)
### Testing
1. Steps for testing

[//]: # (Mention any other dependencies)


19 changes: 19 additions & 0 deletions .github/workflows/new.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Add to main project

on:
issues:
types:
- opened
pull_request:
types:
- opened

jobs:
add-to-project:
name: Add to main project
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
project-url: https://github.com/orgs/adapt-security/projects/5
github-token: ${{ secrets.PROJECTS_SECRET }}
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
/**
* Application of custom course theme settings
* @namespace coursetheme
*/
export { default } from './lib/CourseThemeModule.js';
export { default } from './lib/CourseThemeModule.js'
102 changes: 54 additions & 48 deletions lib/CourseThemeModule.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import _ from 'lodash';
import AbstractApiModule from 'adapt-authoring-api';
import fs from 'fs/promises';
import _ from 'lodash'
import AbstractApiModule from 'adapt-authoring-api'
import fs from 'fs/promises'
/**
* Module which handles course theming
* @memberof coursetheme
* @extends {AbstractApiModule}
*/
class CourseThemeModule extends AbstractApiModule {
/** @override */
async setValues() {
/** @ignore */ this.root = 'coursethemepresets';
/** @ignore */ this.permissionsScope = 'content';
/** @ignore */ this.schemaName = 'coursethemepreset';
/** @ignore */ this.schemaExtensionName = 'coursethemepreset';
/** @ignore */ this.collectionName = 'coursethemepresets';
/** @ignore */ this.attributeKey = 'themeVariables';
async setValues () {
/** @ignore */ this.root = 'coursethemepresets'
/** @ignore */ this.permissionsScope = 'content'
/** @ignore */ this.schemaName = 'coursethemepreset'
/** @ignore */ this.schemaExtensionName = 'coursethemepreset'
/** @ignore */ this.collectionName = 'coursethemepresets'
/** @ignore */ this.attributeKey = 'themeVariables'

const perms = [`write:${this.permissionsScope}`];
const perms = [`write:${this.permissionsScope}`]

this.useDefaultRouteConfig();
this.useDefaultRouteConfig()
this.routes.push({
route: '/:_id/apply/:courseId',
validate: false,
Expand All @@ -29,19 +29,21 @@ class CourseThemeModule extends AbstractApiModule {
validate: false,
handlers: { post: this.removeHandler() },
permissions: { post: perms }
});
})
}

/** @override */
async init() {
await super.init();
const [framework, content] = await this.app.waitForModule('adaptframework', 'content');
async init () {
await super.init()
const [framework, content] = await this.app.waitForModule('adaptframework', 'content')
/**
* Cached module instance for easy access
* @type {ContentModule}
*/
this.content = content;
framework.preBuildHook.tap(this.writeCustomLess.bind(this));
this.content = content
framework.preBuildHook.tap(this.writeCustomLess.bind(this))
}

/**
* Writes the customStyle and themeVariables attributes to LESS files. themeVariables are reduced into a string of variables, in the format `@key: value;`
* @param {AdaptFrameworkBuild} fwBuild Reference to the current build
Expand All @@ -57,69 +59,73 @@ class CourseThemeModule extends AbstractApiModule {
this.writeFile(fwBuild, '3-themeCustomStyles.less', themeCustomStyle)
]);
}

/**
* Generates a LESS variables string
* @param {object} data The data to process
* @param {string} variablesStr String memo to allow recursion
* @return {string} The processed LESS varaibles string
*/
getVariablesString(data = {}, variablesStr = '') {
getVariablesString (data = {}, variablesStr = '') {
return Object.entries(data).reduce((s, [k, v]) => {
if(_.isObject(v)) return this.getVariablesString(v, s);
return v ? `${s}@${k}: ${v};\n` : s;
}, variablesStr);
if (_.isObject(v)) return this.getVariablesString(v, s)
return v ? `${s}@${k}: ${v};\n` : s
}, variablesStr)
}

/**
* Writes a file to the theme folder
* @param {Object} fwBuild Build data
* @param {String} filename Name of output file
* @param {String} fileContents Contents to be written
* @return {Promise}
*/
async writeFile(fwBuild, filename, fileContents) {
if(_.isEmpty(fileContents)) {
return;
async writeFile (fwBuild, filename, fileContents) {
if (_.isEmpty(fileContents)) {
return
}
try {
const outputDir = `${fwBuild.dir}/src/theme/${fwBuild.courseData.config.data._theme}/less/zzzzz`;
await fs.mkdir(outputDir, { recursive: true });
await fs.writeFile(`${outputDir}/${filename}`, fileContents);
} catch(e) {
this.log('error', `failed to write ${filename}, ${e.message}`);
const outputDir = `${fwBuild.dir}/src/theme/${fwBuild.courseData.config.data._theme}/less/zzzzz`
await fs.mkdir(outputDir, { recursive: true })
await fs.writeFile(`${outputDir}/${filename}`, fileContents)
} catch (e) {
this.log('error', `failed to write ${filename}, ${e.message}`)
}
}

/**
* Handles applying theme settings
* @return {Function} Handler function
*/
applyHandler() {
applyHandler () {
return async (req, res, next) => {
try {
const { _id, courseId } = req.apiData.query;
const [{ properties: presetProps }] = await this.find({ _id });
await this.content.update({ _id: courseId }, { [this.attributeKey]: presetProps });
res.sendStatus(204);
} catch(e) {
return next(e);
const { _id, courseId } = req.apiData.query
const [{ properties: presetProps }] = await this.find({ _id })
await this.content.update({ _id: courseId }, { [this.attributeKey]: presetProps })
res.sendStatus(204)
} catch (e) {
return next(e)
}
};
}
}

/**
* Handles removing theme settings
* @return {Function} Handler function
*/
removeHandler() {
removeHandler () {
return async (req, res, next) => {
try {
const { _id, courseId } = req.apiData.query;
const [{ properties: presetProps }] = await this.find({ _id });
const [{ themeVariables: existingProps }] = await this.content.find({ _id: courseId });
await this.content.update({ _id: courseId }, { [this.attributeKey]: _.pickBy(existingProps, (v,k) => v !== presetProps[k]) });
res.sendStatus(204);
} catch(e) {
return next(e);
const { _id, courseId } = req.apiData.query
const [{ properties: presetProps }] = await this.find({ _id })
const [{ themeVariables: existingProps }] = await this.content.find({ _id: courseId })
await this.content.update({ _id: courseId }, { [this.attributeKey]: _.pickBy(existingProps, (v, k) => v !== presetProps[k]) })
res.sendStatus(204)
} catch (e) {
return next(e)
}
};
}
}

/**
Expand Down Expand Up @@ -203,4 +209,4 @@ class CourseThemeModule extends AbstractApiModule {
}
}

export default CourseThemeModule;
export default CourseThemeModule;
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@
"dependencies": {
"adapt-authoring-api": "github:adapt-security/adapt-authoring-api",
"lodash": "^4.17.21"
},
"devDependencies": {
"eslint": "^8.36.0",
"standard": "^17.0.0"
}
}

0 comments on commit df51bcf

Please sign in to comment.