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

Adds a filter to the Module Library page. #2056

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
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