Merge pull request #14 from RandellDawson/feat/create-search-component

[feature] created Search component
This commit is contained in:
Honman Yau
2018-11-30 13:56:43 +11:00
committed by mrugesh mohapatra
parent c1c1154bc3
commit db0fd603a5
7 changed files with 103 additions and 72 deletions

View File

@ -2,8 +2,7 @@ import React, { Component } from 'react';
import styled from 'styled-components';
import Tabs from './components/Tabs';
import Input from './components/Input';
import Results from './components/Results';
import Search from './components/Search';
import Pareto from './components/Pareto';
const Container = styled.div`
@ -11,79 +10,34 @@ const Container = styled.div`
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 960px;
width: 90vw;
padding: 15px;
border-radius: 4px;
box-shadow: 0 0 4px 0 #777;
`;
class App extends Component {
state = {
number: '',
foundPRs: [],
pareto: [],
view: 'search'
};
clearObj = { number: '', foundPRs: [] };
inputRef = React.createRef();
handleInputEvent = (event) => {
const { type, key, target: { value } } = event;
if (type === 'change') {
if (Number(value) || value === '') {
this.setState((prevState) => ({ number: value, foundPRs: [] }));
}
}
else if (type === 'keypress' && key === 'Enter') {
this.searchPRs(value);
}
}
handleButtonClick = () => {
const { number } = this.state;
this.searchPRs(number);
}
searchPRs = (number) => {
fetch(`https://pr-relations.glitch.me/pr/${number}`)
.then((response) => response.json())
.then(({ ok, foundPRs }) => {
if (ok) {
if (!foundPRs.length) {
foundPRs.push({ number: 'No PRs with matching files', filenames: [] });
}
this.setState((prevState) => ({ foundPRs }));
}
else {
this.inputRef.current.focus();
}
})
.catch(() => {
this.setState((prevState) => (this.clearObj));
});
}
handleViewChange = ( { target: { id } }) => {
const view = id.replace('tabs-', '');
this.setState((prevState) => ({ ...this.clearObj, view }));
}
render() {
const { handleButtonClick, handleViewChange, handleInputEvent, inputRef, state } = this;
const { number, foundPRs, view } = state;
const { handleViewChange, state: { view } } = this;
return (
<Container>
<>
<Tabs view={view} onViewChange={handleViewChange}/>
<Input ref={inputRef} value={number} onInputEvent={handleInputEvent} />
<button onClick={handleButtonClick}>Search</button>
{ view === 'search' && <Results foundPRs={foundPRs} /> }
<Container>
{ view === 'search' && <Search /> }
{ view === 'reports' && <Pareto /> }
</Container>
</>
);
}
}
export default App;

View File

@ -1,7 +1,12 @@
import React from 'react';
import styled from 'styled-components';
const Container = styled.input`
margin-bottom: 10px;
`;
const Input = React.forwardRef((props, ref) => (
<input
<Container
type="text"
placeholder="PR #"
onChange={props.onInputEvent}

View File

@ -54,7 +54,7 @@ class Pareto extends React.Component {
return (
<div>
{elements}
{data.length ? elements : 'Report Loading...'}
</div>
);
}

View File

@ -1,4 +1,9 @@
import React from 'react';
import styled from 'styled-components';
const List = styled.ul`
margin: 5px;
`;
const Results = ({ foundPRs }) => {
const elements = foundPRs.map((foundPR) => {
@ -10,7 +15,6 @@ const Results = ({ foundPRs }) => {
return (
<div key={number}>
<h5>
{!Number(number)
? number
: <>
@ -18,10 +22,9 @@ const Results = ({ foundPRs }) => {
<span>&nbsp;{username}</span>
</>
}
</h5>
<ul>
<List>
{files}
</ul>
</List>
</div>
);
});

View File

@ -0,0 +1,66 @@
import React, { Component } from 'react';
import Input from './Input';
import Results from './Results';
class Search extends Component {
state = {
number: '',
foundPRs: [],
};
clearObj = { number: '', foundPRs: [] };
inputRef = React.createRef();
handleInputEvent = (event) => {
const { type, key, target: { value } } = event;
if (type === 'change') {
if (Number(value) || value === '') {
this.setState((prevState) => ({ number: value, foundPRs: [] }));
}
}
else if (type === 'keypress' && key === 'Enter') {
this.searchPRs(value);
}
}
handleButtonClick = () => {
const { number } = this.state;
this.searchPRs(number);
}
searchPRs = (number) => {
fetch(`https://pr-relations.glitch.me/pr/${number}`)
.then((response) => response.json())
.then(({ ok, foundPRs }) => {
if (ok) {
if (!foundPRs.length) {
foundPRs.push({ number: 'No PRs with matching files', filenames: [] });
}
this.setState((prevState) => ({ foundPRs }));
}
else {
this.inputRef.current.focus();
}
})
.catch(() => {
this.setState((prevState) => (this.clearObj));
});
}
render() {
const { handleButtonClick, handleInputEvent, inputRef, state } = this;
const { number, foundPRs } = state;
return (
<>
<Input ref={inputRef} value={number} onInputEvent={handleInputEvent} />
<button onClick={handleButtonClick}>Search</button>
<Results foundPRs={foundPRs} />
</>
);
}
}
export default Search;

View File

@ -5,6 +5,7 @@ const Container = styled.div`
display: flex;
justify-content: center;
height: 40px;
margin: 10px;
`;
const Tab = styled.div`
@ -14,10 +15,12 @@ const Tab = styled.div`
padding: 5px;
border: 2px solid ${({ theme }) => theme.primary};
border-left: none;
flex-basis: 200px;
text-align: center;
&:hover {
cursor: pointer;
background: ${({ theme }) => theme.primary};
background: rgba(0, 0, 255, 0.8);
color: white;
}
@ -30,7 +33,7 @@ const Tabs = ({ view, onViewChange }) => {
return (
<Container>
<Tab id="tabs-search" onClick={onViewChange} active={view === 'search'}>Search</Tab>
<Tab id="tabs-reports" onClick={onViewChange} active={view === 'reports'}>Reports</Tab>
<Tab id="tabs-reports" onClick={onViewChange} active={view === 'reports'}>Pareto</Tab>
</Container>
);
};

View File

@ -6,7 +6,7 @@ body {
display: flex;
justify-content: center;
align-items: center;
/* height: 100vh; */
min-height: 100vh;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",