diff --git a/client/app/components/admin/Sidebar.jsx b/client/app/components/admin/Sidebar.jsx
index 5d001b0..7d48397 100644
--- a/client/app/components/admin/Sidebar.jsx
+++ b/client/app/components/admin/Sidebar.jsx
@@ -1,57 +1,213 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
+import Interactive from 'react-interactive';
+
+import sidebarCSS from '../styles/adminSidebar.jsx'
+
class SidebarComponent extends Component {
- generateListElements(index, item) {
- if (index == this.props.listItemSelected)
- return (
-
{item.name} |
- )
- else
- return (
- {item.name} |
- )
- }
-
- displayRequestedElementsInfo() {
- if (this.props.requested_objects) {
- let requestedElement = this.props.requested_objects.map((item, index) => {
- return (
-
- { this.generateListElements(index, item) }
- | {item.status} |
- {item.requested_date} |
-
- )
- })
-
- return (
-
-
-
- | Name |
- Status |
- Date |
-
-
-
- {requestedElement}
-
-
- )
+ constructor(props){
+ super(props)
+ // Constructor with states holding the search query and the element of reponse.
+ this.state = {
+ filterValue: '',
+ filterQuery: '',
+ requestItemsToBeDisplayed: [],
+ listItemSelected: '',
}
}
- render() {
- console.log('sidebar: ', this.props.requested_objects)
- return (
-
-
Hello from the sidebar:
- { this.displayRequestedElementsInfo() }
-
- );
- }
+ // Where we wait for api response to be delivered from parent through props
+ componentWillReceiveProps(props) {
+ this.state.listItemSelected = props.listItemSelected;
+ this.displayRequestedElementsInfo(props.requested_objects);
+ }
+
+ // Inputs a date and returns a text string that matches how long it was since
+ convertDateToDaysSince(date) {
+ var oneDay = 24*60*60*1000;
+ var firstDate = new Date(date);
+ var secondDate = new Date();
+
+ var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime()) / oneDay));
+
+ switch (diffDays) {
+ case 0:
+ return 'Today';
+ case 1:
+ return '1 day ago'
+ default:
+ return diffDays + ' days ago'
+ }
+ }
+
+ // Called from our dropdown, receives a filter string and checks it with status field
+ // of our request objects.
+ filterItems(filterValue) {
+ let filteredRequestElements = this.props.requested_objects.map((item, index) => {
+ if (item.status === filterValue || filterValue === 'all')
+ return this.generateListElements(index, item);
+ })
+
+ this.setState({
+ requestItemsToBeDisplayed: filteredRequestElements,
+ filterValue: filterValue,
+ })
+ }
+
+
+ // Updates the internal state of the query filter and updates the list to only
+ // display names matching the query. This is real-time filtering.
+ updateFilterQuery(event) {
+ const query = event.target.value;
+
+ let filteredByQuery = this.props.requested_objects.map((item, index) => {
+ if (item.name.toLowerCase().indexOf(query.toLowerCase()) != -1)
+ return this.generateListElements(index, item);
+ })
+
+ this.setState({
+ requestItemsToBeDisplayed: filteredByQuery,
+ filterQuery: query,
+ });
+ }
+
+
+ generateFilterDropdown() {
+ return (
+
+ )
+ }
+
+ generateFilterSearchbar() {
+ return (
+ this.updateFilterQuery(event)}
+ value={this.state.filterQuery}/>
+ )
+ }
+
+ // A colored bar indicating the status of a item by color.
+ generateRequestIndicator(status) {
+ let statusColor;
+
+ switch (status) {
+ case 'requested':
+ // Yellow
+ statusColor = '#ffe14d';
+ break;
+ case 'downloading':
+ // Blue
+ statusColor = '#3fc3f3';
+ break;
+ case 'downloaded':
+ // Green
+ statusColor = '#6be682';
+ break;
+ default:
+ statusColor = 'grey';
+ }
+
+ const indicatorCSS = {
+ width: '100%',
+ height: '4px',
+ marginTop: '3px',
+ backgroundColor: statusColor,
+ }
+
+ return (
+
+ )
+ }
+
+
+ generateListElements(index, item) {
+ if (index == this.state.listItemSelected) {
+ return (
+
+
+
{item.name }
+
+ { this.convertDateToDaysSince(item.requested_date) }
+
+
+
Status: { item.status }
+
+
Matches found: 0
+ { this.generateRequestIndicator(item.status) }
+
+ )
+ }
+ else
+ return (
+
+
+
+ {item.name }
+
+ { this.convertDateToDaysSince(item.requested_date) }
+
+
+ { this.generateRequestIndicator(item.status) }
+
+
+ )
+ }
+
+ // This is our main loader that gets called when we receive api response through props from parent
+ displayRequestedElementsInfo(requested_objects) {
+ let requestedElement = requested_objects.map((item, index) => {
+ if (['requested', 'downloading', 'downloaded'].indexOf(this.state.filterValue) != -1) {
+ if (item.status === this.state.filterValue){
+ return this.generateListElements(index, item);
+ }
+ }
+
+ else if (this.state.filterQuery !== '') {
+ if (item.name.toLowerCase().indexOf(this.state.filterQuery.toLowerCase()) != -1)
+ return this.generateListElements(index, item);
+ }
+
+ else
+ return this.generateListElements(index, item);
+ })
+
+ this.setState({
+ requestItemsToBeDisplayed: requestedElement,
+ })
+ }
+
+ render() {
+ let bodyCSS = sidebarCSS.body;
+ if (typeof InstallTrigger !== 'undefined')
+ bodyCSS.width = '-moz-min-content';
+
+ return (
+
+
Hello from the sidebar:
+ { this.generateFilterDropdown() }
+ { this.generateFilterSearchbar() }
+
+ { this.state.requestItemsToBeDisplayed }
+
+
+ );
+ }
}
export default SidebarComponent;
\ No newline at end of file
diff --git a/client/app/components/styles/adminSidebar.jsx b/client/app/components/styles/adminSidebar.jsx
new file mode 100644
index 0000000..c10fe49
--- /dev/null
+++ b/client/app/components/styles/adminSidebar.jsx
@@ -0,0 +1,50 @@
+export default {
+ body: {
+ backgroundColor: 'white',
+ width: 'min-content',
+ },
+
+ parentElement: {
+ display: 'inline-block',
+ width: '300px',
+ border: '1px solid black',
+ borderRadius: '2px',
+ padding: '4px',
+ margin: '4px',
+ marginLeft: '4px',
+ backgroundColor: 'white',
+ },
+
+ parentElement_hover: {
+ marginLeft: '10px',
+ },
+
+ parentElement_active: {
+ textDecoration: 'none',
+ },
+
+ parentElement_selected: {
+ display: 'inline-block',
+ width: '300px',
+ border: '1px solid black',
+ borderRadius: '2px',
+ padding: '4px',
+ margin: '4px 0px 4px 4px',
+ marginLeft: '10px',
+ backgroundColor: 'white',
+ },
+
+ title: {
+ maxWidth: '70%',
+ display: 'inline-flex',
+ },
+
+ link: {
+ color: 'black',
+ textDecoration: 'none',
+ },
+
+ rightContainer: {
+ float: 'right',
+ },
+}
\ No newline at end of file