Skip to content

Commit

Permalink
Merge pull request #1206 from concord-consortium/185588012-optimize-c…
Browse files Browse the repository at this point in the history
…ollections-listing

feat:  Optimize collections listing [PT-185588012]
  • Loading branch information
dougmartin committed Jul 24, 2023
2 parents 841a09c + e4347fe commit d88f763
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 54 deletions.
2 changes: 1 addition & 1 deletion rails/app/assets/javascripts/react-components.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions rails/app/assets/stylesheets/web/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,9 @@
overflow:hidden;
}
}

.htmlContentEditor {
width: 100%;
height: 300px;
font-family: monospace;
}
2 changes: 1 addition & 1 deletion rails/app/views/admin/projects/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
= f.text_field :landing_page_slug
%li
Landing page content:
= f.text_area :landing_page_content, class: 'mceNoEditor'
= f.text_area :landing_page_content, class: 'mceNoEditor htmlContentEditor'
%li
Project card image url:
= f.text_field :project_card_image_url
Expand Down
12 changes: 8 additions & 4 deletions rails/app/views/admin/projects/landing_page.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@
}
}

// This function should be called after a materials collection is fully loaded on a
// landing page via PortalPages.renderMaterialsCollection(). In the case that the
// collection page is embedded in a class's assign lightbox via an iframe, it ensures
// This function should be called after a materials collection is fully loaded on a
// landing page via PortalPages.renderMaterialsCollection(). In the case that the
// collection page is embedded in a class's assign lightbox via an iframe, it ensures
// that the iframe is resized to show the collection's entire contents.
function cleanUpAssignViewAdjustment() {
function cleanUpAssignViewAdjustment(options) {
if (isAssignWrapped) {
setParentIframeHeight();
jQuery('#collectionIframe', window.parent.document).css({'visibility': 'visible'});
jQuery('#collectionIframeLoading', window.parent.document).css({'display': 'none'});
}
if (options && options.skipAnimation) {
jQuery(".resourceItem").css('transition', 'none').css('opacity', 1);
return;
}
jQuery(".resourceItem").animate({'opacity': 1}, 500);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
%br
Clear everything from this editor and save the settings to reset the content to default.)
- about_page_text_area_id = dom_id_for(admin_settings, :about_page_content, :textarea)
= f.text_area :about_page_content, :id => about_page_text_area_id, :class => 'mceNoEditor'
= f.text_area :about_page_content, :id => about_page_text_area_id, :class => 'mceNoEditor htmlContentEditor'
%input{:type=>"button", :value=>"Preview About Page", :onclick=>"preview_about_page('#{about_page_text_area_id}', null);", :class=>"button", :style=>"margin-top: 10px; font-size: 13px"}
%br
%br
6 changes: 3 additions & 3 deletions rails/app/views/admin/settings/_help_page_item.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
No help link
%br
(This option will remove the help link from the menu.)
%br
%br
- help_external_url_id = "help_external_url_for_settings_#{admin_settings.id}"
= f.radio_button :help_type,"external url",:id=> "#{help_external_url_id}",:style=>"margin-top:10px"
%label{:for=>"#{help_external_url_id}", :style=>"margin-left : 10px"}
Expand All @@ -26,6 +26,6 @@
%br
(This option will display a custom help page to users. Enter the custom HTML for the help page below.)
- custom_help_page_html_textarea_id = "custom_help_page_html_textarea_for_settings_#{admin_settings.id}"
= f.text_area :custom_help_page_html, :id => "#{custom_help_page_html_textarea_id}", :class => 'mceNoEditor'
= f.text_area :custom_help_page_html, :id => "#{custom_help_page_html_textarea_id}", :class => 'mceNoEditor htmlContentEditor'
%input{:type=>"button", :value=>"Preview Custom Help Page", :onclick=>"openPreviewHelpPage(false, '#{custom_help_page_html_textarea_id}', true, '')", :class=>"button" , :style=>"margin-top: 10px; font-size: 13px"}

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
%br
Clear everything from this editor and save the settings to reset the content to default.)
- home_page_text_area_id = dom_id_for(admin_settings, :home_page_content, :textarea)
= f.text_area :home_page_content, :id => home_page_text_area_id, :class => 'mceNoEditor'
= f.text_area :home_page_content, :id => home_page_text_area_id, :class => 'mceNoEditor htmlContentEditor'
%input{:type=>"button", :value=>"Preview Home Page", :onclick=>"preview_home_page('#{home_page_text_area_id}', null);", :class=>"button", :style=>"margin-top: 10px; font-size: 13px"}
%br
%br
Expand Down
63 changes: 35 additions & 28 deletions react-components/src/library/components/materials-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import Component from '../helpers/component'
import shuffleArray from '../helpers/shuffle-array'
import stemFinderResult from './stem-finder-result'
import portalObjectHelpers from '../helpers/portal-object-helpers'
import { loadMaterialsCollection } from '../helpers/materials-collection-cache'

const MaterialsCollection = Component({
getInitialState: function () {
return {
materials: []
materials: [],
loadedData: false
}
},

Expand All @@ -18,34 +20,39 @@ const MaterialsCollection = Component({
},

UNSAFE_componentWillMount: function () {
jQuery.ajax({
url: Portal.API_V1.MATERIALS_BIN_COLLECTIONS,
data: { id: this.props.collection,
skip_lightbox_reloads: true
},
dataType: 'json',
success: function (data) {
let materials = data[0].materials
if (this.props.randomize) {
materials = shuffleArray(materials)
loadMaterialsCollection(this.props.collection, function (data) {
let materials = data.materials
if (this.props.randomize) {
materials = shuffleArray(materials)
}
if (this.props.featured) {
// props.featured is the ID of the material we
// wish to insert at the start of the list
let featuredID = this.props.featured
let sortFeatured = function (a, b) {
if (a.id === featuredID) return -1
if (b.id === featuredID) return 1
return 0
}
if (this.props.featured) {
// props.featured is the ID of the material we
// wish to insert at the start of the list
let featuredID = this.props.featured
let sortFeatured = function (a, b) {
if (a.id === featuredID) return -1
if (b.id === featuredID) return 1
return 0
}
materials.sort(sortFeatured)
}
this.setState({ materials: materials })
if (this.props.onDataLoad) {
this.props.onDataLoad(materials)
}
}.bind(this)
})
materials.sort(sortFeatured)
}
this.setState({ materials: materials, loadedData: true })
}.bind(this))
},

componentDidMount: function () {
const checkForDataLoaded = () => {
if (!this.props.onDataLoad) {
return
}
if (this.state.loadedData) {
this.props.onDataLoad(this.state.materials)
} else {
setTimeout(checkForDataLoaded, 10)
}
}

checkForDataLoaded()
},

render: function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import React from 'react'

import SMaterialsList from '../search/materials-list'
import { loadMaterialsCollection } from '../../helpers/materials-collection-cache'

const shuffle = function (a) {
let idx = a.length
Expand All @@ -32,21 +33,15 @@ export default class MaterialsCollection extends React.Component {
componentDidMount () {
this.mounted = true
const { randomize, onDataLoad } = this.props
jQuery.ajax({
url: Portal.API_V1.MATERIALS_BIN_COLLECTIONS,
data: { id: this.props.collection },
dataType: 'json',
success: data => {
let { materials } = data[0]
if (randomize) {
materials = shuffle(materials)
}
if (onDataLoad) {
onDataLoad(materials)
}
if (this.mounted) {
this.setState({ materials })
}
loadMaterialsCollection(this.props.collection, ({ materials }) => {
if (randomize) {
materials = shuffle(materials)
}
if (onDataLoad) {
onDataLoad(materials)
}
if (this.mounted) {
this.setState({ materials })
}
})
}
Expand Down
38 changes: 38 additions & 0 deletions react-components/src/library/helpers/materials-collection-cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const cache = {}

export const loadMaterialsCollections = (ids, callback) => {
const onComplete = () => {
const data = ids.map(id => cache[id] || { name: 'MISSING-COLLECTION-' + id, materials: [] })
callback(data)
}

// ensure we only request each id once
const missingIds = ids.filter(id => !cache[id])
if (missingIds.length === 0) {
onComplete()
return
}

jQuery.ajax({
url: Portal.API_V1.MATERIALS_BIN_COLLECTIONS,
data: {
id: missingIds,
skip_lightbox_reloads: true
},
dataType: 'json',
success: (missingData) => {
missingIds.forEach((id, index) => {
cache[id] = missingData[index]
})
},
complete: () => {
onComplete()
}
})
}

export const loadMaterialsCollection = (id, callback) => {
loadMaterialsCollections([id], (data) => {
callback(data[0])
})
}
8 changes: 8 additions & 0 deletions react-components/src/library/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import ResourceRequirements from './components/browse-page/resource-requirements
import ResourceLicense from './components/browse-page/resource-license'
import ResourceProjects from './components/browse-page/resource-projects'
import showTab from './helpers/tabs'
import { loadMaterialsCollections } from './helpers/materials-collection-cache'

// previously React and ReactDOM were set by the react-rails gem
window.React = React
Expand Down Expand Up @@ -200,6 +201,13 @@ window.PortalComponents = {
renderSignupForm: signupFunctions.renderSignupForm,

MaterialsCollection: MaterialsCollection,

// this loads a set of materials collections in a single AJAX call and caches them for use
// in a later call to renderMaterialsCollection
loadMaterialsCollections: function (ids, callback) {
loadMaterialsCollections(ids, callback)
},

// this is a different format to match to existing project pages which had 2 formats itself
renderMaterialsCollection: function (collectionId, selectorOrElement, limitOrOptions) {
let options = limitOrOptions || {}
Expand Down

0 comments on commit d88f763

Please sign in to comment.