diff --git a/css/styles.css b/css/styles.css index a069e6ee6..34c08bc6c 100644 --- a/css/styles.css +++ b/css/styles.css @@ -44,6 +44,10 @@ h1 { font-weight: bold; } +.card > .card-body { + position: relative; +} + .sidebar-filters > .card-body { padding: 15px 15px 0 15px; } diff --git a/src/components/bucket/BucketAttributes.tsx b/src/components/bucket/BucketAttributes.tsx index 9b2705980..1d0cc8a1d 100644 --- a/src/components/bucket/BucketAttributes.tsx +++ b/src/components/bucket/BucketAttributes.tsx @@ -60,24 +60,24 @@ export default function BucketAttributes({ [bid, updateBucket] ); - if (busy) { - return ; - } - return (

Edit {bid} bucket attributes

- + {busy ? ( + + ) : ( + + )}
); diff --git a/src/components/bucket/BucketCollections.tsx b/src/components/bucket/BucketCollections.tsx index 9e1d1d60f..ee06e4721 100644 --- a/src/components/bucket/BucketCollections.tsx +++ b/src/components/bucket/BucketCollections.tsx @@ -76,6 +76,7 @@ export default function BucketCollections({ collections={collections} listBucketNextCollections={listBucketNextCollections} capabilities={capabilities} + showSpinner={!collections.loaded} /> )} {listActions} diff --git a/src/components/bucket/BucketGroups.tsx b/src/components/bucket/BucketGroups.tsx index 2ddd4b224..fdb5d9ff8 100644 --- a/src/components/bucket/BucketGroups.tsx +++ b/src/components/bucket/BucketGroups.tsx @@ -42,12 +42,17 @@ export default function BucketCollections({ {listActions} - {groups.length === 0 ? ( + {!bucket.busy && groups.length === 0 ? (

This bucket has no groups.

) : ( - + )} {listActions}
diff --git a/src/components/bucket/BucketPermissions.tsx b/src/components/bucket/BucketPermissions.tsx index e8387a87b..6b10f3012 100644 --- a/src/components/bucket/BucketPermissions.tsx +++ b/src/components/bucket/BucketPermissions.tsx @@ -19,9 +19,6 @@ export function BucketPermissions() { const { busy, permissions } = bucket; const acls = ["read", "write", "collection:create", "group:create"]; - if (busy) { - return ; - } return (

@@ -32,12 +29,16 @@ export function BucketPermissions() { capabilities={session.serverInfo.capabilities} selected="permissions" > - + {busy ? ( + + ) : ( + + )}

); diff --git a/src/components/bucket/CollectionDataList.tsx b/src/components/bucket/CollectionDataList.tsx index 7cfcb7395..1bd5e7895 100644 --- a/src/components/bucket/CollectionDataList.tsx +++ b/src/components/bucket/CollectionDataList.tsx @@ -1,3 +1,4 @@ +import Spinner from "../Spinner"; import AdminLink from "@src/components/AdminLink"; import PaginatedTable from "@src/components/PaginatedTable"; import { canCreateCollection } from "@src/permission"; @@ -28,7 +29,13 @@ export function ListActions(props) { } export function DataList(props) { - const { bid, collections, capabilities, listBucketNextCollections } = props; + const { + bid, + collections, + capabilities, + listBucketNextCollections, + showSpinner, + } = props; const { loaded, entries, hasNextPage } = collections; const thead = ( @@ -45,6 +52,13 @@ export function DataList(props) { const tbody = ( + {showSpinner && ( + + + + + + )} {entries.map((collection, index) => { const { id: cid, diff --git a/src/components/bucket/GroupDataList.tsx b/src/components/bucket/GroupDataList.tsx index 2912b7af4..074febf1a 100644 --- a/src/components/bucket/GroupDataList.tsx +++ b/src/components/bucket/GroupDataList.tsx @@ -1,3 +1,4 @@ +import Spinner from "../Spinner"; import AdminLink from "@src/components/AdminLink"; import { canCreateGroup } from "@src/permission"; import { timeago } from "@src/utils"; @@ -6,7 +7,7 @@ import { Gear } from "react-bootstrap-icons"; import { ClockHistory } from "react-bootstrap-icons"; export function DataList(props) { - const { bid, groups, capabilities } = props; + const { bid, groups, capabilities, showSpinner } = props; return ( @@ -18,6 +19,13 @@ export function DataList(props) { + {showSpinner && ( + + + + )} {groups.map((group, index) => { const { id: gid, members, last_modified } = group; const date = new Date(last_modified); diff --git a/src/components/collection/CollectionAttributes.tsx b/src/components/collection/CollectionAttributes.tsx index 856160a05..55ff4399d 100644 --- a/src/components/collection/CollectionAttributes.tsx +++ b/src/components/collection/CollectionAttributes.tsx @@ -63,10 +63,6 @@ export default function CollectionAttributes({ } = match; const { busy, data: formData } = collection; - if (busy) { - return ; - } - return (

@@ -82,16 +78,20 @@ export default function CollectionAttributes({ selected="attributes" capabilities={capabilities} > - + {busy ? ( + + ) : ( + + )}

); diff --git a/src/components/collection/CollectionPermissions.tsx b/src/components/collection/CollectionPermissions.tsx index c141c0fc1..b07410466 100644 --- a/src/components/collection/CollectionPermissions.tsx +++ b/src/components/collection/CollectionPermissions.tsx @@ -28,9 +28,6 @@ export function CollectionPermissions() { ); }; - if (busy) { - return ; - } return (

@@ -46,12 +43,16 @@ export function CollectionPermissions() { capabilities={session.serverInfo.capabilities} selected="permissions" > - + {busy ? ( + + ) : ( + + )}

); diff --git a/src/components/group/GroupAttributes.tsx b/src/components/group/GroupAttributes.tsx index b6d9042b6..9ed1e5873 100644 --- a/src/components/group/GroupAttributes.tsx +++ b/src/components/group/GroupAttributes.tsx @@ -43,6 +43,7 @@ export default function GroupAttributes(props: Props) { params: { bid, gid }, } = match; const { busy, data: formData } = group; + console.log(group); const onSubmit = useCallback( (formData: GroupData) => { @@ -60,10 +61,6 @@ export default function GroupAttributes(props: Props) { [bid, deleteGroup] ); - if (busy || formData == null) { - return ; - } - return (

@@ -79,16 +76,20 @@ export default function GroupAttributes(props: Props) { selected="attributes" capabilities={capabilities} > - + {busy || formData == null ? ( // formData will be null until it is fetched, busy will be false until the fetch starts, need to wait for for both conditions before rendering + + ) : ( + + )}

); diff --git a/src/components/group/GroupPermissions.tsx b/src/components/group/GroupPermissions.tsx index b17fff8d2..7c7656ef1 100644 --- a/src/components/group/GroupPermissions.tsx +++ b/src/components/group/GroupPermissions.tsx @@ -22,9 +22,6 @@ export function GroupPermissions() { const onSubmit = ({ formData }: { formData: GroupPermissionsType }) => { dispatch(BucketActions.updateGroup(bid, gid, { permissions: formData })); }; - if (busy) { - return ; - } return (

@@ -40,12 +37,16 @@ export function GroupPermissions() { capabilities={session.serverInfo.capabilities} selected="permissions" > - + {busy ? ( + + ) : ( + + )}

); diff --git a/src/components/record/RecordPermissions.tsx b/src/components/record/RecordPermissions.tsx index 159140c85..14e5b800c 100644 --- a/src/components/record/RecordPermissions.tsx +++ b/src/components/record/RecordPermissions.tsx @@ -26,9 +26,6 @@ export function RecordPermissions() { }; const { busy, permissions } = record; const acls = ["read", "write"]; - if (busy) { - return ; - } return (

@@ -45,12 +42,16 @@ export function RecordPermissions() { capabilities={session.serverInfo.capabilities} selected="permissions" > - + {busy ? ( + + ) : ( + + )}

); diff --git a/src/components/signoff/SimpleReview/index.tsx b/src/components/signoff/SimpleReview/index.tsx index 50fa798da..6ea3149d9 100644 --- a/src/components/signoff/SimpleReview/index.tsx +++ b/src/components/signoff/SimpleReview/index.tsx @@ -116,6 +116,8 @@ export default function SimpleReview({ console.error(ex); } } + } else { + setRecords({ oldRecords: [], newRecords: [], loading: false }); } } getRecords(); @@ -137,11 +139,7 @@ export default function SimpleReview({ Not authenticated ); - } else if ( - session.authenticating || - session.busy || - (records.loading && signoffSource && signoffDest) - ) { + } else if (session.authenticating || session.busy) { return ; } const handleRollback = (text: string) => { @@ -212,7 +210,7 @@ export default function SimpleReview({ capabilities={capabilities || {}} totalRecords={collection?.totalRecords || 0} > - + {records.loading ? : } ); diff --git a/test/components/bucket/CollectionDataList_test.tsx b/test/components/bucket/CollectionDataList_test.tsx index e8f68218f..5cfc04ca2 100644 --- a/test/components/bucket/CollectionDataList_test.tsx +++ b/test/components/bucket/CollectionDataList_test.tsx @@ -64,6 +64,10 @@ describe("Bucket CollectionDataList", () => { expect(screen.queryByTitle("Browse collection")).toBeDefined(); expect(screen.queryByTitle("Edit collection attributes")).toBeDefined(); }); + it("Should render a spinner when showSpinner is true", () => { + renderWithProvider(); + expect(screen.queryByTestId("spinner")).toBeDefined(); + }); }); describe("Bucket CollectionListActions", () => { diff --git a/test/components/bucket/GroupDataList_test.tsx b/test/components/bucket/GroupDataList_test.tsx index 18ae837a9..b5ebefb58 100644 --- a/test/components/bucket/GroupDataList_test.tsx +++ b/test/components/bucket/GroupDataList_test.tsx @@ -36,6 +36,11 @@ describe("Bucket GroupDataList", () => { expect(screen.queryByText("memberA-1, memberA-2")).toBeDefined(); expect(screen.queryByText("memberB-1, memberB-2")).toBeDefined(); }); + + it("Should render a spinner when showSpinner is true", () => { + renderWithProvider(); + expect(screen.queryByTestId("spinner")).toBeDefined(); + }); }); describe("Bucket GroupListActions", () => { diff --git a/test/components/signoff/SimpleReview/SimpleReview_test.tsx b/test/components/signoff/SimpleReview/SimpleReview_test.tsx index e66a5a6c4..e011692c1 100644 --- a/test/components/signoff/SimpleReview/SimpleReview_test.tsx +++ b/test/components/signoff/SimpleReview/SimpleReview_test.tsx @@ -117,7 +117,7 @@ describe("SimpleTest component", () => { it("should render not reviewable", async () => { renderSimpleReview({ signoff: undefined }); expect( - screen.getByText(/This collection does not support/).textContent + (await screen.findByText(/This collection does not support/)).textContent ).toBe( "This collection does not support reviews, or you do not have permission to review." );
+ +