Move fling administration to /admin subpath
Fling administration was directly beneth root path. For convenience the root path should be reserved for retrieving flings. Also adds fling content sections to real urls instead of hash urls, parameterized by the active fling. A content section for a fling can hence now be bookmarked or directly navigated to.
This commit is contained in:
parent
70cd9c29be
commit
857535bb93
15 changed files with 65 additions and 59 deletions
|
@ -5,14 +5,14 @@ import {Switch, Route, Redirect} from "react-router-dom";
|
||||||
|
|
||||||
import request, {isOwner} from './util/request';
|
import request, {isOwner} from './util/request';
|
||||||
|
|
||||||
import Login from './components/Login';
|
import Login from './components/admin/Login';
|
||||||
import Fling from './components/Fling';
|
import Fling from './components/admin/Fling';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/login" component={Login} />
|
<Route exact path="/admin/login" component={Login} />
|
||||||
<OwnerRoute exact path="(/|/flings)"><Fling /></OwnerRoute>
|
<OwnerRoute path="/admin"><Fling /></OwnerRoute>
|
||||||
<Route match="*">Not implemented</Route>
|
<Route match="*">Not implemented</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
|
@ -27,7 +27,7 @@ function OwnerRoute({ children, ...rest }) {
|
||||||
render={({ location }) => {
|
render={({ location }) => {
|
||||||
log.info(request.defaults);
|
log.info(request.defaults);
|
||||||
if(isOwner()) { return children; }
|
if(isOwner()) { return children; }
|
||||||
else { return <Redirect to={{pathname: "/login", state: {from: location}}} />; }
|
else { return <Redirect to={{pathname: "/admin/login", state: {from: location}}} />; }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import log from 'loglevel';
|
|
||||||
import React, {useState, useEffect, useRef} from 'react';
|
|
||||||
import {Switch, Route, Redirect, HashRouter, useLocation} from "react-router-dom";
|
|
||||||
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import {artifactClient} from '../util/flingclient';
|
|
||||||
|
|
||||||
import FlingArtifacts from './FlingArtifacts';
|
|
||||||
import Upload from './Upload';
|
|
||||||
import Settings from './Settings';
|
|
||||||
|
|
||||||
export default function FlingContent(props) {
|
|
||||||
let location = useLocation();
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div className="fling-content p-2">
|
|
||||||
<ul className="tab tab-block mt-0">
|
|
||||||
<li className={`tab-item ${location.hash !== "#/upload" && location.hash !== "#/settings" ? "active": ""}`}>
|
|
||||||
<a href="#/files">Files</a>
|
|
||||||
</li>
|
|
||||||
<li className={`tab-item ${location.hash === "#/upload"? "active": ""}`}>
|
|
||||||
<a href="#/upload">Upload</a>
|
|
||||||
</li>
|
|
||||||
<li className={`tab-item ${location.hash === "#/settings"? "active": ""}`}>
|
|
||||||
<a href="#/settings">Settings</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div className="mt-2">
|
|
||||||
<HashRouter>
|
|
||||||
<Switch>
|
|
||||||
<Route exact path={["/files","/"]}><FlingArtifacts activeFling={props.activeFling} /></Route>
|
|
||||||
<Route path="/upload"><Upload activeFling={props.activeFling} /></Route>
|
|
||||||
<Route path="/settings"><div><Settings activeFling={props.activeFling}/></div></Route>
|
|
||||||
</Switch>
|
|
||||||
</HashRouter>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@ import Navbar from './Navbar';
|
||||||
import FlingList from './FlingList';
|
import FlingList from './FlingList';
|
||||||
import FlingContent from './FlingContent';
|
import FlingContent from './FlingContent';
|
||||||
|
|
||||||
import {HashRouter} from 'react-router-dom';
|
import {BrowserRouter} from 'react-router-dom';
|
||||||
|
|
||||||
export default function Fling() {
|
export default function Fling() {
|
||||||
const [activeFling, setActiveFling] = useState(undefined);
|
const [activeFling, setActiveFling] = useState(undefined);
|
||||||
|
@ -17,7 +17,9 @@ export default function Fling() {
|
||||||
<div className="columns mt-2">
|
<div className="columns mt-2">
|
||||||
<div className="column col-sm-12 col-lg-3 col-2"> <FlingList setActiveFlingFn={setActiveFling} activeFling={activeFling} /> </div>
|
<div className="column col-sm-12 col-lg-3 col-2"> <FlingList setActiveFlingFn={setActiveFling} activeFling={activeFling} /> </div>
|
||||||
<div className="column col-sm-12">
|
<div className="column col-sm-12">
|
||||||
|
<BrowserRouter>
|
||||||
<FlingContent activeFling={activeFling} />
|
<FlingContent activeFling={activeFling} />
|
||||||
|
</BrowserRouter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -3,7 +3,7 @@ import React, {useState, useEffect, useRef} from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {artifactClient} from '../util/flingclient';
|
import {artifactClient} from '../../util/flingclient';
|
||||||
|
|
||||||
function FlingArtifactControl(props) {
|
function FlingArtifactControl(props) {
|
||||||
return(
|
return(
|
44
web/fling/src/components/admin/FlingContent.jsx
Normal file
44
web/fling/src/components/admin/FlingContent.jsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import log from 'loglevel';
|
||||||
|
import React, {useState, useEffect, useRef} from 'react';
|
||||||
|
import {Switch, Route, Redirect, BrowserRouter, useLocation, useParams, Link} from "react-router-dom";
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import {artifactClient} from '../../util/flingclient';
|
||||||
|
|
||||||
|
import FlingArtifacts from './FlingArtifacts';
|
||||||
|
import Upload from './Upload';
|
||||||
|
import Settings from './Settings';
|
||||||
|
|
||||||
|
export default function FlingContent(props) {
|
||||||
|
let location = useLocation();
|
||||||
|
let { fling } = useParams();
|
||||||
|
|
||||||
|
function path(tail) {
|
||||||
|
return `/admin/${props.activeFling}/${tail}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="fling-content p-2">
|
||||||
|
<ul className="tab tab-block mt-0">
|
||||||
|
<li className={`tab-item ${location.pathname !== path("upload") && location.pathname !== path("settings") ? "active": ""}`}>
|
||||||
|
<Link to={path("files")}>Files</Link>
|
||||||
|
</li>
|
||||||
|
<li className={`tab-item ${location.pathname === path("upload") ? "active": ""}`}>
|
||||||
|
<Link to={path("upload")}>Upload</Link>
|
||||||
|
</li>
|
||||||
|
<li className={`tab-item ${location.pathname === path("settings") ? "active": ""}`}>
|
||||||
|
<Link to={path("settings")}>Settings</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className="mt-2">
|
||||||
|
<Switch>
|
||||||
|
<Route exact path={["/admin/:fling/files","/admin"]}><FlingArtifacts activeFling={props.activeFling} /></Route>
|
||||||
|
<Route path="/admin/:fling/upload"><Upload activeFling={props.activeFling} /></Route>
|
||||||
|
<Route path="/admin/:fling/settings"><Settings activeFling={props.activeFling}/></Route>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import React, {useState, useEffect} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
import {flingClient} from '../util/flingclient';
|
import {flingClient} from '../../util/flingclient';
|
||||||
|
|
||||||
import FlingTile from './FlingTile';
|
import FlingTile from './FlingTile';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import log from 'loglevel';
|
||||||
import React, {useRef, useState} from 'react';
|
import React, {useRef, useState} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {flingClient} from '../util/flingclient';
|
import {flingClient} from '../../util/flingclient';
|
||||||
|
|
||||||
function TileAction(props) {
|
function TileAction(props) {
|
||||||
let shareUrlRef = useRef(null);
|
let shareUrlRef = useRef(null);
|
|
@ -2,7 +2,7 @@ import log from 'loglevel';
|
||||||
import React, {useState, useEffect} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import {useHistory, useLocation} from 'react-router-dom';
|
import {useHistory, useLocation} from 'react-router-dom';
|
||||||
|
|
||||||
import request, {setAuth} from '../util/request';
|
import request, {setAuth} from '../../util/request';
|
||||||
|
|
||||||
import Error from './Error';
|
import Error from './Error';
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export default () => {
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { from } = location.state || { from: { pathname: "/" } };
|
const { from } = location.state || { from: { pathname: "/admin" } };
|
||||||
|
|
||||||
useEffect(() => setAuth(null), []);
|
useEffect(() => setAuth(null), []);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import request from '../util/request';
|
import request from '../../util/request';
|
||||||
|
|
||||||
import send from './send.svg';
|
import send from '../resources/send.svg';
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
|
@ -22,7 +22,7 @@ export default function Navbar() {
|
||||||
</section>
|
</section>
|
||||||
<section className="navbar-section navbar-control">
|
<section className="navbar-section navbar-control">
|
||||||
<button className="btn btn-sm btn-link"><i className="icon icon-plus"/> New</button>
|
<button className="btn btn-sm btn-link"><i className="icon icon-plus"/> New</button>
|
||||||
<a className="btn btn-sm btn-link" href="/login"><i className="icon icon-shutdown"/> Logout</a>
|
<a className="btn btn-sm btn-link" href="/admin/login"><i className="icon icon-shutdown"/> Logout</a>
|
||||||
</section>
|
</section>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
|
@ -3,7 +3,7 @@ import React, {useState, useEffect, useRef} from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {flingClient} from '../util/flingclient';
|
import {flingClient} from '../../util/flingclient';
|
||||||
|
|
||||||
export default function Settings(props) {
|
export default function Settings(props) {
|
||||||
let [fling, setFling] = useState({name: "", sharing: {directDownload: false, allowUpload: true, shared: true, shareUrl: ""}});
|
let [fling, setFling] = useState({name: "", sharing: {directDownload: false, allowUpload: true, shared: true, shareUrl: ""}});
|
|
@ -1,12 +1,13 @@
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import React, {useState, useEffect, useRef} from 'react';
|
import React, {useState, useEffect, useRef} from 'react';
|
||||||
|
import {Switch, Route, Redirect, BrowserRouter, useLocation, useParams, Link} from "react-router-dom";
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {artifactClient} from '../util/flingclient';
|
import {artifactClient} from '../../util/flingclient';
|
||||||
|
|
||||||
import upload from './upload.svg';
|
import upload from '../resources/upload.svg';
|
||||||
import drop from './drop.svg';
|
import drop from '../resources/drop.svg';
|
||||||
|
|
||||||
|
|
||||||
export default function Upload(props) {
|
export default function Upload(props) {
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
Loading…
Reference in a new issue