Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Optimize collections listing [PT-185588012] #1206

Merged
merged 2 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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