Management windows grouped together.

editsong
Sander Vocke 5 years ago
parent ee5b80fadb
commit 94dd7a0dd6
  1. 19
      client/src/components/MainWindow.tsx
  2. 14
      client/src/components/appbar/AppBar.tsx
  3. 6
      client/src/components/windows/album/AlbumWindow.tsx
  4. 6
      client/src/components/windows/artist/ArtistWindow.tsx
  5. 67
      client/src/components/windows/manage/ManageWindow.tsx
  6. 2
      client/src/components/windows/manage_tags/ManageTagsWindow.tsx
  7. 15
      client/src/lib/backend/request.tsx
  8. 2
      client/src/lib/integration/useIntegrations.tsx

@ -16,7 +16,7 @@ import SettingsWindow from './windows/settings/SettingsWindow';
import { ErrorBoundary } from 'react-error-boundary';
import { ProvideIntegrations } from '../lib/integration/useIntegrations';
import ManageLinksWindow from './windows/manage_links/ManageLinksWindow';
import ManageWindow from './windows/manage/ManageWindow';
import ManageWindow, { ManageWhat } from './windows/manage/ManageWindow';
const darkTheme = createMuiTheme({
palette: {
@ -88,17 +88,16 @@ export default function MainWindow(props: any) {
<AppBar selectedTab={null} />
<SongWindow />
</PrivateRoute>
<PrivateRoute path="/tags">
<AppBar selectedTab={AppBarTab.Tags} />
<ManageTagsWindow />
<PrivateRoute path="/manage/tags">
<AppBar selectedTab={AppBarTab.Manage} />
<ManageWindow selectedWindow={ManageWhat.Tags}/>
</PrivateRoute>
<PrivateRoute path="/links">
<AppBar selectedTab={AppBarTab.Links} />
<ManageLinksWindow />
<PrivateRoute path="/manage/links">
<AppBar selectedTab={AppBarTab.Manage} />
<ManageWindow selectedWindow={ManageWhat.Links}/>
</PrivateRoute>
<PrivateRoute path="/manage">
<AppBar selectedTab={null} />
<ManageWindow />
<PrivateRoute exact path="/manage">
<Redirect to={"/manage/tags"} />
</PrivateRoute>
</Switch>
</BrowserRouter>

@ -3,13 +3,13 @@ import { AppBar as MuiAppBar, Box, Tab as MuiTab, Tabs, IconButton, Typography,
import SearchIcon from '@material-ui/icons/Search';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
import BuildIcon from '@material-ui/icons/Build';
import { Link, useHistory } from 'react-router-dom';
import { useAuth } from '../../lib/useAuth';
export enum AppBarTab {
Query = 0,
Tags,
Links,
Manage,
}
export const appBarTabProps: Record<any, any> = {
@ -17,13 +17,9 @@ export const appBarTabProps: Record<any, any> = {
label: <Box display="flex"><SearchIcon /><Typography variant="button">Query</Typography></Box>,
path: "/query",
},
[AppBarTab.Tags]: {
label: <Box display="flex"><LocalOfferIcon /><Typography variant="button">Tags</Typography></Box>,
path: "/tags",
},
[AppBarTab.Links]: {
label: <Box display="flex"><OpenInNewIcon /><Typography variant="button">Links</Typography></Box>,
path: "/links",
[AppBarTab.Manage]: {
label: <Box display="flex"><BuildIcon /><Typography variant="button">Manage</Typography></Box>,
path: "/manage",
},
}

@ -91,7 +91,7 @@ export function AlbumWindowControlled(props: {
value: m
});
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}, [albumId, dispatch]);
// Effect to get the album's songs.
@ -108,7 +108,7 @@ export function AlbumWindowControlled(props: {
offset: 0,
limit: -1,
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) });
.catch((e: any) => { handleNotLoggedIn(auth, e) });
dispatch({
type: AlbumWindowStateActions.SetSongs,
value: songs,
@ -159,7 +159,7 @@ export function AlbumWindowControlled(props: {
type: AlbumWindowStateActions.Reload
})
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}} />
{applying && <CircularProgress />}
</Box>

@ -95,7 +95,7 @@ export function ArtistWindowControlled(props: {
value: m
});
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}, [artistId, dispatch]);
// Effect to get the artist's songs.
@ -112,7 +112,7 @@ export function ArtistWindowControlled(props: {
offset: 0,
limit: -1,
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) });
.catch((e: any) => { handleNotLoggedIn(auth, e) });
dispatch({
type: ArtistWindowStateActions.SetSongs,
value: songs,
@ -163,7 +163,7 @@ export function ArtistWindowControlled(props: {
type: ArtistWindowStateActions.Reload
})
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}} />
{applying && <CircularProgress />}
</Box>

@ -1,4 +1,4 @@
import React, { useReducer } from 'react';
import React, { ReactFragment, useReducer, useState } from 'react';
import { WindowState } from "../Windows";
import { Box, Paper, Typography, TextField, Button, Tabs, Tab, Divider, IconButton } from "@material-ui/core";
import { useHistory } from 'react-router';
@ -8,45 +8,52 @@ import { Link } from 'react-router-dom';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
import ManageLinksWindow from '../manage_links/ManageLinksWindow';
import ManageTagsWindow from '../manage_tags/ManageTagsWindow';
export enum ManageWhat {
Tags = 0,
Links,
}
export interface ManageWindowState extends WindowState {
dummy: boolean
}
export enum ManageWindowActions {
SetDummy = "SetDummy",
}
export function ManageWindowReducer(state: ManageWindowState, action: any) {
switch (action.type) {
case ManageWindowActions.SetDummy: {
return state;
}
default:
throw new Error("Unimplemented ManageWindow state update.")
}
}
export default function ManageWindow(props: {
selectedWindow: ManageWhat,
}) {
let history = useHistory();
export default function ManageWindow(props: {}) {
const [state, dispatch] = useReducer(ManageWindowReducer, {
dummy: true,
});
let NavButton = (props: {
label: string,
icon: ReactFragment,
selected: boolean,
onClick?: () => void,
}) => {
return <Button
style={{ textTransform: "none" }}
onClick={props.onClick}
variant={props.selected ? "outlined" : "text"}
>
<Box display="flex" flexDirection="column" alignItems="center">
{props.icon}{props.label}
</Box>
</Button>
return <ManageWindowControlled state={state} dispatch={dispatch} />
}
}
export function ManageWindowControlled(props: {
state: ManageWindowState,
dispatch: (action: any) => void,
}) {
return <Box display="flex" alignItems="top" height="100%" m={2}>
<Box display="flex" flexDirection="column" alignItems="center">
<Box mt={2}><IconButton size="small"><LocalOfferIcon/></IconButton>Tags</Box>
<Box mt={2}><IconButton size="small"><OpenInNewIcon/></IconButton>Links</Box>
<NavButton
label="Tags"
icon={<LocalOfferIcon />}
selected={props.selectedWindow === ManageWhat.Tags}
onClick={() => history.push('/manage/tags')}
/>
<NavButton
label="Links"
icon={<OpenInNewIcon />}
selected={props.selectedWindow === ManageWhat.Links}
onClick={() => history.push('/manage/links')}
/>
</Box>
<ManageLinksWindow />
</Box>
{props.selectedWindow === ManageWhat.Tags && <ManageTagsWindow/>}
{props.selectedWindow === ManageWhat.Links && <ManageLinksWindow/>}
</Box >
}

@ -426,7 +426,7 @@ export function ManageTagsWindowControlled(props: {
type: ManageTagsWindowActions.Reset
});
})
.catch((e: NotLoggedInError) => { handleNotLoggedIn(auth, e) })
.catch((e: any) => { handleNotLoggedIn(auth, e) })
.catch((e: Error) => {
props.dispatch({
type: ManageTagsWindowActions.SetAlert,

@ -9,6 +9,10 @@ export class NotLoggedInError extends Error {
}
}
export function isNotLoggedInError(e: any): e is NotLoggedInError {
return e.name === NotLoggedInError;
}
export default async function backendRequest(url: any, ...restArgs: any[]): Promise<Response> {
let response = await fetch(url, ...restArgs);
if (response.status === 401 && (await response.json()).reason === "NotLoggedIn") {
@ -18,7 +22,12 @@ export default async function backendRequest(url: any, ...restArgs: any[]): Prom
return response;
}
export function handleNotLoggedIn(auth: Auth, e: NotLoggedInError) {
console.log("Not logged in!")
auth.signout();
export function handleNotLoggedIn(auth: Auth, e: any) {
if (isNotLoggedInError(e)) {
console.log("Not logged in!")
auth.signout();
return;
}
// Rethrow if unhandled
throw e;
}

@ -139,7 +139,7 @@ function useProvideIntegrations(): Integrations {
})
});
})
.catch((e: NotLoggedInError) => handleNotLoggedIn(auth, e));
.catch((e: any) => handleNotLoggedIn(auth, e));
}
let addIntegration = async (v: serverApi.CreateIntegrationRequest) => {

Loading…
Cancel
Save