Skip to content

Commit 705b4db

Browse files
committed
Add a grid view toggle to the dashboard
Signed-off-by: Brent Salisbury <[email protected]>
1 parent b2e508c commit 705b4db

File tree

1 file changed

+64
-3
lines changed

1 file changed

+64
-3
lines changed

src/components/Dashboard/index.tsx

+64-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as React from 'react';
2+
import { useState } from 'react';
23
import { useSession } from 'next-auth/react';
34
import { Label } from '@patternfly/react-core/dist/dynamic/components/Label';
45
import { PageBreadcrumb } from '@patternfly/react-core/dist/dynamic/components/Page';
@@ -27,16 +28,17 @@ import { TextContent } from '@patternfly/react-core/dist/esm/components/Text/Tex
2728
import OutlinedQuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon';
2829
import { Popover } from '@patternfly/react-core/dist/esm/components/Popover';
2930
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
31+
import { Gallery } from '@patternfly/react-core';
3032
import { Modal, ModalVariant } from '@patternfly/react-core/dist/esm/components/Modal/Modal';
31-
import { useState } from 'react';
3233
import { Spinner } from '@patternfly/react-core/dist/esm/components/Spinner';
3334

3435
const Index: React.FunctionComponent = () => {
3536
const { data: session } = useSession();
3637
const [pullRequests, setPullRequests] = React.useState<PullRequest[]>([]);
38+
const [error, setError] = React.useState<string | null>(null);
39+
const [isGridView, setIsGridView] = React.useState(false);
3740
const [isFirstPullDone, setIsFirstPullDone] = React.useState<boolean>(false);
3841
const [isLoading, setIsLoading] = useState<boolean>(true);
39-
//const [error, setError] = React.useState<string | null>(null);
4042
const router = useRouter();
4143

4244
const fetchAndSetPullRequests = React.useCallback(async () => {
@@ -57,6 +59,7 @@ const Index: React.FunctionComponent = () => {
5759

5860
setPullRequests(sortedPRs);
5961
} catch (error) {
62+
setError('Failed to fetch pull requests.');
6063
console.log('Failed to fetch pull requests.' + error);
6164
}
6265
setIsFirstPullDone(true);
@@ -81,6 +84,14 @@ const Index: React.FunctionComponent = () => {
8184
}
8285
};
8386

87+
const handleListViewClick = () => {
88+
setIsGridView(false);
89+
};
90+
91+
const handleGridViewClick = () => {
92+
setIsGridView(true);
93+
};
94+
8495
const handleOnClose = () => {
8596
setIsLoading(false);
8697
};
@@ -119,7 +130,20 @@ const Index: React.FunctionComponent = () => {
119130
</TextContent>
120131
</PageSection>
121132
<PageSection>
122-
<div style={{ marginBottom: '20px' }} />
133+
{/* Only show toggle buttons if there are pull requests */}
134+
{pullRequests.length > 0 && (
135+
<div style={{ marginBottom: '20px' }}>
136+
<Button variant={isGridView ? 'secondary' : 'primary'} onClick={handleListViewClick} style={{ marginRight: '10px' }}>
137+
List View
138+
</Button>
139+
<Button variant={isGridView ? 'primary' : 'secondary'} onClick={handleGridViewClick}>
140+
Grid View
141+
</Button>
142+
</div>
143+
)}
144+
{/* Error message */}
145+
{error && <div>{error}</div>}
146+
{/* Loading modal */}
123147
{!isFirstPullDone && (
124148
<Modal variant={ModalVariant.small} title="Retrieving your submissions" isOpen={isLoading} onClose={() => handleOnClose()}>
125149
<div>
@@ -128,6 +152,7 @@ const Index: React.FunctionComponent = () => {
128152
</div>
129153
</Modal>
130154
)}
155+
{/* Content when no pull requests */}
131156
{isFirstPullDone && pullRequests.length === 0 ? (
132157
<EmptyState>
133158
<EmptyStateHeader
@@ -172,7 +197,43 @@ const Index: React.FunctionComponent = () => {
172197
</EmptyStateActions>
173198
</EmptyStateFooter>
174199
</EmptyState>
200+
) : isGridView ? (
201+
// Grid view
202+
<Gallery hasGutter>
203+
{pullRequests.map((pr) => (
204+
<Card key={pr.number}>
205+
<CardTitle>{pr.title}</CardTitle>
206+
<CardBody>
207+
<Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
208+
<FlexItem>State: {pr.state}</FlexItem>
209+
<FlexItem>Created At: {new Date(pr.created_at).toLocaleString()}</FlexItem>
210+
<FlexItem>Updated At: {new Date(pr.updated_at).toLocaleString()}</FlexItem>
211+
<FlexItem>
212+
{pr.labels.map((label) => (
213+
<Label key={label.name} color="blue" style={{ marginRight: '5px' }}>
214+
{label.name}
215+
</Label>
216+
))}
217+
</FlexItem>
218+
<FlexItem alignSelf={{ default: 'alignSelfFlexEnd' }} flex={{ default: 'flexNone' }}>
219+
<Button variant="secondary" component="a" href={pr.html_url} target="_blank" rel="noopener noreferrer">
220+
View PR
221+
</Button>
222+
</FlexItem>
223+
<FlexItem alignSelf={{ default: 'alignSelfFlexEnd' }} flex={{ default: 'flexNone' }}>
224+
{pr.state === 'open' && (
225+
<Button variant="primary" onClick={() => handleEditClick(pr)}>
226+
Edit
227+
</Button>
228+
)}
229+
</FlexItem>
230+
</Flex>
231+
</CardBody>
232+
</Card>
233+
))}
234+
</Gallery>
175235
) : (
236+
// List view (Stack)
176237
<Stack hasGutter>
177238
{pullRequests.map((pr) => (
178239
<StackItem key={pr.number}>

0 commit comments

Comments
 (0)