Skip to content

Commit

Permalink
Merge pull request #556 from BloomBooks/BL13272_StaffControls
Browse files Browse the repository at this point in the history
Move staff controls to separate box (BL-13272)
  • Loading branch information
andrew-polk authored Jul 9, 2024
2 parents 0eec13b + ae2f6c5 commit e81091c
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 87 deletions.
2 changes: 2 additions & 0 deletions src/components/BookDetail/BookDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
import { Helmet } from "react-helmet";
import { DownloadToBloomDialogs } from "./DownloadToBloomButton";
import { BookOwnerControlsBox } from "./BookOwnerControlsBox";
import { StaffControlsBox } from "./StaffControlsBox";

const BookDetail: React.FunctionComponent<IBookDetailProps> = (props) => {
const l10n = useIntl();
Expand Down Expand Up @@ -324,6 +325,7 @@ const BookDetailInternal: React.FunctionComponent<{
showDownloadDialog={showDownloadDialog}
/>
)}
<StaffControlsBox book={props.book} />
<DownloadToBloomDialogs
book={props.book}
getShowFunction={(download) =>
Expand Down
80 changes: 4 additions & 76 deletions src/components/BookDetail/BookExtraPanels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,15 @@ import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import { HarvesterArtifactUserControl } from "./ArtifactVisibilityPanel/ArtifactVisibilityPanel";
import { LoggedInUser } from "../../connection/LoggedInUser";
import { commonUI } from "../../theme";

// This used to have three panels, but two got moved to StaffControlsBox.tsx.
// Rather than refactor this back out, I'm taking the simple route of just
// leaving the remainder as is. Who knows if we'll add another panel here someday.
export const BookExtraPanels: React.FunctionComponent<{
book: Book;
}> = observer((props) => {
const user = LoggedInUser.current;
const userIsUploader = user?.username === props.book.uploader?.username;

// causes webpack to create a chunk for this which we only download as needed.
const ReactJsonView = React.lazy(() =>
user?.moderator
? import(
/* webpackChunkName: "react-json-view" */ "react-json-view"
)
: new Promise(() => {})
);

const StaffPanel = React.lazy(() =>
user?.moderator
? import(/* webpackChunkName: "staffPanel" */ "../Admin/StaffPanel")
: new Promise(() => {})
);
return (
<div
css={css`
Expand Down Expand Up @@ -67,67 +56,6 @@ export const BookExtraPanels: React.FunctionComponent<{
</ExpansionPanel>
</>
)}

{user?.moderator && (
<ExpansionPanel defaultExpanded={true}>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
Staff Controls
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<React.Suspense
fallback={
<div>
Loading chunk for showing staff panel...
</div>
}
>
<StaffPanel book={props.book!}></StaffPanel>
</React.Suspense>
</ExpansionPanelDetails>
</ExpansionPanel>
)}
{user?.moderator && (
<ExpansionPanel>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
Raw Book Data (Staff Only)
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<div
// raw book data typically has some very long strings without spaces,
// which the browser is reluctant to break. The overflow-wrap allows
// it to break them at undesirable places, but it still wants to make
// the panel as wide as it possibly can. A width of 100%, for reasons
// I don't understand, doesn't use the browser width minus various
// parent margins, but seems to be based on the nearest parental
// max-width. That currently makes it 800px wide, even on screens
// that are much smaller, which in turn makes the parent that wide
// and prevents various things being responsive. The width setting here
// does not allow it to be wider than the viewport (minus unfortunately
// duplicated information about how wide parent margins are).
// I picked 95 rather than 100 to give a bit of wiggle room.
// This element is only seen by staff (and only useful to very tecnhical
// staff at that) so it doesn't need to be especially pretty.
css={css`
overflow: auto;
overflow-wrap: break-word;
width: calc(95vw - 4em);
`}
>
<React.Suspense
fallback={
<div>Loading chunk for showing json...</div>
}
>
<ReactJsonView
src={props.book}
theme="monokai"
/>
</React.Suspense>
{/* {JSON.stringify(props.book)} */}
</div>
</ExpansionPanelDetails>
</ExpansionPanel>
)}
</div>
);
});
14 changes: 3 additions & 11 deletions src/components/BookDetail/BookOwnerControlsBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
useGetPermissions,
} from "../../connection/LibraryQueryHooks";
import { OSFeaturesContext } from "../OSFeaturesContext";
import { ControlsBox } from "./ControlsBox";

export const BookOwnerControlsBox: React.FunctionComponent<{
book: Book;
Expand Down Expand Up @@ -77,16 +78,7 @@ export const BookOwnerControlsBox: React.FunctionComponent<{
const showDeleteButton = userIsModerator || permissions.delete === true;

return (
<div
css={css`
box-sizing: border-box;
padding: 1em;
margin-top: 20px;
margin-bottom: 20px;
border: 4px solid ${commonUI.colors.bloomBlue};
border-radius: 5px;
`}
>
<ControlsBox>
<div>
<div
css={css`
Expand Down Expand Up @@ -257,6 +249,6 @@ export const BookOwnerControlsBox: React.FunctionComponent<{
<DeleteButton book={props.book} />
</div>
)}
</div>
</ControlsBox>
);
});
29 changes: 29 additions & 0 deletions src/components/BookDetail/ControlsBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// this engages a babel macro that does cool emotion stuff (like source maps). See https://emotion.sh/docs/babel-macros
import css from "@emotion/css/macro";
// these two lines make the css prop work on react elements
import { jsx } from "@emotion/core";
/** @jsx jsx */

import React from "react";

import { commonUI } from "../../theme";

// This is just a reusable box with a border around it.
export const ControlsBox: React.FunctionComponent<
React.HTMLProps<HTMLDivElement>
> = (props) => {
return (
<div
css={css`
box-sizing: border-box;
padding: 1em;
margin-top: 20px;
margin-bottom: 20px;
border: 4px solid ${commonUI.colors.bloomBlue};
border-radius: 5px;
`}
>
{props.children}
</div>
);
};
100 changes: 100 additions & 0 deletions src/components/BookDetail/StaffControlsBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// this engages a babel macro that does cool emotion stuff (like source maps). See https://emotion.sh/docs/babel-macros
import css from "@emotion/css/macro";
// these two lines make the css prop work on react elements
import { jsx } from "@emotion/core";
/** @jsx jsx */

import React, { Fragment } from "react";
import { observer } from "mobx-react-lite";
import {
ExpansionPanel,
ExpansionPanelSummary,
ExpansionPanelDetails,
} from "@material-ui/core";

import { Book } from "../../model/Book";
import { useGetUserIsModerator } from "../../connection/LoggedInUser";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import { commonUI } from "../../theme";
import { ControlsBox } from "./ControlsBox";

export const StaffControlsBox: React.FunctionComponent<{
book: Book;
}> = observer((props) => {
const userIsModerator = useGetUserIsModerator();
const showControlsBox = userIsModerator;

if (!showControlsBox) return <Fragment />;

// causes webpack to create a chunk for this which we only download as needed.
const StaffPanel = React.lazy(
() => import(/* webpackChunkName: "staffPanel" */ "../Admin/StaffPanel")
);
const ReactJsonView = React.lazy(
() =>
import(/* webpackChunkName: "react-json-view" */ "react-json-view")
);

return (
<ControlsBox>
<h1
css={css`
color: ${commonUI.colors.bloomBlue};
margin-top: 0;
`}
>
You have staff permission on this book
</h1>
<ExpansionPanel defaultExpanded={true}>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
Staff Controls
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<React.Suspense
fallback={
<div>Loading chunk for showing staff panel...</div>
}
>
<StaffPanel book={props.book!}></StaffPanel>
</React.Suspense>
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel>
<ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
Raw Book Data
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<div
// raw book data typically has some very long strings without spaces,
// which the browser is reluctant to break. The overflow-wrap allows
// it to break them at undesirable places, but it still wants to make
// the panel as wide as it possibly can. A width of 100%, for reasons
// I don't understand, doesn't use the browser width minus various
// parent margins, but seems to be based on the nearest parental
// max-width. That currently makes it 800px wide, even on screens
// that are much smaller, which in turn makes the parent that wide
// and prevents various things being responsive. The width setting here
// does not allow it to be wider than the viewport (minus unfortunately
// duplicated information about how wide parent margins are).
// I picked 95 rather than 100 to give a bit of wiggle room.
// This element is only seen by staff (and only useful to very technical
// staff at that) so it doesn't need to be especially pretty.
css={css`
overflow: auto;
overflow-wrap: break-word;
width: calc(95vw - 4em);
`}
>
<React.Suspense
fallback={
<div>Loading chunk for showing json...</div>
}
>
<ReactJsonView src={props.book} theme="monokai" />
</React.Suspense>
</div>
</ExpansionPanelDetails>
</ExpansionPanel>
</ControlsBox>
);
});

0 comments on commit e81091c

Please sign in to comment.