Skip to content

Commit

Permalink
Merge pull request #2056 from FrenjaminBanklin/issue/2000-filter-modu…
Browse files Browse the repository at this point in the history
…le-library

Adds a filter to the Module Library page.
  • Loading branch information
FrenjaminBanklin authored Feb 28, 2023
2 parents 715de4c + 271c05d commit 975203b
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 64 deletions.
1 change: 1 addition & 0 deletions packages/app/obojobo-repository/client/css/_defaults.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $color-dangerous-minor: desaturate($color-dangerous, 20%);
$color-text: #000000;
$color-text-minor: lighten($color-text, 40%);
$color-text-subheading: #a20e83;
$color-text-placeholder: #aaaaaa;
$color-bg: #ffffff;
$color-bg-overlay: rgba(200, 200, 200, 0.9);
$color-shadow: rgba(0, 0, 0, 0.3);
Expand Down
3 changes: 2 additions & 1 deletion packages/app/obojobo-repository/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module.exports = {
dashboard: 'shared/components/pages/page-dashboard-client.jsx',
stats: 'shared/components/pages/page-stats-client.jsx',
homepage: 'shared/components/pages/page-homepage.jsx',
'page-module': 'shared/components/pages/page-module-client.jsx'
'page-module': 'shared/components/pages/page-module-client.jsx',
'page-library': 'shared/components/pages/page-library-client.jsx'
}
}
}
19 changes: 19 additions & 0 deletions packages/app/obojobo-repository/server/models/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ class Collection {
this.createdAt = created_at
}

static fetchAllPublic() {
return db
.manyOrNone(
`
SELECT
id,
title,
user_id,
created_at
FROM repository_collections
WHERE visibility_type = 'public'
AND deleted = FALSE
`
)
.then(result => {
return result.map(row => new Collection(row))
})
}

static fetchById(id) {
return db
.one(
Expand Down
21 changes: 21 additions & 0 deletions packages/app/obojobo-repository/server/models/collection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ describe('Collection Model', () => {
expect(c.createdAt).toBe(mockRawCollection.created_at)
})

test('fetchAllPublic retrieves all public collections from the database', () => {
expect.hasAssertions()

const mockDbResponse = [
{ ...mockRawCollection },
{ ...mockRawCollection, id: 'mockCollectionId2', title: 'mockCollectionTitle2' }
]
db.manyOrNone.mockResolvedValueOnce(mockDbResponse)

return CollectionModel.fetchAllPublic().then(collections => {
expect(collections.length).toBe(2)
for (let c = 0; c < collections.length; c++) {
expect(collections[c]).toBeInstanceOf(CollectionModel)
expect(collections[c].id).toBe(mockDbResponse[c].id)
expect(collections[c].title).toBe(mockDbResponse[c].title)
expect(collections[c].userId).toBe(mockDbResponse[c].user_id)
expect(collections[c].createdAt).toBe(mockDbResponse[c].created_at)
}
})
})

test('fetchById retrieves a Collection from the database', () => {
expect.hasAssertions()

Expand Down
8 changes: 6 additions & 2 deletions packages/app/obojobo-repository/server/routes/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ router
.route('/library')
.get(getCurrentUser)
.get((req, res) => {
// when allowing for multiple public collections, replace this
// with a call to 'Collection.fetchAllPublic' followed by
// Promise.all() using collections.map(c => (c.loadRelatedDrafts()))
return Collection.fetchById(publicLibCollectionId)
.then(collection => {
return collection.loadRelatedDrafts()
Expand All @@ -122,9 +125,10 @@ router
pageCount: 1,
currentUser: req.currentUser,
// must use webpackAssetPath for all webpack assets to work in dev and production!
appCSSUrl: webpackAssetPath('repository.css')
appCSSUrl: webpackAssetPath('repository.css'),
appJsUrl: webpackAssetPath('page-library.js')
}
res.render('pages/page-library.jsx', props)
res.render('pages/page-library-server.jsx', props)
})
.catch(res.unexpected)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('repository library route', () => {

expect(response.header['content-type']).toContain('text/html')
expect(response.statusCode).toBe(200)
expectPageTitleToBe(response, 'Module Library')
expectPageTitleToBe(response, 'Obojobo Module Library')
})
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
@import '../../client/css/defaults';

#dashboard-root {
$placeholder-text-color: #aaaaaa;

.repository--main-content--control-bar {
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -87,7 +85,7 @@
margin: 0 auto;

.repository--item-list--collection--empty-placeholder--text {
color: $placeholder-text-color;
color: $color-text-placeholder;
margin-right: 2em;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { hydrateElWithoutStore } from '../../react-utils'
import PageLibrary from './page-library.jsx'

hydrateElWithoutStore(PageLibrary, '#react-hydrate-root')
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const React = require('react')
const DefaultLayout = require('../layouts/default')
const { convertPropsToString } = require('../../react-utils')

const PageLibraryServer = props => {
return (
<DefaultLayout
title={`Obojobo Module Library`}
appScriptUrl={props.appJsUrl}
appCSSUrl={props.appCSSUrl}
>
<span id="react-hydrate-root" data-react-props={convertPropsToString(props)} />
</DefaultLayout>
)
}

module.exports = PageLibraryServer
Original file line number Diff line number Diff line change
@@ -1,54 +1,89 @@
require('./page-library.scss')

const React = require('react')
import LayoutDefault from '../layouts/default'
import RepositoryNav from '../repository-nav'
import RepositoryBanner from '../repository-banner'
import Module from '../module'

const Search = require('../search')

const { filterModules } = require('../../util/filter-functions')

const title = 'Module Library'

const PageLibrary = props => (
<LayoutDefault
title={title}
className="repository--library"
appCSSUrl={props.appCSSUrl /* provided by resp.render() */}
>
<RepositoryNav
userId={props.currentUser.id}
userPerms={props.currentUser.perms}
avatarUrl={props.currentUser.avatarUrl}
displayName={`${props.currentUser.firstName} ${props.currentUser.lastName}`}
noticeCount={0}
/>
<RepositoryBanner className="default-bg" title={title} />

<div className="repository--section-wrapper">
<section className="repository--main-content">
<p>Find modules for your course.</p>
{props.collections.map(collection => (
<span key={collection.id}>
const PageLibrary = props => {
const [filterString, setFilterString] = React.useState('')

let filteredDisplay = props.collections
.map(collection => {
const visibleModulesInCollection = filterModules(collection.drafts, filterString, false)
const modulesInCollectionRender = visibleModulesInCollection.map(draft => (
<Module key={draft.draftId} {...draft}></Module>
))

if (visibleModulesInCollection.length) {
return (
<span
key={collection.id}
className="repository--main-content--item-list--collection-wrapper"
>
<div className="repository--main-content--title">
<span>{collection.title}</span>
</div>
<div className="repository--item-list--collection">
<div className="repository--item-list--collection--item-wrapper">
<div className="repository--item-list--row">
<div className="repository--item-list--collection--item--multi-wrapper">
{collection.drafts.map(draft => (
<Module key={draft.draftId} {...draft}></Module>
))}
{modulesInCollectionRender}
</div>
</div>
</div>
</div>
</span>
))}
</section>
</div>
</LayoutDefault>
)
)
}
return null
})
.filter(c => c !== null)

if (!filteredDisplay.length) {
filteredDisplay = (
<span className="repository--main-content--no-filter-results-text">
No modules found matching provided filter!
</span>
)
}

return (
<LayoutDefault
title={title}
className="repository--library"
appCSSUrl={props.appCSSUrl /* provided by resp.render() */}
>
<RepositoryNav
userId={props.currentUser.id}
userPerms={props.currentUser.perms}
avatarUrl={props.currentUser.avatarUrl}
displayName={`${props.currentUser.firstName} ${props.currentUser.lastName}`}
noticeCount={0}
/>
<RepositoryBanner className="default-bg" title={title} />

<div className="repository--section-wrapper">
<section className="repository--main-content">
<p>Find modules for your course.</p>
<Search value={filterString} placeholder="Filter Modules..." onChange={setFilterString} />
{filteredDisplay}
</section>
</div>
</LayoutDefault>
)
}

PageLibrary.defaultProps = {
collections: []
}

module.exports = PageLibrary
// module.exports = PageLibrary
export default PageLibrary
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* stylelint-disable */
@import '../../../client/css/defaults';

// reduce a larger font-size set on an ancestor in the library page
.repository--nav--links--search {
font-size: 0.9em;
}

.repository--main-content--no-filter-results-text {
display: block;
margin: 1em auto;
color: $color-text-placeholder;
text-align: center;
}
Loading

0 comments on commit 975203b

Please sign in to comment.