diff --git a/dashboard-client/app/app/src/components/FilenameResults.js b/dashboard-client/app/app/src/components/FilenameResults.js
new file mode 100644
index 0000000000..ec9446e784
--- /dev/null
+++ b/dashboard-client/app/app/src/components/FilenameResults.js
@@ -0,0 +1,42 @@
+import React from 'react';
+import styled from 'styled-components';
+
+const List = styled.div`
+ margin: 5px;
+ display: flex;
+ flex-wrap: wrap;
+`;
+
+const ListItem = styled.div`
+ padding: 0 5px;
+`;
+
+const FilenameResults = ({ searchValue, results }) => {
+ const elements = results.map((result) => {
+ const { filename, prs: prObjects } = result;
+ const prs = prObjects.map(({ number }, index) => {
+ const prUrl = `https://github.com/freeCodeCamp/freeCodeCamp/pull/${number}`;
+ return
+ • {number}
+ ;
+ });
+
+ return (
+
+ {filename}
+
+ {prs}
+
+
+ );
+ });
+
+ return (
+
+ {results.length ?
Results for: {searchValue}
: null}
+ {elements}
+
+ );
+};
+
+export default FilenameResults;
diff --git a/dashboard-client/app/app/src/components/Input.js b/dashboard-client/app/app/src/components/Input.js
index ae1b45cbfa..da8ae2ecb7 100644
--- a/dashboard-client/app/app/src/components/Input.js
+++ b/dashboard-client/app/app/src/components/Input.js
@@ -8,7 +8,6 @@ const Container = styled.input`
const Input = React.forwardRef((props, ref) => (
{
const { filename, count, prs } = entry;
- const prsList = prs.reduce((html, { number, username }) => {
+ const prsList = prs.map(({ number, username }) => {
const prUrl = `https://github.com/freeCodeCamp/freeCodeCamp/pull/${number}`;
- return html += `
- #${number} ${username}, `;
- }, '');
+ return (
+
+ #{number} ({username})
+
+ )
+ });
return (
- {filename}
-
+ {filename}
+
# of PRs: {count}
-
+ {prsList}
);
diff --git a/dashboard-client/app/app/src/components/Results.js b/dashboard-client/app/app/src/components/PrResults.js
similarity index 62%
rename from dashboard-client/app/app/src/components/Results.js
rename to dashboard-client/app/app/src/components/PrResults.js
index 8ec3191703..4b3554d5d9 100644
--- a/dashboard-client/app/app/src/components/Results.js
+++ b/dashboard-client/app/app/src/components/PrResults.js
@@ -1,20 +1,24 @@
import React from 'react';
import styled from 'styled-components';
-const List = styled.ul`
- margin: 5px;
+const Container = styled.div`
+ margin-bottom: 15px;
`;
-const Results = ({ foundPRs }) => {
- const elements = foundPRs.map((foundPR) => {
- const { number, filenames, username } = foundPR;
+const List = styled.ul`
+ margin: 3px;
+`;
+
+const PrResults = ({ searchValue, results }) => {
+ const elements = results.map((result, idx) => {
+ const { number, filenames, username } = result;
const files = filenames.map((filename, index) => {
return {filename};
});
const prUrl = `https://github.com/freeCodeCamp/freeCodeCamp/pull/${number}`
return (
-
+
{!Number(number)
? number
: <>
@@ -25,15 +29,16 @@ const Results = ({ foundPRs }) => {
{files}
-
+
);
});
return (
+ {results.length ?
Results for PR# {searchValue}
: null}
{elements}
);
};
-export default Results;
+export default PrResults;
diff --git a/dashboard-client/app/app/src/components/Search.js b/dashboard-client/app/app/src/components/Search.js
index 6b4a8b54ed..604e71ddea 100644
--- a/dashboard-client/app/app/src/components/Search.js
+++ b/dashboard-client/app/app/src/components/Search.js
@@ -1,45 +1,62 @@
import React, { Component } from 'react';
import Input from './Input';
-import Results from './Results';
-
+import PrResults from './PrResults';
+import FilenameResults from './FilenameResults';
+import SearchOption from './SearchOption';
class Search extends Component {
state = {
- number: '',
- foundPRs: [],
+ searchValue: '',
+ selectedOption: 'pr',
+ results: []
};
- clearObj = { number: '', foundPRs: [] };
+ clearObj = { searchValue: '', results: [] };
inputRef = React.createRef();
handleInputEvent = (event) => {
- const { type, key, target: { value } } = event;
+ const { type, key, target: { value: searchValue } } = event;
if (type === 'change') {
- if (Number(value) || value === '') {
- this.setState((prevState) => ({ number: value, foundPRs: [] }));
+ if (this.state.selectedOption === 'pr'){
+ if (Number(searchValue) || searchValue === '') {
+ this.setState((prevState) => ({ searchValue, results: [] }));
+ }
+ }
+ else {
+ this.setState((prevState) => ({ searchValue, results: [] }));
}
}
else if (type === 'keypress' && key === 'Enter') {
- this.searchPRs(value);
+ this.searchPRs(searchValue);
}
}
handleButtonClick = () => {
- const { number } = this.state;
- this.searchPRs(number);
+ const { searchValue } = this.state;
+ this.searchPRs(searchValue);
}
- searchPRs = (number) => {
- fetch(`https://pr-relations.glitch.me/pr/${number}`)
+ handleOptionChange = (changeEvent) => {
+ const selectedOption = changeEvent.target.value;
+ this.setState((prevState) => ({ selectedOption, ...this.clearObj }));
+ }
+
+ searchPRs = (value) => {
+ const { selectedOption } = this.state;
+ const baseUrl = 'https://pr-relations.glitch.me/';
+ const fetchUrl = baseUrl + (selectedOption === 'pr' ? `pr/${value}` : `search/?value=${value}`);
+ fetch(fetchUrl)
.then((response) => response.json())
- .then(({ ok, foundPRs }) => {
- if (ok) {
- if (!foundPRs.length) {
- foundPRs.push({ number: 'No PRs with matching files', filenames: [] });
+ .then((response) => {
+ if (response.ok) {
+ const { results } = response;
+ const objArrName = selectedOption === 'pr' ? 'filenames' : 'prs';
+ if (!results.length) {
+ results.push({ searchValue: 'No matching results', [objArrName]: [] });
}
- this.setState((prevState) => ({ foundPRs }));
+ this.setState((prevState) => ({ results }));
}
else {
this.inputRef.current.focus();
@@ -51,13 +68,22 @@ class Search extends Component {
}
render() {
- const { handleButtonClick, handleInputEvent, inputRef, state } = this;
- const { number, foundPRs } = state;
+ const { handleButtonClick, handleInputEvent, inputRef, handleOptionChange, state } = this;
+ const { searchValue, results, selectedOption } = state;
return (
<>
-
+
+
+ PR #
+
+
+ Filename
+
+
+
-
+ {selectedOption === 'pr' && }
+ {selectedOption === 'filename' && }
>
);
}
diff --git a/dashboard-client/app/app/src/components/SearchOption.js b/dashboard-client/app/app/src/components/SearchOption.js
new file mode 100644
index 0000000000..e527f7c211
--- /dev/null
+++ b/dashboard-client/app/app/src/components/SearchOption.js
@@ -0,0 +1,16 @@
+import React from 'react';
+
+const SearchOption = ({ children, value, selectedOption, onOptionChange }) => (
+
+);
+
+export default SearchOption;
diff --git a/dashboard-client/app/app/src/index.css b/dashboard-client/app/app/src/index.css
index 685ac3c8b1..b360e095c7 100644
--- a/dashboard-client/app/app/src/index.css
+++ b/dashboard-client/app/app/src/index.css
@@ -16,6 +16,11 @@ body {
-moz-osx-font-smoothing: grayscale;
}
+a {
+ text-decoration: none;
+ color: blue;
+}
+
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
diff --git a/dashboard-client/app/yarn.lock b/dashboard-client/app/yarn.lock
new file mode 100644
index 0000000000..fb57ccd13a
--- /dev/null
+++ b/dashboard-client/app/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+