@caspingus/lt
Version:
A utility library of helpers and tools for working with Learnosity APIs.
173 lines (153 loc) • 5.32 kB
JavaScript
import * as app from '../../../core/app';
import logger from '../../../../utils/logger';
/**
* Extensions add specific functionality to Learnosity APIs.
* They rely on modules within LT being available.
*
* --
*
* Adds the ability for authors to add more native column tabs
* than is currently possible today in the Layout area.
*
* <p><img src="https://raw.githubusercontent.com/michaelsharman/LT/main/src/assets/images/nativetabs.png" alt="" width="660"></p>
* @module Extensions/Authoring/nativeTabs
*/
const state = {
columns: {
numTabsLeft: 2,
numTabsRight: 2,
},
logPrefix: 'LT Dynamic Content: ',
renderedCss: false,
};
/**
* Extension constructor.
* @example
* import { LT } from '@caspingus/lt/src/authoring/index';
*
* LT.init(authorApp); // Set up LT with the Author API application instance variable
* LT.extensions.nativeTabs.run();
* @since 2.25.0
*/
export function run() {
state.renderedCss || injectCSS();
app.appInstance().on('navigate', checkForSetup);
app.appInstance().on('itemsettings:applied', saveTabsToItem);
function checkForSetup() {
setTimeout(() => {
if (['items/:reference/settings/:tab', 'items/:reference/settings', undefined].includes(app.appInstance().getLocation().route)) {
const lastElement = app.appInstance().getLocation().location.split('/').pop();
if (['layout', 'settings'].includes(lastElement)) {
setup();
}
}
}, 2050);
}
}
/**
* Injects an input field to choose number of tabs.
* @since 2.25.0
* @ignore
*/
function setup() {
const elTabsWrapper1 = document.querySelector('[data-authorapi-selector="lrn-author-tabs-col1"]');
const elTabsWrapper2 = document.querySelector('[data-authorapi-selector="lrn-author-tabs-col2"]');
const elNumTabs1 = document.getElementById('lt__nativeTabs-1');
const elNumTabs2 = document.getElementById('lt__nativeTabs-2');
const elSettingsApply = document.querySelector('[data-authorapi-selector="lrn-author-apply-settings"]');
if (elSettingsApply) {
if (!elNumTabs1 && elTabsWrapper1) {
elTabsWrapper1.querySelector('.lrn-author-layout-content').insertAdjacentHTML('beforeend', getNumTabsUI(1));
}
if (!elNumTabs2 && elTabsWrapper2) {
elTabsWrapper2.querySelector('.lrn-author-layout-content').insertAdjacentHTML('beforeend', getNumTabsUI(2));
}
setNumColumnsState();
elSettingsApply.addEventListener('click', saveTabsToItem);
} else {
logger.warn(`${state.logPrefix}Settings apply button not found`);
}
function getNumTabsUI(num) {
return `
<label class="lrn-author-checkbox-label" for="lt__nativeTabs-${num}">Number of tabs</label>
<div class="lrn-form-group">
<input id="lt__nativeTabs-${num}" type="number" min="2" max="5" value="2" class="lrn-form-control lt__width-sm">
</div>
`;
}
}
/**
* Saves tab layout to item JSON
* @since 2.25.0
* @ignore
*/
function saveTabsToItem() {
const itemJson = app.appInstance().getItem();
if (state.columns.numTabsLeft > 2) {
setTimeout(() => {
itemJson.item.definition = {
regions: {
regions: {
regions: [
{
label: 'Tab 1',
type: 'tab',
},
{
label: 'Tab 2',
type: 'tab',
},
{
label: 'Tab 3',
type: 'tab',
},
],
},
},
};
}, 500);
}
}
/**
* Saves the UI number of tabs to internal state
* so we can use it once the Apply button is clicked.
* @since 2.25.0
* @ignore
*/
function setNumColumnsState() {
const elNumTabs1 = document.getElementById('lt__nativeTabs-1');
const elNumTabs2 = document.getElementById('lt__nativeTabs-2');
elNumTabs1.addEventListener('change', () => {
state.columns.numTabsLeft = elNumTabs1.value;
});
elNumTabs2.addEventListener('change', () => {
state.columns.numTabsRight = elNumTabs2.value;
});
}
/**
* Injects the necessary CSS to the header
* @since 2.25.0
* @ignore
*/
function injectCSS() {
const elStyle = document.createElement('style');
const css = `
/* Learnosity native tab styles */
.lrn .lrn-author-ui,
.lrn.lrn-author {
.lrn-author-api-react-container .lrn-author-item-settings .lrn-author-layout-settings .lrn-author-layout-tab .lrn-author-layout-content,
.lrn-author-api-react-container .lrn-author-activity-labels .lrn-author-layout-settings .lrn-author-layout-tab .lrn-author-layout-content {
padding: 9px;
}
.lrn-form-control.lt__width-sm {
width: 100px;
}
.lrn-author-checkbox-label {
padding-bottom: .5714285714em;
}
}
`;
elStyle.textContent = css;
document.head.append(elStyle);
state.renderedCss = true;
}