Skip to content

Commit

Permalink
clean up CourseResultsList a bit after virtualization
Browse files Browse the repository at this point in the history
and make it fit the screen properly
  • Loading branch information
hawkrives committed Jul 23, 2018
1 parent 4f7eeb1 commit 1729d2a
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 87 deletions.
3 changes: 3 additions & 0 deletions modules/gob-web/components/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const SidebarElement = styled.aside`
${theme.contentBlockSpacing};
flex: 1;
display: flex;
flex-direction: column;
@media all and (min-width: 35em) {
max-width: 280px;
padding-left: ${theme.pageEdgePadding};
Expand Down
191 changes: 104 additions & 87 deletions modules/gob-web/modules/course-searcher/course-results-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ const GROUP_BY_TO_TITLE = {
None: () => '',
}

type Results = Array<[string, Array<any>]>

type Props = {
groupBy: string,
results: Array<[string, Array<any>]>,
results: Results,
sortBy?: string,
studentId?: string,
}
Expand All @@ -31,94 +33,104 @@ type State = {
itemCount: number,
}

export default class CourseResultsList extends React.Component<Props, State> {
state = {itemCount: 0}
// method borrowed from https://github.com/lucasferreira/react-virtualized-sectionlist/blob/1ed9437c76dbc9b3fcf01dd9c5b50c96d9dc211c/source/index.js#L100-L123
type ExtractArgs = {
title: ?string,
items: Array<any>,
itemIndex: ?number,
sectionIndex: ?number,
isHeader: boolean,
}
function extractItemAtIndex(index: number, results: Results): ExtractArgs {
let itemIndex = index

static getDerivedStateFromProps = (props: Props) => {
// add 1 for the section heading
let itemCount = sumBy(props.results, ([_, items]) => items.length + 1)
return {itemCount}
}
for (let i = 0; i < results.length; i++) {
let [title, items] = results[i]

// The section adds an item for the header
itemIndex -= 1

// method borrowed from https://github.com/lucasferreira/react-virtualized-sectionlist/blob/1ed9437c76dbc9b3fcf01dd9c5b50c96d9dc211c/source/index.js#L100-L123
extractItemAtIndex = (
index: number,
): {
title: ?string,
items: Array<any>,
itemIndex: ?number,
sectionIndex: ?number,
isHeader: boolean,
} => {
let itemIndex = index

for (let i = 0; i < this.props.results.length; i++) {
let [title, items] = this.props.results[i]

// The section adds an item for the header
itemIndex -= 1

if (itemIndex >= items.length) {
itemIndex -= items.length
continue
}

let isHeader = itemIndex === -1

return {
title,
items,
itemIndex: isHeader ? null : itemIndex,
sectionIndex: i,
isHeader: isHeader,
}
if (itemIndex >= items.length) {
itemIndex -= items.length
continue
}

let isHeader = itemIndex === -1

return {
title: null,
items: [],
itemIndex: null,
sectionIndex: null,
isHeader: false,
title,
items,
itemIndex: isHeader ? null : itemIndex,
sectionIndex: i,
isHeader: isHeader,
}
}

getRowHeight = ({index}: {|index: number|}) => {
let {isHeader, itemIndex, items} = this.extractItemAtIndex(index)
return {
title: null,
items: [],
itemIndex: null,
sectionIndex: null,
isHeader: false,
}
}

if (isHeader) {
return 35
}
function getRowHeight(
isHeader: boolean,
itemIndex: ?number,
items: Array<any>,
) {
if (isHeader) {
return 35
}

if (itemIndex == null || !items[itemIndex]) {
return 0
}
if (itemIndex == null || !items[itemIndex]) {
return 0
}

let course = items[itemIndex]
let courseRows = 2
let course = items[itemIndex]
let courseRows = 2

let hasTimes = course.times && course.times.length
let hasSubtitle =
course.name &&
course.title &&
(course.type === 'Seminar' || course.type === 'Topic')
let hasTimes = course.times && course.times.length
let hasSubtitle =
course.name &&
course.title &&
(course.type === 'Seminar' || course.type === 'Topic')

if (hasTimes) {
courseRows += 1
}
if (hasSubtitle) {
courseRows += 1
}
if (hasTimes) {
courseRows += 1
}
if (hasSubtitle) {
courseRows += 1
}

if (courseRows === 2) {
return 38
} else if (courseRows === 3) {
return 56
} else if (courseRows === 4) {
return 71
}
if (courseRows === 2) {
return 38
} else if (courseRows === 3) {
return 56
} else if (courseRows === 4) {
return 71
}

return 0
return 0
}

export default class CourseResultsList extends React.Component<Props, State> {
state = {
itemCount: 0,
}

static getDerivedStateFromProps = (props: Props) => {
// add 1 for the section heading
let itemCount = sumBy(props.results, ([_, items]) => items.length + 1)
return {itemCount}
}

getRowHeight = ({index}: {|index: number|}) => {
let results = this.props.results
let {isHeader, itemIndex, items} = extractItemAtIndex(index, results)

return getRowHeight(isHeader, itemIndex, items)
}

renderHeader = (args: {title: ?string, key: string, style: any}) => {
Expand All @@ -137,7 +149,10 @@ export default class CourseResultsList extends React.Component<Props, State> {

renderRow = (args: {index: number, style: Object, key: string}) => {
let {index, style, key} = args
let {isHeader, itemIndex, items, title} = this.extractItemAtIndex(index)
let {isHeader, itemIndex, items, title} = extractItemAtIndex(
index,
this.props.results,
)

if (isHeader) {
return this.renderHeader({title, key, style})
Expand All @@ -161,18 +176,20 @@ export default class CourseResultsList extends React.Component<Props, State> {

render() {
return (
<AutoSizer>
{({height, width}) => (
<List
className="term-list"
height={height}
rowCount={this.state.itemCount}
rowHeight={this.getRowHeight}
rowRenderer={this.renderRow}
width={width}
/>
)}
</AutoSizer>
<div className="results-list-sizer">
<AutoSizer>
{({height, width}) => (
<List
className="term-list"
height={height}
rowCount={this.state.itemCount}
rowHeight={this.getRowHeight}
rowRenderer={this.renderRow}
width={width}
/>
)}
</AutoSizer>
</div>
)
}

Expand Down
13 changes: 13 additions & 0 deletions modules/gob-web/modules/course-searcher/course-searcher.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
@import '../../styles/mixins.scss';

.course-search {
flex: 1;
display: flex;
flex-direction: column;

// for AutoSizer (react-virtualized):
// > If the parent has style `position: static` (default value), it changes to
// > position: relative. It also injects a sibling div for size measuring.
position: relative;

.course-group {
@include card();
padding: 0.5em;
Expand Down Expand Up @@ -33,6 +42,10 @@
margin-top: 0.25em;
margin-bottom: 0.5em;
}

.results-list-sizer {
flex: 1;
}
}

.search-box {
Expand Down

0 comments on commit 1729d2a

Please sign in to comment.