diff --git a/README.md b/README.md index b660fa9..d3d6311 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ With the [Adapt CLI](https://github.com/adaptlearning/adapt-cli) installed, run
Back to Top
## 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**. @@ -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**. @@ -91,4 +96,4 @@ No known limitations. **Author / maintainer:** Adapt Core Team with [contributors](https://github.com/adaptlearning/adapt-contrib-resources/graphs/contributors)
**Accessibility support:** WAI AA
**RTL support:** Yes
-**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, IE11, Safari 12+13 for macOS/iOS/iPadOS, Opera
+**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, Safari for macOS/iOS/iPadOS, Opera
diff --git a/example.json b/example.json index 3db9fbd..b17e5e3 100644 --- a/example.json +++ b/example.json @@ -7,6 +7,7 @@ "displayTitle": "", "body": "", "instruction": "", + "_enableFilters": true, "_filterButtons": { "all": "All", "document": "PDF", diff --git a/js/ResourcesView.js b/js/ResourcesView.js index ee325b9..852c275 100644 --- a/js/ResourcesView.js +++ b/js/ResourcesView.js @@ -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(, this.el); diff --git a/js/adapt-contrib-resources.js b/js/adapt-contrib-resources.js index add0c38..a211ce8 100644 --- a/js/adapt-contrib-resources.js +++ b/js/adapt-contrib-resources.js @@ -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 { @@ -48,6 +49,8 @@ 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); }); @@ -55,8 +58,34 @@ class Resources extends Backbone.Controller { 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); } } diff --git a/properties.schema b/properties.schema index 471a50a..dbe89f5 100644 --- a/properties.schema +++ b/properties.schema @@ -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", diff --git a/schema/course.schema.json b/schema/course.schema.json index ab78347..546d733 100644 --- a/schema/course.schema.json +++ b/schema/course.schema.json @@ -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", diff --git a/templates/resources.jsx b/templates/resources.jsx index 7419bce..a6a5dae 100644 --- a/templates/resources.jsx +++ b/templates/resources.jsx @@ -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); @@ -59,13 +49,12 @@ export default function Resources (props) {
- - {resourcesHasMultipleTypes(resources) && + {_showFilters &&
4) && 'has-extra-types' + `has-${_filterColumnCount}-columns`, + (_filterColumnCount > 4) && 'has-extra-types' ])} >
diff --git a/templates/resourcesFilterButton.jsx b/templates/resourcesFilterButton.jsx index 346bfc8..59e9222 100644 --- a/templates/resourcesFilterButton.jsx +++ b/templates/resourcesFilterButton.jsx @@ -5,7 +5,6 @@ export default function ResourcesFilterButton (props) { const { model, onClick, - resources, selected, _filter } = props; @@ -13,12 +12,6 @@ export default function ResourcesFilterButton (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 (