From 907c006102447ec127b168feaf8c20c7453f771d Mon Sep 17 00:00:00 2001 From: KevinBacas Date: Fri, 19 Jul 2024 23:49:59 +0200 Subject: [PATCH] chore: Update layout component, metadata, and prettier configuration feat: add github actions overview --- .prettierrc | 2 +- app/github-actions/page.tsx | 35 ++++ app/layout.tsx | 10 +- components/Header.tsx | 8 +- .../github-actions/GitHubWorkflowCard.tsx | 186 +++++++++--------- .../github-actions/GitHubWorkflowGrid.tsx | 27 ++- .../github-actions/GitHubWorkflowHandler.tsx | 120 +++++------ .../groupes-parlementaires/GroupeGrid.tsx | 2 +- .../groupes-parlementaires/GroupesHandler.tsx | 4 +- lib/react-custom-hooks/useSupabaseSession.tsx | 32 +-- lib/supabase/Client.ts | 4 +- package.json | 4 +- yarn.lock | 12 ++ 13 files changed, 246 insertions(+), 200 deletions(-) create mode 100644 app/github-actions/page.tsx diff --git a/.prettierrc b/.prettierrc index ea9ebdb..5ac85e2 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,4 @@ { "printWidth": 100, "singleQuote": true -} \ No newline at end of file +} diff --git a/app/github-actions/page.tsx b/app/github-actions/page.tsx new file mode 100644 index 0000000..0aec022 --- /dev/null +++ b/app/github-actions/page.tsx @@ -0,0 +1,35 @@ +'use client'; + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +import GitHubWorkflowGrid from '../../components/github-actions/GitHubWorkflowGrid'; +import useSupabaseSession from '../../lib/react-custom-hooks/useSupabaseSession'; + +export default function Page() { + const session = useSupabaseSession(); + + console.log({ session }); + + if (session === null) { + return ( + + {'You must log in first.'} + + ); + } + + if (session.provider_token === null || session.provider_token === undefined) { + return ( + + {'Something wrong happened, please ty again later.'} + + ); + } + const queryClient = new QueryClient(); + + return ( + + + + ); +} diff --git a/app/layout.tsx b/app/layout.tsx index a4368f3..1f97627 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -18,11 +18,11 @@ export default function RootLayout({ children }: { children: React.ReactNode }) return ( - -
-
- {children} -
+ +
+
+ {children} +
); diff --git a/components/Header.tsx b/components/Header.tsx index 7f747d5..cdbd944 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -18,10 +18,10 @@ const routes = [ Label: 'Home', URL: '/', }, - // { - // Label: 'Groupes', - // URL: '/groupes-parlementaires', - // }, + { + Label: 'GitHub Actions', + URL: '/github-actions', + }, // { // Label: 'Files', // URL: '/files', diff --git a/components/github-actions/GitHubWorkflowCard.tsx b/components/github-actions/GitHubWorkflowCard.tsx index cb74955..479dd18 100644 --- a/components/github-actions/GitHubWorkflowCard.tsx +++ b/components/github-actions/GitHubWorkflowCard.tsx @@ -1,104 +1,100 @@ -// import React from 'react'; -// import { Box, Button, Heading, IconButton, Text } from '@chakra-ui/react'; -// import Link from 'next/link'; -// import { formatDistanceToNow, parseJSON } from 'date-fns'; -// import { ImCross } from 'react-icons/im'; -// import { FaSync, FaCheck, FaSlash, FaCog } from 'react-icons/fa'; -// import { useQuery, UseQueryResult } from 'react-query'; -// import { GetJobs } from '../../lib/github/Workflows'; -// import Spinner from '../common/Spinner'; +'use client'; -// interface EnhancedWorkflowRun extends Types.External.WorkflowRun { -// parentReactQuery: UseQueryResult; -// } +import React from 'react'; +import Link from 'next/link'; +import { formatDistanceToNow, parseJSON } from 'date-fns'; +import { ImCross } from 'react-icons/im'; +import { FaSync, FaCheck, FaSlash, FaCog, FaCodeBranch, FaClock } from 'react-icons/fa'; +import { Badge, Card, Chip, Spacer, Spinner, Tooltip } from '@nextui-org/react'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; -// interface IGitHubWorkflowCardProps extends EnhancedWorkflowRun { -// githubToken: string; -// } +import { GetJobs } from '../../lib/github/Workflows'; -// const statusToBg = { -// success: 'bg-teal-600', -// failure: 'bg-red-600', -// in_progress: '', -// }; +interface EnhancedWorkflowRun extends Types.External.WorkflowRun { + parentReactQuery: UseQueryResult; +} -// const jobStatusToBg = { -// cancelled: 'bg-gray-500', -// success: 'bg-green-500', -// failure: 'bg-red-500', -// in_progress: 'bg-yellow-500', -// skipped: 'bg-gray-500', -// }; +interface IGitHubWorkflowCardProps extends EnhancedWorkflowRun { + githubToken: string; +} -// export default function GitHubWorkflowCard(props: IGitHubWorkflowCardProps) { -// const { data, isLoading } = useQuery( -// ['github-jobs', props.repository.name, props.id], -// () => GetJobs(props.githubToken, props.repository.name, props.id.toString()), -// { -// refetchInterval: (data) => -// data ? (data.jobs.some((j) => j.status !== 'completed') ? 5000 : false) : false, -// refetchOnWindowFocus: (data) => data.state.data.jobs.some((j) => j.status !== 'completed'), -// refetchIntervalInBackground: false, -// }, -// ); +const jobStatusToColor = { + cancelled: 'default', + success: 'success', + failure: 'danger', + in_progress: 'warning', + skipped: 'default', +}; -// return ( -//
-//
-//
-// -// -// {props.repository.name} -// -// -// -// {props.conclusion} -// -//
-// {/* : } -// onClick={() => refetch()} -// isDisabled={isFetching} -// /> */} -//
+export default function GitHubWorkflowCard(props: IGitHubWorkflowCardProps) { + const { data, isLoading } = useQuery({ + queryKey: ['github-jobs', props.repository.name, props.id], + queryFn: () => GetJobs(props.githubToken, props.repository.name, props.id.toString()), + refetchInterval: (data) => + data.state.data?.jobs.some((j) => j.status !== 'completed') ? 30000 : false, + refetchOnWindowFocus: (data) => + data.state.data?.jobs.some((j) => j.status !== 'completed') ?? false, + refetchIntervalInBackground: false, + }); -//
{props.head_branch}
+ return ( + +
+ + + {props.repository.name} + + + + {props.conclusion === 'success' ? 'Success' : 'Error'} + +
-//
-// {formatDistanceToNow(parseJSON(props.created_at))} -//
+ -// {isLoading ? ( -//
-// -//
-// ) : ( -//
-// {data.jobs.map((j) => { -// const currentStatus = j.status === 'completed' ? j.conclusion : j.status; -// return ( -//
-// {currentStatus === 'cancelled' && } -// {currentStatus === 'in_progress' && } -// {currentStatus === 'failure' && } -// {currentStatus === 'success' && } -// {currentStatus === 'skipped' && } -// -// {j.name} -// -//
-// ); -// })} -//
-// )} -//
-// ); -// } + + + +
{props.head_branch}
+ + + + +
+ + +
+ {formatDistanceToNow(parseJSON(props.created_at), { + addSuffix: true, + includeSeconds: true, + })} +
+
+ + + +
+ {data?.jobs.map((j) => { + const currentStatus = j.status === 'completed' ? j.conclusion : j.status; + return ( + + + {currentStatus === 'cancelled' && } + {currentStatus === 'in_progress' && } + {currentStatus === 'failure' && } + {currentStatus === 'success' && } + {currentStatus === 'skipped' && } + + + ); + })} +
+ + ); +} diff --git a/components/github-actions/GitHubWorkflowGrid.tsx b/components/github-actions/GitHubWorkflowGrid.tsx index 0d76f53..256888c 100644 --- a/components/github-actions/GitHubWorkflowGrid.tsx +++ b/components/github-actions/GitHubWorkflowGrid.tsx @@ -1,16 +1,15 @@ -// import { SimpleGrid } from '@chakra-ui/react'; -// import React from 'react'; -// import GitHubWorkflowHandler from './GitHubWorkflowHandler'; +import React from 'react'; +import GitHubWorkflowHandler from './GitHubWorkflowHandler'; -// interface IGitHubWorkflowGridProps { -// githubToken: string; -// } +interface IGitHubWorkflowGridProps { + githubToken: string; +} -// export default function GitHubWorkflowGrid(props: IGitHubWorkflowGridProps) { -// return ( -// -// ); -// } +export default function GitHubWorkflowGrid(props: IGitHubWorkflowGridProps) { + return ( + + ); +} diff --git a/components/github-actions/GitHubWorkflowHandler.tsx b/components/github-actions/GitHubWorkflowHandler.tsx index 1f4fa2c..15b8870 100644 --- a/components/github-actions/GitHubWorkflowHandler.tsx +++ b/components/github-actions/GitHubWorkflowHandler.tsx @@ -1,58 +1,62 @@ -// import React, { useEffect, useState } from 'react'; -// import { useQueries, UseQueryResult } from 'react-query'; -// import { GetWorkflows } from '../../lib/github/Workflows'; -// import Spinner from '../common/Spinner'; -// import GitHubWorkflowCard from './GitHubWorkflowCard'; -// import orderBy from 'lodash/orderBy'; - -// interface IGitHubWorkflowHandlerProps { -// githubToken: string; -// repositoriesName: string[]; -// } - -// interface EnhancedWorkflowRun extends Types.External.WorkflowRun { -// parentReactQuery: UseQueryResult; -// } - -// function orderWorkflows( -// queries: UseQueryResult[], -// ): EnhancedWorkflowRun[] { -// return orderBy( -// queries.flatMap((q) => -// q.data.workflow_runs.map((run) => Object.assign({}, run, { parentReactQuery: q })), -// ), -// 'created_at', -// 'desc', -// ); -// } - -// export default function GitHubWorkflowHandler(props: IGitHubWorkflowHandlerProps) { -// const [workflows, setWorkflows] = useState([]); -// const queries = useQueries( -// props.repositoriesName.map((repositoryName) => ({ -// queryKey: ['github-repos', repositoryName], -// queryFn: () => GetWorkflows(props.githubToken, repositoryName), -// refetchInterval: 30000, -// refetchOnWindowFocus: true, -// refetchIntervalInBackground: false, -// })), -// ); - -// useEffect(() => { -// if (!queries.some((q) => q.isLoading)) { -// setWorkflows(orderWorkflows(queries)); -// } -// }, [queries.some((q) => q.isLoading)]); - -// return queries.some((q) => q.isLoading) ? ( -//
-// -//
-// ) : ( -//
-// {workflows.map((run) => { -// return ; -// })} -//
-// ); -// } +'use client'; + +import React, { useEffect, useState } from 'react'; +import { useQueries, UseQueryResult } from '@tanstack/react-query'; +import orderBy from 'lodash/orderBy'; +import { Spinner } from '@nextui-org/react'; + +import GitHubWorkflowCard from './GitHubWorkflowCard'; +import { GetWorkflows } from '../../lib/github/Workflows'; + +interface IGitHubWorkflowHandlerProps { + githubToken: string; + repositoriesName: string[]; +} + +interface EnhancedWorkflowRun extends Types.External.WorkflowRun { + parentReactQuery: UseQueryResult; +} + +function orderWorkflows( + queries: UseQueryResult[], +): EnhancedWorkflowRun[] { + return orderBy( + queries.flatMap( + (q) => + q.data?.workflow_runs.map((run) => Object.assign({}, run, { parentReactQuery: q })) || [], + ), + 'created_at', + 'desc', + ); +} + +export default function GitHubWorkflowHandler(props: IGitHubWorkflowHandlerProps) { + const [workflows, setWorkflows] = useState([]); + const queries = useQueries({ + queries: props.repositoriesName.map((repositoryName) => ({ + queryKey: ['github-repos', repositoryName], + queryFn: () => GetWorkflows(props.githubToken, repositoryName), + refetchInterval: 30000, + refetchOnWindowFocus: true, + refetchIntervalInBackground: false, + })), + }); + + useEffect(() => { + if (!queries.some((q) => q.isLoading)) { + setWorkflows(orderWorkflows(queries)); + } + }, [queries.some((q) => q.isLoading)]); + + return queries.some((q) => q.isLoading) ? ( +
+ +
+ ) : ( +
+ {workflows.map((run) => { + return ; + })} +
+ ); +} diff --git a/components/groupes-parlementaires/GroupeGrid.tsx b/components/groupes-parlementaires/GroupeGrid.tsx index e297ee9..88ba4df 100644 --- a/components/groupes-parlementaires/GroupeGrid.tsx +++ b/components/groupes-parlementaires/GroupeGrid.tsx @@ -10,7 +10,7 @@ interface IGroupeGrid { export default function GroupeGrid(props: IGroupeGrid) { return ( -
+
{sortBy(props.GroupesParlementaires, ['Ordre']).map((gp) => ( { toast.error('Failed to update staging: ' + err.message); setIsUpdatingStaging(false); - console.error(err) + console.error(err); }); }; @@ -91,7 +91,7 @@ export default function GroupesHandler() {
) : ( <> -
+