Merge pull request #14 from RandellDawson/feat/create-search-component
[feature] created Search component
This commit is contained in:
committed by
mrugesh mohapatra
parent
c1c1154bc3
commit
db0fd603a5
@ -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;
|
||||
|
@ -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}
|
||||
|
@ -54,7 +54,7 @@ class Pareto extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{elements}
|
||||
{data.length ? elements : 'Report Loading...'}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -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> {username}</span>
|
||||
</>
|
||||
}
|
||||
</h5>
|
||||
<ul>
|
||||
<List>
|
||||
{files}
|
||||
</ul>
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
66
dashboard-client/app/app/src/components/Search.js
Normal file
66
dashboard-client/app/app/src/components/Search.js
Normal 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;
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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",
|
||||
|
Reference in New Issue
Block a user