Skip to content

Commit

Permalink
library grouped pagination (connects #390) (#419)
Browse files Browse the repository at this point in the history
Co-authored-by: Laxman Maharjan <[email protected]>
  • Loading branch information
ABee-Tech and lmmrssa authored Aug 4, 2021
1 parent f44df6d commit 2267e81
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 99 deletions.
10 changes: 8 additions & 2 deletions api/src/controllers/resourceController.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@ const Resource = require('../models/resourceModel.js')
const Sequelize = require('sequelize')
const Op = Sequelize.Op
const { changeFormat } = require('../helpers/filehelpers')
const { where } = require('sequelize')

// @desc Fetch all resources
// @route GET /api/resources
// @route GET /api/resources?pageNumber=${pageNumber}&category=${category}
// @access Public
const getResources = (req, res) => {
const pageSize = 5
const page = Number(req.query.pageNumber) || 1
const { category, search } = req.query
const order = req.query.order || 'ASC'
const ordervalue = order && [['title', order]]
Resource.findAndCountAll({
offset: (page - 1) * pageSize,
limit: pageSize,
ordervalue
ordervalue,
where: {
...(search ? { title: { [Op.iLike]: '%' + search + '%' } } : {}),
...(category ? { resourceType: category } : {})
}
})
.then((resources) => {
const totalPages = Math.ceil(resources.count / pageSize)
Expand Down
61 changes: 61 additions & 0 deletions api/src/migrations/20210804154521-resource-remove-column.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict'

module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('resources', 'resourceFor')
await queryInterface.removeColumn('resources', 'publisher')
await queryInterface.removeColumn('resources', 'linkToLicense')
await queryInterface.removeColumn('resources', 'uploadDate')
await queryInterface.removeColumn('resources', 'addedBy')
await queryInterface.removeColumn('resources', 'openWith')
await queryInterface.removeColumn('resources', 'subject')
await queryInterface.removeColumn('resources', 'articleDate')
await queryInterface.removeColumn('resources', 'kind')
await queryInterface.removeColumn('resources', 'language')
await queryInterface.removeColumn('resources', 'author')
await queryInterface.removeColumn('resources', 'sum')
await queryInterface.removeColumn('resources', 'level')
await queryInterface.removeColumn('resources', 'languages')
await queryInterface.removeColumn('resources', 'timesRated')
await queryInterface.removeColumn('resources', 'tag')
await queryInterface.removeColumn('resources', 'year')
await queryInterface.removeColumn('resources', 'averageRating')
await queryInterface.removeColumn('resources', 'mediaType')
await queryInterface.removeColumn('resources', 'tags')
await queryInterface.removeColumn('resources', 'medium')
await queryInterface.removeColumn('resources', 'isDownloadable')
await queryInterface.removeColumn('resources', 'openUrl')
await queryInterface.removeColumn('resources', 'attachments')
await queryInterface.renameColumn('resources', 'createdDate', 'createdAt')
await queryInterface.renameColumn('resources', 'updatedDate', 'updatedAt')
},

down: async (queryInterface, Sequelize) => {
await queryInterface.addColumn('resources', 'resourceFor', { type: Sequelize.TEXT })
await queryInterface.addColumn('resources', 'publisher', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'linkToLicense', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'uploadDate', { type: Sequelize.DATE })
await queryInterface.addColumn('resources', 'addedBy', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'openWith', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'subject', { type: Sequelize.TEXT })
await queryInterface.addColumn('resources', 'articleDate', { type: Sequelize.DATE })
await queryInterface.addColumn('resources', 'kind', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'language', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'author', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'sum', { type: Sequelize.DOUBLE })
await queryInterface.addColumn('resources', 'level', { type: Sequelize.TEXT })
await queryInterface.addColumn('resources', 'languages', { type: Sequelize.TEXT })
await queryInterface.addColumn('resources', 'timesRated', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'tag', { type: Sequelize.TEXT })
await queryInterface.addColumn('resources', 'year', { type: Sequelize.DATE })
await queryInterface.addColumn('resources', 'averageRating', { type: Sequelize.DOUBLE })
await queryInterface.addColumn('resources', 'mediaType', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'tags', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'medium', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'isDownloadable', { type: Sequelize.BOOLEAN })
await queryInterface.addColumn('resources', 'openUrl', { type: Sequelize.STRING })
await queryInterface.addColumn('resources', 'attachments', { type: Sequelize.TEXT })
await queryInterface.renameColumn('resources', 'createdAt', 'createdDate')
await queryInterface.renameColumn('resources', 'updatedAt', 'updatedDate')
}
}
74 changes: 1 addition & 73 deletions api/src/models/resourceModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,89 +6,17 @@ const Resources = db.define('resources',
title: {
type: Sequelize.TEXT
},
resourceFor: {
type: Sequelize.TEXT
},
publisher: {
type: Sequelize.STRING
},
linkToLicense: {
type: Sequelize.STRING
},
uploadDate: {
type: Sequelize.DATE
},
addedBy: {
type: Sequelize.STRING
},
openWith: {
type: Sequelize.STRING
},
subject: {
type: Sequelize.TEXT
},
articleDate: {
type: Sequelize.DATE
},
kind: {
type: Sequelize.STRING
},
language: {
type: Sequelize.STRING
},
author: {
type: Sequelize.STRING
},
sum: {
type: Sequelize.DOUBLE
},
level: {
type: Sequelize.TEXT
},
languages: {
type: Sequelize.TEXT
},
timesRated: {
type: Sequelize.STRING
},
tag: {
type: Sequelize.TEXT
},
year: {
type: Sequelize.DATE
},
averageRating: {
type: Sequelize.DOUBLE
},
filename: {
type: Sequelize.STRING
},
mediaType: {
type: Sequelize.STRING
},
description: {
type: Sequelize.TEXT
},
tags: {
type: Sequelize.STRING
},
medium: {
type: Sequelize.STRING
},
isDownloadable: {
type: Sequelize.BOOLEAN
},
resourceType: {
type: Sequelize.STRING
},
openUrl: {
type: Sequelize.STRING
},
attachments: {
type: Sequelize.TEXT
}
},
{ timestamps: false }
{ timestamps: true }
)

module.exports = Resources
1 change: 1 addition & 0 deletions src/actions/resourceActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const createResource = (newResource) => async (dispatch, getState) => {
formData.append('title', newResource.title)
formData.append('description', newResource.description)
formData.append('file', newResource.file)
formData.append('resourceType', newResource.resourceType || 'articles')
try {
dispatch({ type: RESOURCE_CREATE_REQUEST })
const { userLogin: { userInfo } } = getState()
Expand Down
58 changes: 37 additions & 21 deletions src/screens/library/Library.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,31 @@ import SimpleModal from '../../components/simpleModal/SimpleModal'
import CollectionModal from '../../components/collectionModal/CollectionModal'
import GroupModal from '../../components/groupModal/GroupModal'
import { groupCollection, nav } from './CollectionData'
import { useSelector, useDispatch } from 'react-redux'
import { listResources, searchResources } from '../../actions/resourceActions'
import { useSelector } from 'react-redux'
import Pagination from '../../components/pagination/Pagination'
import SubHeader from '../../components/subHeader/SubHeader'
import { useHistory } from 'react-router-dom'
import useGetFetchData from '../../utils/useGetFetchData'
import { GET_LIBRARY } from '../../utils/urlConstants'

const Library = () => {
const resourceList = useSelector((state) => state.listResources)
const data = useSelector((state) => state.listResources)
let resources = resourceList.searchResources ? resourceList.searchResources : resourceList.resources
if (data) resources = data.resources
const userLogin = useSelector((state) => state.userLogin)
const { userInfo } = userLogin
const history = useHistory()

const [newCollection, setNewCollection] = useState(false)
const [active, setActive] = useState(false)
const [modalActive, setModalActive] = useState(false)
const [pageNumber, setPageNumber] = useState(1)
const [search, setSearch] = useState(null)
const dispatch = useDispatch()
const [search, setSearch] = useState()

function openAddCollection () {
setModalActive(true)
setActive(false)
}

useEffect(() => {
if (!userInfo) {
history.push('/login')
}
if (search) dispatch(searchResources(search))
if (!search) dispatch(listResources('', pageNumber))
}, [search, dispatch, history, userInfo, pageNumber])
if (!userInfo) history.push('/login')
}, [search, history, userInfo])

return (
<>
Expand All @@ -48,23 +39,21 @@ const Library = () => {
data={groupCollection} btnName='add to collections'
setNewCollection={setNewCollection}
/>}

{newCollection && <SimpleModal setNewCollection={setNewCollection} />}

{active && <CollectionModal setActive={setActive} openAddCollection={openAddCollection} />}

<DashboardLayout title='Library'>
<div className='library-main-container'>
<SubHeader search={search} setSearch={setSearch} nav={nav} setCreateActive={setActive} btnName='Add files' />
{['Articles', 'Videos'].map(type => (
<div className='list-container'>
<ListView
title={type} data={resources}
<div className='list-container' key={type}>
<LibraryCategory
search={search}
title={type}
setNewCollection={setNewCollection}
modalActive={modalActive}
setModalActive={setModalActive}
/>
<Pagination pageNumber={pageNumber} setPageNumber={setPageNumber} resourceList={resourceList} />
</div>
))}
</div>
Expand All @@ -73,4 +62,31 @@ const Library = () => {
)
}

const LibraryCategory = ({ title, search, setNewCollection, modalActive, setModalActive }) => {
const [pageNumber, setPageNumber] = useState(1)
useEffect(() => {
setPageNumber(1)
}, [search])
const { data: libraryData, isLoading } = useGetFetchData(
'LIBRARY_CATEGORY_DATA',
GET_LIBRARY + '?pageNumber=' + pageNumber + '&category=' + title.toLowerCase() + '&search=' + (search || ''),
{ title, pageNumber, search }
)
if (isLoading) {
return (<div>Loading...</div>)
}
return (
libraryData?.resources.length > 0
? <>
<ListView
title={title} data={libraryData?.resources}
setNewCollection={setNewCollection}
modalActive={modalActive}
setModalActive={setModalActive}
/>
<Pagination pageNumber={pageNumber} setPageNumber={setPageNumber} resourceList={libraryData} />
</> : <></>
)
}

export default Library
3 changes: 3 additions & 0 deletions src/utils/urlConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const Axios = axios.create({
// categories
export const CATEGORY = BASE_URL + 'categories'

// library
export const GET_LIBRARY = BASE_URL + 'resources'

// course
export const GET_COURSE = BASE_URL + 'courses'
export const ADD_COURSE = BASE_URL + 'courses/add'
Expand Down
6 changes: 3 additions & 3 deletions src/utils/useGetFetchData.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import axios from 'axios'
import { useQuery } from 'react-query'
import { configFunc } from './apiFunc'

const useGetFetchData = (uniqueKey, url) => {
const { error, isLoading, data } = useQuery(uniqueKey, async () => {
const useGetFetchData = (uniqueKey, url, dependencies) => {
const { error, isLoading, data } = useQuery([uniqueKey, { ...dependencies }], async () => {
const { data } = await axios.get(url, configFunc())
return data
})
}, { keepPreviousData: true })
return { data, error, isLoading }
}

Expand Down

0 comments on commit 2267e81

Please sign in to comment.