Skip to content

Commit

Permalink
Fixes issue #2269 - Using simple-review as default review process (#3064
Browse files Browse the repository at this point in the history
)

* Fixes issue #2269 - Using simple-review as default review process. Established a hook pattern that I'd like to carry forward to loosen component coupling. Added a few unit tests.
* bumping version number in package.json as we will be cutting a release
  • Loading branch information
alexcottner authored Nov 21, 2023
1 parent fa4832e commit 8c1c786
Show file tree
Hide file tree
Showing 40 changed files with 722 additions and 288 deletions.
16 changes: 16 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,22 @@ table.record-list td.load-more {
text-decoration: none;
}

.card-body > .spinner {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.2);
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
width: auto;
margin: 0;
border-radius: 3px;
}

.load-more .spinner {
margin-top: 0.25em;
}
Expand Down
62 changes: 62 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kinto-admin",
"version": "2.0.0",
"version": "2.1.0",
"description": "Kinto Web Administration Console in React.js",
"scripts": {
"build": "rimraf build && cross-env NODE_ENV=production webpack --progress --config webpack.prod.js",
Expand All @@ -27,6 +27,7 @@
"@rjsf/bootstrap-4": "^5.13.2",
"@rjsf/core": "^5.13.2",
"@rjsf/validator-ajv8": "^5.13.2",
"@testing-library/react-hooks": "^8.0.1",
"atob": "^2.0.3",
"bootstrap": "^4.6.2",
"bootstrap-icons": "^1.11.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Spinner from "./Spinner";
import AuthForm from "./AuthForm";
import { getServerByPriority, isObject } from "../utils";
import { loadSession } from "../store/localStore";
import { useAppDispatch, useAppSelector } from "../hooks";
import { useAppDispatch, useAppSelector } from "../hooks/app";
import { useParams } from "react-router";

function ServerProps({ node }: { node: any }) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { Sidebar } from "../components/Sidebar";
import Notifications from "../containers/Notifications";

import { SessionInfoBar } from "./SessionInfoBar";
import { useAppSelector } from "../hooks";
import { useAppSelector } from "../hooks/app";

export function Layout() {
const authenticated = useAppSelector(store => store.session.authenticated);
Expand Down
2 changes: 1 addition & 1 deletion src/components/PermissionsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
preparePermissionsForm,
} from "../permission";
import { useParams } from "react-router";
import { useAppSelector } from "../hooks";
import { useAppSelector } from "../hooks/app";

import { RJSFSchema } from "@rjsf/utils";

Expand Down
2 changes: 1 addition & 1 deletion src/components/SessionInfoBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BoxArrowRight } from "react-bootstrap-icons";
import { QuestionCircleFill } from "react-bootstrap-icons";
import { Clipboard } from "react-bootstrap-icons";

import { useAppSelector, useAppDispatch } from "../hooks";
import { useAppSelector, useAppDispatch } from "../hooks/app";
import * as SessionActions from "../actions/session";

export function SessionInfoBar() {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import AdminLink from "./AdminLink";
import url from "../url";
import { canCreateBucket } from "../permission";
import { SIDEBAR_MAX_LISTED_COLLECTIONS } from "../constants";
import { useAppSelector, useAppDispatch } from "../hooks";
import { useAppSelector, useAppDispatch } from "../hooks/app";

type SideBarLinkProps = {
currentPath: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/bucket/BucketForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function BucketForm({
onSubmit,
}: Props) {
const creation = !formData.id;
const hasWriteAccess = canEditBucket(session, bucket);
const hasWriteAccess = canEditBucket(session, bid);
const formIsEditable = creation || hasWriteAccess;
const showDeleteForm = !creation && hasWriteAccess;

Expand Down
4 changes: 2 additions & 2 deletions src/components/bucket/BucketPermissions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { PermissionsForm } from "../PermissionsForm";
import { canEditBucket } from "../../permission";
import { useParams } from "react-router";

import { useAppSelector, useAppDispatch } from "../../hooks";
import { useAppSelector, useAppDispatch } from "../../hooks/app";

export function BucketPermissions() {
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -38,7 +38,7 @@ export function BucketPermissions() {
<PermissionsForm
permissions={permissions}
acls={acls}
readonly={!canEditBucket(session, bucket)}
readonly={!canEditBucket(session, bid)}
onSubmit={onSubmit}
/>
</BucketTabs>
Expand Down
2 changes: 1 addition & 1 deletion src/components/bucket/CollectionDataList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { canCreateCollection } from "../../permission";

export function ListActions(props) {
const { bid, session, bucket } = props;
if (session.busy || bucket.busy || !canCreateCollection(session, bucket)) {
if (session.busy || bucket.busy || !canCreateCollection(session, bid)) {
return null;
}
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/bucket/GroupDataList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function DataList(props) {
}

export function ListActions({ bid, session, bucket }) {
if (session.busy || bucket.busy || !canCreateGroup(session, bucket)) {
if (session.busy || bucket.busy || !canCreateGroup(session, bid)) {
return null;
}
return (
Expand Down
4 changes: 2 additions & 2 deletions src/components/collection/CollectionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ export default function CollectionForm({
}: Props) {
const [asJSON, setAsJSON] = useState(false);
const allowEditing = propFormData
? canEditCollection(session, bucket, collection)
: canCreateCollection(session, bucket);
? canEditCollection(session, bucket?.data?.id, collection)
: canCreateCollection(session, bucket?.data?.id);

const toggleJSON = event => {
event.preventDefault();
Expand Down
5 changes: 2 additions & 3 deletions src/components/collection/CollectionPermissions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import CollectionTabs from "./CollectionTabs";
import { PermissionsForm } from "../PermissionsForm";
import { canEditCollection } from "../../permission";
import { useParams } from "react-router";
import { useAppSelector, useAppDispatch } from "../../hooks";
import { useAppSelector, useAppDispatch } from "../../hooks/app";
interface RouteParams {
bid: string;
cid: string;
Expand All @@ -17,7 +17,6 @@ interface RouteParams {
export function CollectionPermissions() {
const { bid, cid } = useParams<RouteParams>();
const session = useAppSelector(state => state.session);
const bucket = useAppSelector(state => state.bucket);
const collection = useAppSelector(state => state.collection);
const { busy, permissions } = collection;
const acls = ["read", "write", "record:create"];
Expand Down Expand Up @@ -50,7 +49,7 @@ export function CollectionPermissions() {
<PermissionsForm
permissions={permissions}
acls={acls}
readonly={!canEditCollection(session, bucket, collection)}
readonly={!canEditCollection(session, bid, collection)}
onSubmit={onSubmit}
/>
</CollectionTabs>
Expand Down
23 changes: 23 additions & 0 deletions src/components/collection/CollectionRecords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { CommonProps, CommonStateProps } from "./commonPropTypes";

import * as CollectionActions from "../../actions/collection";
import * as RouteActions from "../../actions/route";
import AdminLink from "../AdminLink";
import { storageKeys, useLocalStorage } from "../../hooks/storage";
import { Shuffle } from "react-bootstrap-icons";

type OwnProps = {
match: CollectionRouteMatch;
Expand Down Expand Up @@ -71,6 +74,10 @@ export default function CollectionRecords(props: Props) {
} = collection;
const { schema, displayFields } = data;

const [useSimpleReview, setUseSimpleReview] = useLocalStorage(
storageKeys.useSimpleReview,
true
);
useEffect(() => {
if (!session.authenticated || !data?.last_modified) {
return;
Expand Down Expand Up @@ -127,6 +134,22 @@ export default function CollectionRecords(props: Props) {
/>
)}
{listActions}
{capabilities.signer && !useSimpleReview && (
<AdminLink
className="btn btn-secondary"
params={{ bid, cid }}
name="collection:simple-review"
onClick={() => {
setUseSimpleReview(true);
}}
style={{
float: "right",
marginTop: "1.5em",
}}
>
<Shuffle className="icon" /> Switch to Default Review UI
</AdminLink>
)}
</CollectionTabs>
</div>
);
Expand Down
32 changes: 30 additions & 2 deletions src/components/collection/CollectionTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import React from "react";
import { Gear, Lock, Justify, ClockHistory } from "react-bootstrap-icons";
import {
Gear,
Lock,
Justify,
ClockHistory,
Braces,
} from "react-bootstrap-icons";

import AdminLink from "../AdminLink";
import type { Capabilities } from "../../types";
import { storageKeys, useLocalStorage } from "../../hooks/storage";

type Props = {
bid: string;
cid: string;
selected: "records" | "attributes" | "permissions" | "history";
selected:
| "records"
| "attributes"
| "permissions"
| "history"
| "simple-review";
capabilities: Capabilities;
children?: React.ReactNode;
totalRecords?: number | null;
Expand All @@ -21,6 +33,8 @@ export default function CollectionTabs({
children,
totalRecords,
}: Props) {
const [useSimpleReview] = useLocalStorage(storageKeys.useSimpleReview, true);

return (
<div className="card">
<div className="card-header">
Expand All @@ -37,6 +51,20 @@ export default function CollectionTabs({
Records {totalRecords ? `(${totalRecords})` : null}
</AdminLink>
</li>
{capabilities.signer && useSimpleReview && (
<li className="nav-item" role="presentation">
<AdminLink
name="collection:simple-review"
params={{ bid, cid }}
className={
selected === "simple-review" ? "nav-link active" : "nav-link"
}
>
<Braces className="icon" />
Review
</AdminLink>
</li>
)}
<li className="nav-item" role="presentation">
<AdminLink
name="collection:attributes"
Expand Down
4 changes: 2 additions & 2 deletions src/components/collection/RecordTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import SignoffContainer from "../../containers/signoff/SignoffToolBar";
import { CommonProps } from "./commonPropTypes";

export function ListActions(props) {
const { bid, cid, session, bucket, collection } = props;
const { bid, cid, session, collection } = props;
if (session.busy || collection.busy) {
return null;
}
return (
<div className="list-actions">
{canCreateRecord(session, bucket, collection) && (
{canCreateRecord(session, bid, collection) && (
<>
<AdminLink
key="__1"
Expand Down
4 changes: 2 additions & 2 deletions src/components/group/GroupForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ export default function GroupForm(props: Props) {

const creation = !formData.id;
const hasWriteAccess = creation
? canCreateGroup(session, bucket)
: canEditGroup(session, bucket, group);
? canCreateGroup(session, bucket.data.id)
: canEditGroup(session, bucket.data.id, group);
const formIsEditable = creation || hasWriteAccess;
const showDeleteForm = !creation && hasWriteAccess;

Expand Down
Loading

0 comments on commit 8c1c786

Please sign in to comment.