Skip to content

Commit

Permalink
New: Add _enableFilters property (fixes #115) (#116)
Browse files Browse the repository at this point in the history
* Schemas and documentation

* Rework resourcesHasMultipleTypes and move to the controller

* Move filter button column count logic from JSX to JS

* Rework setupFilters for conciseness

* Add enableFilters check, rename property

* Use nullish operator for enableFilters

* Remove enableFilters from content objects schema

* Refactor resourcesHasType, remove from JSX

* Rework resourcesForceDownload and remove from JSX

* Remove _enableFilters default from initResources

* Remove shallow clone of configuredTypes

Co-authored-by: Oliver Foster <[email protected]>
  • Loading branch information
swashbuck and oliverfoster authored May 21, 2024
1 parent ac33cd7 commit 54c3461
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 45 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ With the [Adapt CLI](https://github.com/adaptlearning/adapt-cli) installed, run
<div float align=right><a href="#top">Back to Top</a></div>

## Settings
The attributes listed below are used in *course.json* to configure **Resources**, and are properly formatted as JSON in [*example.json*](https://github.com/adaptlearning/adapt-contrib-resources/blob/master/example.json). Visit the [**Resources** wiki](https://github.com/adaptlearning/adapt-contrib-resources/wiki) for more information about how they appear in the [authoring tool](https://github.com/adaptlearning/adapt_authoring/wiki).

The attributes listed below are used in *course.json* to configure **Resources**, and are properly formatted as JSON in [*example.json*](https://github.com/adaptlearning/adapt-contrib-resources/blob/master/example.json). Some attributes can also be overridden for each content object in *contentObjects.json* (see [*example.json*](https://github.com/adaptlearning/adapt-contrib-resources/blob/master/example.json)).

Visit the [**Resources** wiki](https://github.com/adaptlearning/adapt-contrib-resources/wiki) for more information about how they appear in the [authoring tool](https://github.com/adaptlearning/adapt_authoring/wiki).

**\_resources** (object): The Resources object that contains values for **title**, **description**, **\_filterButtons**, **\_filterAria**, and **\_resourcesItems**.

Expand All @@ -44,6 +47,8 @@ The attributes listed below are used in *course.json* to configure **Resources**
>**instruction** (string): The instruction text for the resources which displays at the top of the resources drawer.
>**\_enableFilters** (boolean): Turns the filter buttons on and off. Acceptable values are `true` and `false`. Defaults to `true`. Note that the filter buttons will be automatically disabled if all `_resourcesItems` items have the same `_type` value.
>**\_filterButtons** (object): This attribute group maintains the labels for the four buttons that filter resources by type. It contains values for **all**, **document**, **media**, and **link**.
>>**all** (string): This text appears on the button that returns all **\_resourcesItems**.
Expand Down Expand Up @@ -91,4 +96,4 @@ No known limitations.
**Author / maintainer:** Adapt Core Team with [contributors](https://github.com/adaptlearning/adapt-contrib-resources/graphs/contributors)<br>
**Accessibility support:** WAI AA<br>
**RTL support:** Yes<br>
**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, IE11, Safari 12+13 for macOS/iOS/iPadOS, Opera<br>
**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, Safari for macOS/iOS/iPadOS, Opera<br>
1 change: 1 addition & 0 deletions example.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"displayTitle": "",
"body": "",
"instruction": "",
"_enableFilters": true,
"_filterButtons": {
"all": "All",
"document": "PDF",
Expand Down
5 changes: 4 additions & 1 deletion js/ResourcesView.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export default class ResourcesView extends Backbone.View {
...this,
model: this.model.toJSON(),
resources: this.model.get('_resources'),
resourceTypes: this.model.get('_resourceTypes')
resourceTypes: this.model.get('_resourceTypes'),
_showFilters: this.model.get('_showFilters'),
_filterColumnCount: this.model.get('_filterColumnCount'),
_canDownload: this.model.get('_canDownload')
};
ReactDOM.render(<templates.resources {...data} />, this.el);

Expand Down
33 changes: 31 additions & 2 deletions js/adapt-contrib-resources.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Adapt from 'core/js/adapt';
import drawer from 'core/js/drawer';
import device from 'core/js/device';
import ResourcesView from './ResourcesView';

class Resources extends Backbone.Controller {
Expand Down Expand Up @@ -48,15 +49,43 @@ class Resources extends Backbone.Controller {
model.set('_resources', resources);

this.setupTypes(model, resourcesData);
this.setupFilters(model, resources);
this.setupCanDownload(model);

drawer.triggerCustomView(new ResourcesView({ model }).$el);
});
}

setupTypes(model, resourcesData) {
const configuredTypes = Object.keys(resourcesData._filterButtons).filter(type => type !== 'all');
const allTypes = [ 'all', ...configuredTypes ];
model.set('_resourceTypes', allTypes);
const typesWithItems = configuredTypes.filter(type => {
return resourcesData._resourcesItems.some(_.matcher({ _type: type }));
});

model.set('_resourceTypes', [ 'all', ...typesWithItems ]);
}

setupFilters(model, resources) {
const hasMultipleResources = resources.length > 1;
const hasMultipleTypes = !resources.every(_.matcher({ _type: resources[0]._type }));
const enableFilters = model.get('_enableFilters') ?? true;

const showFilters = hasMultipleResources && hasMultipleTypes && enableFilters;
model.set('_showFilters', showFilters);

const filterColumnCount = _.uniq(_.pluck(resources, '_type')).length + 1;
model.set('_filterColumnCount', filterColumnCount);
}

/**
* IE doesn't support the 'download' attribute
* https://github.com/adaptlearning/adapt_framework/issues/1559
* and iOS just opens links with that attribute in the same window
* https://github.com/adaptlearning/adapt_framework/issues/1852
*/
setupCanDownload(model) {
const canEnableDownloads = device.browser !== 'internet explorer' && device.OS !== 'ios';
model.set('_canDownload', canEnableDownloads);
}

}
Expand Down
9 changes: 9 additions & 0 deletions properties.schema
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@
"help": "The instruction text for the resources which displays at the top of the resources drawer.",
"translatable": true
},
"_enableFilters": {
"type": "boolean",
"required":true,
"default": true,
"title": "Enable filter buttons",
"inputType": "Checkbox",
"validators": [],
"help": "Turns the filter buttons on and off. Note that the filter buttons will be automatically disabled if all resource items have the same Type value."
},
"_filterButtons": {
"type": "object",
"title": "Filter Buttons",
Expand Down
6 changes: 6 additions & 0 deletions schema/course.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@
"translatable": true
}
},
"_enableFilters": {
"type": "boolean",
"title": "Enable filter buttons",
"default": true,
"description": "Turns the filter buttons on and off. Note that the filter buttons will be automatically disabled if all resource items have the same Type value."
},
"_filterButtons": {
"type": "object",
"title": "Filter buttons",
Expand Down
23 changes: 6 additions & 17 deletions templates/resources.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,12 @@ import { classes, templates } from 'core/js/reactHelpers';
export default function Resources (props) {
const {
resources,
resourceTypes
resourceTypes,
_showFilters,
_filterColumnCount
} = props;

const _globals = Adapt.course.get('_globals');

function resourcesHasMultipleTypes(resources) {
if (resources.length < 2) return false;

const allSameType = resources.every(_.matcher({ _type: resources[0]._type }));
return !allSameType;
}

function resourcesGetColumnCount(resources) {
return _.uniq(_.pluck(resources, '_type')).length + 1; // add 1 for the 'All' button column
}

const [selectedFilter, setSelectedFilter] = useState('all');
const [selectedId, setSelectedId] = useState('resources__show-all');
const [focusFlag, setFocusFlag] = useState(false);
Expand Down Expand Up @@ -59,13 +49,12 @@ export default function Resources (props) {
<div className="resources__inner">

<templates.header {...props.model} />

{resourcesHasMultipleTypes(resources) &&
{_showFilters &&
<div
className={classes([
'resources__filter',
`has-${resourcesGetColumnCount(resources)}-columns`,
(resourcesGetColumnCount(resources) > 4) && 'has-extra-types'
`has-${_filterColumnCount}-columns`,
(_filterColumnCount > 4) && 'has-extra-types'
])}
>
<div className="resources__filter-inner" role="tablist">
Expand Down
7 changes: 0 additions & 7 deletions templates/resourcesFilterButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@ export default function ResourcesFilterButton (props) {
const {
model,
onClick,
resources,
selected,
_filter
} = props;

const buttonText = model._filterButtons[_filter];
const ariaLabel = model._filterAria[`${_filter}Aria`];

function resourcesHasType(resources, type) {
return resources.some(_.matcher({ _type: type }));
}

if (!resourcesHasType(resources, _filter) && _filter !== 'all') return null;

return (
<button
id={`resources__show-${_filter}`}
Expand Down
18 changes: 2 additions & 16 deletions templates/resourcesItem.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import device from 'core/js/device';
import { classes } from 'core/js/reactHelpers';

export default function ResourcesItem (props) {
const {
_forceDownload,
_canDownload,
_isGlobal,
_link,
_type,
Expand All @@ -16,20 +16,6 @@ export default function ResourcesItem (props) {
onResourceItemClicked
} = props;

/**
* IE doesn't support the 'download' attribute
* https://github.com/adaptlearning/adapt_framework/issues/1559
* and iOS just opens links with that attribute in the same window
* https://github.com/adaptlearning/adapt_framework/issues/1852
*/
function resourcesForceDownload(filename, _forceDownload) {
if (device.browser === 'internet explorer' || device.OS === 'ios') {
return false;
}

return (_forceDownload || filename);
}

return (
<div
className={classes([
Expand All @@ -43,7 +29,7 @@ export default function ResourcesItem (props) {
<a href={_link} className="resources__item-btn drawer__item-btn"
data-type={_type}
data-index={_index}
download={resourcesForceDownload(filename, _forceDownload) && filename }
download={(_canDownload && _forceDownload) && filename }
onClick={onResourceItemClicked}
target="_blank"
rel="noreferrer"
Expand Down

0 comments on commit 54c3461

Please sign in to comment.