Skip to content
This repository has been archived by the owner on Sep 4, 2020. It is now read-only.

Feature/162416792 create new experiment table #1

Merged
merged 66 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
2854e5d
Delete useless file and update packages
lingyun1010 Jan 15, 2019
8c205f4
Add a fetchLoader for all experiments json data
lingyun1010 Jan 15, 2019
86d7b09
Add a calloutAlert for fetch loader
lingyun1010 Jan 15, 2019
52c4f75
Create a table with evergreen
lingyun1010 Jan 15, 2019
b6bce1d
Initialize component name and props
lingyun1010 Jan 15, 2019
6d5205e
Change cell style to show all content
lingyun1010 Jan 15, 2019
24f3a75
bugfix check box stays consistent with items
lingyun1010 Jan 15, 2019
f800a21
Debug change to lower cases for overall search
lingyun1010 Jan 15, 2019
cb687b9
Debug next page button diablility after filtering
lingyun1010 Jan 15, 2019
99bbc52
Refactor table header and cell to make it generic
lingyun1010 Jan 16, 2019
fb3aec7
Remove useless packages, change basic info
lingyun1010 Jan 16, 2019
eaa4fb2
Write a readme file
lingyun1010 Jan 16, 2019
617a817
Refactor cell style as a props and clean up code
lingyun1010 Jan 18, 2019
8c48ba6
Change jest env to jsdom
lingyun1010 Jan 18, 2019
1370e24
Add test utils required in experiment table
lingyun1010 Jan 18, 2019
e692d1a
Tests for fechloader and calloutalert
lingyun1010 Jan 18, 2019
2f8292e
Add test for experiment table
lingyun1010 Jan 18, 2019
8622301
Update snapshots and remove useless file
lingyun1010 Jan 18, 2019
a8fb42b
Remove link props if null
lingyun1010 Jan 18, 2019
ffbbcb5
Download files via an endpoint by clicking link
lingyun1010 Jan 29, 2019
4306be4
Update download button and test
lingyun1010 Jan 30, 2019
2adfc81
Adujst table column width for wide screen
lingyun1010 Feb 19, 2019
b8e4785
Move the styled.div into table component intead of
lingyun1010 Feb 19, 2019
e13b16d
Add styled component and rename virables
lingyun1010 Feb 19, 2019
d2e64f6
Rename aaData as data
lingyun1010 Feb 19, 2019
6405ead
Refactor code, add two components for table header
lingyun1010 Feb 19, 2019
7db6509
Amend test for ExperimentTable and add tests for
lingyun1010 Feb 19, 2019
9a2ae11
Add a key for tableHeaderCells
lingyun1010 Feb 19, 2019
7317f85
Amend test of search type table header
lingyun1010 Feb 19, 2019
6968798
Remove posttest
lingyun1010 Feb 19, 2019
bb7fee7
Revert "Remove posttest"
lingyun1010 Feb 19, 2019
b218767
Make table width responsive, add enableIndex props
lingyun1010 Feb 25, 2019
fff2261
Change download link with parameters
lingyun1010 Feb 25, 2019
94b046f
Update test props for ExperimentTable
lingyun1010 Feb 25, 2019
9396646
Rephrase information text
lingyun1010 Feb 27, 2019
7d43caa
Fix puralisation on download link
lingyun1010 Feb 27, 2019
61913f4
Use padding to replace blank space and remove keys
lingyun1010 Feb 27, 2019
b5eaa8d
Refactor headercell to component and replace keys
lingyun1010 Mar 1, 2019
0407f88
Clean the url for downloading files
lingyun1010 Mar 1, 2019
fe23e7a
Fix test for headerCell component and clean codes
lingyun1010 Mar 1, 2019
75a1690
Change the endpoint for downloading files
lingyun1010 Mar 20, 2019
da75d6f
Install fetch loader package and update lock.json
lingyun1010 Mar 20, 2019
91c4d77
Integrate atlas-fetch-loader with aaData response
lingyun1010 Mar 20, 2019
7e5c1a4
Rename components
lingyun1010 Mar 20, 2019
1209289
Refactor tableHeaderCells as a function and remove
lingyun1010 Mar 20, 2019
f660e15
Update test props and remove fectch loader tests
lingyun1010 Mar 20, 2019
58aafc0
Delete CalloutAlert snapshot
lingyun1010 Mar 20, 2019
b2bf0c4
Uninstall fetch loader package
lingyun1010 Mar 21, 2019
9e30c4d
Unwrap fetch loader and add an example response
lingyun1010 Mar 21, 2019
312b483
Rmove junk html tag and className, refactor code
lingyun1010 Mar 29, 2019
11d7f17
Remove styled div and clean up codes
lingyun1010 Mar 29, 2019
ac5ae36
Remove style div and refactor codes
lingyun1010 Mar 29, 2019
7617fca
Amend test for table style and footer page buttons
lingyun1010 Mar 29, 2019
fe3cd34
Amend test after clean html classnames
lingyun1010 Mar 29, 2019
485a72d
Split ExperimentTable into searchHeader, content
lingyun1010 Apr 26, 2019
c5c1746
Amend proptypes of entryPerPage
lingyun1010 Apr 26, 2019
f30b1a8
Add test for searchHeader and content, correct …
lingyun1010 Apr 26, 2019
f86d720
Reset default number of entries per page
lingyun1010 Apr 26, 2019
80a2acd
Reformat codes and rename ExperimentTable states
lingyun1010 May 3, 2019
00ea291
Update tests with new states names
lingyun1010 May 3, 2019
45eea8b
Restore the initial result and update prop in test
lingyun1010 May 3, 2019
d74dcd4
Refactor code with better variable names
lingyun1010 May 3, 2019
6382a14
Update aaData example
lingyun1010 May 5, 2019
9a0e6de
Refactor code and complete array prototypes
lingyun1010 May 7, 2019
3dd7b27
Updata test props
lingyun1010 May 7, 2019
6625f22
SearchAll on displayed columns not all data fields
lingyun1010 May 7, 2019
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
90 changes: 20 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,23 @@
# Template for Gene Expression Atlas and Single Cell Expression Atlas NPM packages

## Instructions

***Be sure to be running npm@4.0.0 or later. At least Node.js 8 LTS is strongly recommended.***

### Clone this repository
```
git clone https://github.com/gxa/atlas-package my-package
cd my-package
rm -rf .git
git init
git remote add origin https://github.com/gxa/my-package.git
```
Remember to create the new repository. The recommendation is to prefix the package name with “atlas-”.

### Fill in package metadata
Fill in the fields `name`, `description` and `repository`. As a general rule the packages are prefixed with
“expression-atlas-” or “sc-atlas-”. Finally, replace or remove `README.md`.

## Scripts

### `prepack`
Runs the `build` script before `npm publish`. Only the `lib` directory is packaged, so make sure everything (including
assests such as CSS or images are there).

### `postversion`, `postpublish`
After bumping the version with e.g. `npm version minor`, the package is automatically published and pushed, with all
tags, so new versions can be published in a single step.

### `test`
`npm test` runs all phases of the test lifecycle (i.e. `pretest`, `test` and `posttest`); in case you’ve added support
for Coveralls you won’t likely want to run the `posttest` phase. If that’s the case just do `npx jest`.

## Testing
Basic test boilerplate is included with [Jest](https://facebook.github.io/jest/) and
[Enzyme](http://airbnb.io/enzyme/). Jest is a test runner, an assertion library and a snapshot tester, whereas Enzyme
allows DOM testing. See the examples included in `__test__` to get an idea.

### Continuous integration
If you want CI and nice passing/failing badges, enable the repository in [Travis CI](https://travis-ci.org/). Now, with each push, Travis CI will run your tests and generate a report. You can display a test status badge going to
Travis CI, clicking on the badge and pasting the Markdown embed snippet on your `README.md`.

Enabling code coverage is very similar. You need to enable your repository in [Coveralls](https://coveralls.io/).
Every time that Travis is run, it will generate coverage information and send it to Coveralls for a coverage report.
If you go to Coveralls, you can also get a snippet to embed the coverage report shield on your readme file.

## What’s included?
- [React 16 and PropTypes](https://facebook.github.io/react/)
- [URI.js](https://medialize.github.io/URI.js/) for URL manipulation (the rich version of `query-string`)
- [Babel](https://babeljs.io/) with presets `env` and `react` (see `.babelrc`)
- [Webpack 4 with Webpack-CLI and Webpack-Dev-Server](https://webpack.js.org/)
- [Jest](https://facebook.github.io/jest/) and [Enzyme](http://airbnb.io/enzyme/) for testing

## Polyfills
No polyfills are included by default, but you might want one or both of these:
- [Fetch polyfill](https://github.com/github/fetch)
- [Babel polyfill](https://babeljs.io/docs/usage/polyfill/)

### NPM
```
npm install --save-dev whatwg-fetch @babel/polyfill
```

Tweak your `webpack.config.js` to include them in your entry points:
```
entry: {
myComponent: [`@babel/polyfill`, `whatwg-fetch`, `./html/render.js`]
...
}
# Atlas experiment table
We implement a sortable table header and check box table cell for downloading atlas experiments' files. [Evergreen Table](https://evergreen.segment.com/) component is used in this repository.

## Table header/content props structure

Table information is passed by an array of objects, named as `tableHeader`, including mandatory entries `type`, `title`, `width` and `dataParam`.
If the table cell links to another page, please indicate `link`, `resource`, `endpoint`, which will be transformed as a href to `host/resource/data[link]/endpoint`

***For example:***
```
[
{type: `plain`, title: `index`, width: 60, dataParam: null, link: null}
{type: `sort`, title: `Loaded date`, width: 140, dataParam: `lastUpdate`, link: null},
{type: `search`, title: `species`, width: 200, dataParam: `species`, link: null},
{type: `search`, title: `experiment description`, width: 360, dataParam: `experimentDescription`,
link: `experimentAccession`, resource: `experiments`, endpoint: `Results`},
{type: `search`, title: `experiment factors`, width: 260, dataParam: `experimentalFactors`, link: null},
{type: `sort`, title: `Number of assays`, width: 160, dataParam: `numberOfAssays`,
link: `experimentAccession`, resource: `experiments`, endpoint: `Experiment Design`}
]
```

## Run it on your browser
Expand Down
119 changes: 119 additions & 0 deletions __test__/ExperimentTable.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import React from 'react'
import Enzyme from 'enzyme'
import {shallow, mount} from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import {getRandomInt, TableCellDiv, data, tableHeader} from './TestUtils'
import ExperimentTable from '../src/ExperimentTable'
import TableFooter from '../src/TableFooter'
import { Table } from 'evergreen-ui'
import _ from "lodash"

Enzyme.configure({ adapter: new Adapter() })

describe(`ExperimentTable`, () => {
const props = {
aaData: data,
tableHeader: tableHeader,
host: `fool`,
resource: `bool`,
enableDownload: true,
enableIndex: true,
TableCellDiv: TableCellDiv
}

test(`should render three search general boxes and a table with head and body and two bottom info boxes`, () => {
const wrapper = shallow(<ExperimentTable {...props}/>)
expect(wrapper.find(`.small-8.columns`)).toHaveLength(3)

expect(wrapper.find(Table)).toHaveLength(1)
expect(wrapper.find(Table.Head)).toHaveLength(1)
expect(wrapper.find(Table.Body)).toHaveLength(1)

expect(wrapper.find(TableFooter)).toHaveLength(1)
})


test(`should sort table content and change header text icon`, () => {
const randomColumn = getRandomInt(1, tableHeader.length)
props.tableHeader[randomColumn].type=`sort`
const wrapper = mount(<ExperimentTable {...props}/>)

expect(wrapper.find(`.icon.icon-common.icon-sort-up`)).toHaveLength(1)
expect(wrapper.find(`.icon.icon-common.icon-sort-down`)).toHaveLength(0)

const sortedHeader = wrapper.find(`.header${randomColumn}`).at(0)
sortedHeader.simulate('click')
wrapper.update()
expect(wrapper.find(`.icon.icon-common.icon-sort-up`)).toHaveLength(0)
sortedHeader.simulate('click')
wrapper.update()
expect(wrapper.find(`.icon.icon-common.icon-sort-up`)).toHaveLength(1)
})

test(`should filter based on kingdom selection`, () => {
const event = {target: {name: `pollName`, value: `animals`}}
const wrapper = mount(<ExperimentTable {...props}/>)
const kingdomSearch = wrapper.find(`.kingdom`).at(0)
kingdomSearch.simulate(`change`, event)

expect(wrapper.state(`selectedKingdom`)).toEqual(`animals`)
expect(wrapper.find(Table.Row).length).toBeLessThanOrEqual(data.length)
})

test(`should filter based on table header search`, () => {
const randomValue = `si`
const randomColumn = getRandomInt(1, tableHeader.length)
props.tableHeader[randomColumn].type=`search`

const wrapper = mount(<ExperimentTable {...props}/>)
expect(wrapper.find(`.searchheader${randomColumn}`).exists()).toBe(true)
wrapper.setState({searchQuery: randomValue})
wrapper.update()
expect(wrapper.find(Table.Row).length).toBeLessThanOrEqual(data.length)
})

test(`should change page by clicking buttons`, () => {
const wrapper = mount(<ExperimentTable {...props}/>)
const currentPage = wrapper.state().currentPage
wrapper.setState({selectedNumber: 1, currentPage: 1})
wrapper.update()

const nextButton = wrapper.find('a.next')
nextButton.simulate('click')
wrapper.update()
expect(wrapper.state().currentPage).toEqual(currentPage+1)

const prevButton = wrapper.find('a.previous')
prevButton.simulate('click')
expect(wrapper.state().currentPage).toEqual(currentPage)

const pageNumberButton = wrapper.find(`.paginate_button.number a`)
const currentNumberButton = wrapper.find(`.paginate_button.number.current`)
expect(pageNumberButton).toHaveLength(data.length-1)
expect(currentNumberButton).toHaveLength(1)
})

test(`should show/hide download based on props`, () => {
const wrapper = shallow(<ExperimentTable {...props} enableDownload={true}/>)
expect(wrapper.find(`.downloadHeader`)).toHaveLength(1)

const wrapperNoDownload= shallow(<ExperimentTable {...props} enableDownload={false}/>)
expect(wrapperNoDownload.find(`.downloadHeader`)).toHaveLength(0)
})

test(`should save experiment accession by check download box`, () => {
const randomRow = getRandomInt(0, data.length)

const wrapper = mount(<ExperimentTable {...props} enableDownload={true}/>)
const propKey = tableHeader[wrapper.state(`orderedColumn`)].dataParam
const filteredElements = _.sortBy(data, propKey)

expect(wrapper.state(`checkedArray`)).toEqual([])
const checkbox = wrapper.find(`.checkbox`).at(randomRow)
checkbox.simulate(`change`)
expect(wrapper.state(`checkedArray`)).toEqual([filteredElements[randomRow].experimentAccession])
checkbox.simulate(`change`)
expect(wrapper.state(`checkedArray`)).toEqual([])
})

})
32 changes: 0 additions & 32 deletions __test__/MyComponent.test.js

This file was deleted.

26 changes: 26 additions & 0 deletions __test__/TableFooter.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import Enzyme from 'enzyme'
import {shallow} from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import { data} from './TestUtils'
import TableFooter from '../src/TableFooter'

Enzyme.configure({ adapter: new Adapter() })

describe(`TableFooter`, () => {
const props = {
dataArray: data,
currentPage: 1,
selectedNumber: 2,
data: data,
onChange: ()=>{}
}

test(`should render a previous button, a next button and information text`, () => {
const wrapper = shallow(<TableFooter {...props}/>)
expect(wrapper.find('li.next')).toHaveLength(1)
expect(wrapper.find('li.previous')).toHaveLength(1)
expect(wrapper.find(`.dataTables_info`)).toHaveLength(1)
})

})
57 changes: 57 additions & 0 deletions __test__/TestUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import styled from 'styled-components'

// Stolen from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
const getRandomInt = (min, max) => {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min)) + min //The maximum is exclusive and the minimum is inclusive
}

const TableCellDiv = styled.div`
font-size: 13px;
font-family: Helvetica, Arial, FreeSans, "Liberation Sans", sans-serif;
`

const tableHeader = [
{type: `sort`, title: `Loaded date`, width: 140, dataParam: `lastUpdate`},
{type: `search`, title: `species`, width: 200, dataParam: `species`},
{type: ``, title: `experiment description`, width: 360, dataParam: `experimentDescription`, link: `experimentAccession`, resource: `experiments`, endpoint: `Results`},
{type: `plain`, title: `experiment factors`, width: 260, dataParam: `experimentalFactors`},
{type: `sort`, title: `Number of assays`, width: 160, dataParam: `numberOfAssays`, link: `experimentAccession`, resource: `experiments`, endpoint: `Experiment Design`},
]

const data = [
{"experimentType":`SINGLE`,
"experimentAccession":`E-EHCA-2`,
"experimentDescription":`Melanoma infiltration`,
"lastUpdate":`16-11-2018`,
"numberOfAssays":6638,
"numberOfContrasts":0,
"species":`Mus musculus`,
"kingdom":`animals`,
"experimentalFactors":[`single cell identifier`,`sampling site`,`time`],
},
{"experimentType":`SINGLE`,
"experimentAccession":`E-GEOD-99058`,
"experimentDescription":`Single cell`,
"lastUpdate":`11-10-2018`,
"numberOfAssays":250,
"numberOfContrasts":0,
"species":`Mus musculus`,
"kingdom":`animals`,
"experimentalFactors":[`single cell identifier`]
},
{"experimentType":`SINGLE`,
"experimentAccession":`E-MTAB-5061`,
"experimentDescription":`healthy individuals and type 2 diabetes patients`,
"lastUpdate":`11-10-2018`,
"numberOfAssays":3514,
"numberOfContrasts":0,
"species":`Homo sapiens`,
"kingdom":`plants`,
"experimentalFactors":[`single cell identifier`,`disease`],
}
]

export {getRandomInt, TableCellDiv, tableHeader, data}
Loading