diff --git a/app/src/components/Admin.js b/app/src/components/Admin.js index d6235786..04fe60dd 100644 --- a/app/src/components/Admin.js +++ b/app/src/components/Admin.js @@ -23,7 +23,8 @@ import { startDownloads } from "../api"; import TimezoneSelect from 'react-timezone-select'; -import {secondsToDate, secondsToFrequency, textEllipsis, truncateLong, WROLModeMessage} from "./Common"; +import {secondsToDate, secondsToFrequency, TabLinks, textEllipsis, WROLModeMessage} from "./Common"; +import {Route} from "react-router-dom"; class Settings extends React.Component { @@ -440,23 +441,21 @@ class Downloads extends React.Component { } } -class Admin extends React.Component { +export default function Admin(props) { - render() { + const links = [ + {text: 'Downloads', to: '/admin', exact: true}, + {text: 'Settings', to: '/admin/settings'}, + {text: 'WROL Mode', to: '/admin/wrol'}, + ]; - const panes = [ - {menuItem: 'Downloads', render: () => }, - {menuItem: 'Settings', render: () => }, - {menuItem: 'WROL Mode', render: () => }, - ]; - - return ( - - - - ) - } + return ( + <> + + + + + > + ) } - -export default Admin; diff --git a/app/src/components/Archive.js b/app/src/components/Archive.js index f6cc4be5..cc2c3492 100644 --- a/app/src/components/Archive.js +++ b/app/src/components/Archive.js @@ -1,17 +1,17 @@ import React, {useState} from "react"; -import {Card, Confirm, Container, Icon, Image, Placeholder, Tab} from "semantic-ui-react"; +import {Card, Confirm, Container, Icon, Image, Placeholder} from "semantic-ui-react"; import Paginator, { ClearButton, ExternalLink, SearchInput, - TabRouter, + TabLinks, textEllipsis, uploadDate, WROLModeMessage } from "./Common"; import {deleteArchive, postDownload, refreshArchives} from "../api"; import Button from "semantic-ui-react/dist/commonjs/elements/Button"; -import {Link, NavLink} from "react-router-dom"; +import {Link, Route} from "react-router-dom"; import {ArchivePlaceholder} from "./Placeholder"; import Table from "semantic-ui-react/dist/commonjs/collections/Table"; import {useArchives} from "../hooks/useArchives"; @@ -298,40 +298,15 @@ function Domains() { export function ArchiveRoute(props) { - const panes = [ - { - menuItem: { - as: NavLink, - content: 'Archives', - id: 'archive', - to: '/archive', - exact: true, - key: 'home', - }, - render: () => - }, - { - menuItem: { - as: NavLink, - content: 'Domains', - id: 'domains', - to: '/archive/domains', - exact: true, - key: 'domains', - }, - render: () => - }, - { - menuItem: { - as: NavLink, - content: 'Manage', - id: 'manage', - to: '/archive/manage', - exact: true, - key: 'manage', - }, - render: () => - }, + const links = [ + {text: 'Archives', to: '/archive', exact: true}, + {text: 'Domains', to: '/archive/domains'}, + {text: 'Manage', to: '/archive/manage'}, ]; - return + return <> + + + + + > } diff --git a/app/src/components/Common.js b/app/src/components/Common.js index 82425355..a1daea02 100644 --- a/app/src/components/Common.js +++ b/app/src/components/Common.js @@ -1,6 +1,6 @@ import React, {useEffect, useState} from "react"; -import {Card, Container, Form, Icon, Image, Input, Pagination, Progress, Tab} from 'semantic-ui-react'; -import {Link} from "react-router-dom"; +import {Card, Container, Form, Icon, Image, Input, Menu, Pagination, Progress} from 'semantic-ui-react'; +import {Link, NavLink} from "react-router-dom"; import Button from "semantic-ui-react/dist/commonjs/elements/Button"; import Grid from "semantic-ui-react/dist/commonjs/collections/Grid"; import Message from "semantic-ui-react/dist/commonjs/collections/Message"; @@ -636,61 +636,18 @@ export function textEllipsis(str, maxLength, {side = "end", ellipsis = "..."} = return str; } -export class TabRouter extends React.Component { - constructor(props) { - super(props); - - const panes = props.panes; - let paneTos = []; - for (let i = 0; i < panes.length; i++) { - const pane = panes[i]; - paneTos = paneTos.concat([pane['menuItem']['to']]); - } - - this.state = { - activeIndex: this.matchPaneTo(paneTos), - paneTos: paneTos, - }; - } - - matchPaneTo = (paneTos) => { - const pathname = this.props.location.pathname; - // Attempt to find the exact match first. - let activeIndex = paneTos.indexOf(pathname); - if (activeIndex !== -1) { - return activeIndex; - } - - // Use the first tab if we can't find one. - activeIndex = 0; - // Try to find the most-exact match. - for (let i = 0; i < paneTos.length; i++) { - let to = paneTos[i]; - if (pathname.startsWith(to) && to.length > paneTos[activeIndex].length) { - // "to" is a better match because it is longer than the last one we found. - activeIndex = i; - } - } - return activeIndex; - } - - componentDidUpdate(prevProps, prevState, snapshot) { - if (prevProps.location.pathname !== this.props.location.pathname) { - this.setState({activeIndex: this.matchPaneTo(this.state.paneTos)}); - } - } - - render() { - const {panes, renderActiveOnly} = this.props; - return ( - <> - - > - ) - } - +export function TabLinks({links}) { + return ( + + {links.map((link) => + + {link.text} + + )} + + ) } diff --git a/app/src/components/Files.js b/app/src/components/Files.js index d39226f6..9a2345bf 100644 --- a/app/src/components/Files.js +++ b/app/src/components/Files.js @@ -110,10 +110,8 @@ class Files extends React.Component { } } -export class FilesRoute extends React.Component { - render() { - return ( - - ); - } +export function FilesRoute(props) { + return ( + + ); } diff --git a/app/src/components/Inventory.js b/app/src/components/Inventory.js index b7d44d88..6ded9ded 100644 --- a/app/src/components/Inventory.js +++ b/app/src/components/Inventory.js @@ -13,11 +13,10 @@ import { updateInventory, updateItem } from "../api"; -import {Button, Checkbox, Dropdown, Form, Grid, Header, Portal, Segment, Tab, Table} from "semantic-ui-react"; +import {Button, Checkbox, Dropdown, Form, Grid, Header, Portal, Segment, Table} from "semantic-ui-react"; import {Route} from "react-router-dom"; -import Container from "semantic-ui-react/dist/commonjs/elements/Container"; import {toast} from 'react-semantic-toasts'; -import {arraysEqual, enumerate, replaceNullValues} from './Common'; +import {arraysEqual, enumerate, replaceNullValues, TabLinks} from './Common'; import _ from 'lodash'; class InventorySummary extends React.Component { @@ -1089,27 +1088,16 @@ class InventoryAddList extends React.Component { } } -class InventoryTab extends React.Component { - - render() { - let panes = [ - {menuItem: 'List', render: () => }, - {menuItem: 'Summary', render: () => }, - ]; - return ( - - ) - } -} - -export class InventoryRoute extends React.Component { - render() { - return ( - <> - - - - > - ) - } +export function InventoryRoute(props) { + const links = [ + {text: 'List', to: '/inventory', exact: true}, + {text: 'Summary', to: '/inventory/summary'}, + ]; + return ( + <> + + + + > + ) } diff --git a/app/src/components/Nav.js b/app/src/components/Nav.js index eb5a043f..770605c1 100644 --- a/app/src/components/Nav.js +++ b/app/src/components/Nav.js @@ -5,14 +5,7 @@ import {Dropdown, Menu, Responsive} from "semantic-ui-react"; const responsiveWidth = 500; const links = [ - { - text: 'Videos', links: [ - {to: '/videos', text: 'Newest Videos', exact: true}, - {to: '/videos/favorites', text: 'Favorites', exact: true}, - {to: '/videos/channel', text: 'Channels', exact: true}, - {to: '/videos/manage', text: 'Manage', exact: true}, - ] - }, + {text: 'Videos', to: '/videos'}, {text: 'Inventory', to: '/inventory', exact: true}, {text: 'Archive', to: '/archive'}, {text: 'Files', to: '/files'}, @@ -33,7 +26,7 @@ function DropdownLinks(props) { {props.link.links.map((l) => { return ( - + ) })} @@ -41,7 +34,8 @@ function DropdownLinks(props) { ) } -function Link(props) { +function MenuLink(props) { + // Wrapper around NavLink to handle Navlink/Dropdown change. let classes = 'item'; if (props.link.header) { classes = `${classes} header`; @@ -68,17 +62,17 @@ export function NavBar() { return ( {/*Always show WROLPi home button*/} - + {/*Show the links in a menu when on desktop*/} {links.map((link) => { return ( - + ) })} {rightLinks.map((link) => { - return () + return () })} @@ -87,7 +81,7 @@ export function NavBar() { {collapsedLinks.map((link) => { - return () + return () })} diff --git a/app/src/components/Videos.js b/app/src/components/Videos.js index 756536a0..bac210ed 100644 --- a/app/src/components/Videos.js +++ b/app/src/components/Videos.js @@ -1,5 +1,5 @@ import React from 'react'; -import {Link, Route} from "react-router-dom"; +import {NavLink, Route} from "react-router-dom"; import Paginator, { changePageHistory, DEFAULT_LIMIT, @@ -10,8 +10,10 @@ import Paginator, { scrollToTop, searchOrders, secondsToString, + TabLinks, VideoCards, - videoOrders, WROLModeMessage + videoOrders, + WROLModeMessage } from "./Common" import VideoPage from "./VideoPlayer"; import {download, getChannel, getStatistics, getVideo, refresh, searchVideos} from "../api"; @@ -27,8 +29,7 @@ import { Modal, Radio, Segment, - Statistic, - Tab + Statistic } from "semantic-ui-react"; import * as QueryString from 'query-string'; import Container from "semantic-ui-react/dist/commonjs/elements/Container"; @@ -65,7 +66,6 @@ class ManageVideos extends React.Component { return ( - Manage Videos }, - {menuItem: 'Statistics', render: () => }, - ] - return ( - - - - ) - } +function ManageTab(props) { + return ( + + + + + ) } -export class VideosRoute extends React.Component { - - render() { - return ( - <> - - - } - /> - - - }/> - - - - - - } - /> - - - > - ) +function Link(props) { + let classes = 'item'; + if (props.link.header) { + classes = `${classes} header`; } + + return ( + + {props.link.text} + + ) +} + +export function VideosRoute(props) { + + const links = [ + {text: 'Videos', to: '/videos', exact: true}, + {text: 'Favorites', to: '/videos/favorites'}, + {text: 'Channels', to: '/videos/channel',}, + {text: 'Manage', to: '/videos/manage'}, + ]; + + return ( + <> + + + + } + /> + + + }/> + + + + + + } + /> + + > + ) } class Statistics extends React.Component {
}, - {menuItem: 'Statistics', render: () => }, - ] - return ( - - - - ) - } +function ManageTab(props) { + return ( + + + + + ) } -export class VideosRoute extends React.Component { - - render() { - return ( - <> - - - } - /> - - - }/> - - - - - - } - /> - - - > - ) +function Link(props) { + let classes = 'item'; + if (props.link.header) { + classes = `${classes} header`; } + + return ( + + {props.link.text} + + ) +} + +export function VideosRoute(props) { + + const links = [ + {text: 'Videos', to: '/videos', exact: true}, + {text: 'Favorites', to: '/videos/favorites'}, + {text: 'Channels', to: '/videos/channel',}, + {text: 'Manage', to: '/videos/manage'}, + ]; + + return ( + <> + + + + } + /> + + + }/> + + + + + + } + /> + + > + ) } class Statistics extends React.Component {