Skip to content

Commit

Permalink
feat: Service catalog (#1629)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciaszczykm authored Dec 5, 2024
1 parent 745dd94 commit 44af29a
Show file tree
Hide file tree
Showing 29 changed files with 1,905 additions and 392 deletions.
2 changes: 1 addition & 1 deletion assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@nivo/pie": "0.87.0",
"@nivo/radial-bar": "0.87.0",
"@nivo/tooltip": "0.87.0",
"@pluralsh/design-system": "^4.2.0",
"@pluralsh/design-system": "4.2.0",
"@react-hooks-library/core": "0.6.0",
"@saas-ui/use-hotkeys": "1.1.3",
"@tanstack/react-table": "8.20.5",
Expand Down
141 changes: 141 additions & 0 deletions assets/src/components/catalog/Catalog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import {
AppIcon,
Button,
Chip,
Flex,
PersonIcon,
PrQueueIcon,
Sidecar,
SidecarItem,
useSetBreadcrumbs,
} from '@pluralsh/design-system'
import { useTheme } from 'styled-components'
import { useMemo, useState } from 'react'
import { breadcrumbs } from './Catalogs.tsx'
import { StackedText } from '../utils/table/StackedText.tsx'
import { catalogImageUrl } from './common.ts'
import { ResponsiveLayoutPage } from '../utils/layout/ResponsiveLayoutPage.tsx'
import { useCatalogQuery } from '../../generated/graphql.ts'
import { CATALOG_PARAM_ID } from '../../routes/catalogRoutesConsts.tsx'
import { useParams } from 'react-router-dom'
import LoadingIndicator from '../utils/LoadingIndicator.tsx'
import { GqlError } from '../utils/Alert.tsx'

import { CatalogPRAutomations } from './CatalogPRAutomations.tsx'
import { CatalogPermissions } from './CatalogPermissions.tsx'

export function Catalog() {
const theme = useTheme()
const id = useParams()[CATALOG_PARAM_ID] as string
const [permissionsOpen, setPermissionsOpen] = useState(false)

const { data, refetch, error } = useCatalogQuery({ variables: { id } })

const catalog = data?.catalog

useSetBreadcrumbs(
useMemo(
() => [...breadcrumbs, { label: catalog?.name ?? id }],
[catalog?.name, id]
)
)

if (error) return <GqlError error={error} />

if (!catalog) return <LoadingIndicator />

return (
<ResponsiveLayoutPage css={{ flexDirection: 'column' }}>
<div
css={{
alignSelf: 'center',
maxWidth: theme.breakpoints.desktop,
overflow: 'hidden',
width: '100%',

[`@media (min-width: 1833px)`]: {
maxWidth: theme.breakpoints.desktop + theme.spacing.large + 220, // Increased by sidecar and spacing size.
},
}}
>
<Flex height="100%">
<Flex
direction="column"
grow={1}
>
<div
css={{
alignItems: 'center',
borderBottom: theme.borders['fill-two'],
display: 'flex',
gap: theme.spacing.large,
justifyContent: 'space-between',
paddingBottom: theme.spacing.large,
marginBottom: theme.spacing.large,
}}
>
<Flex
align="center"
gap="medium"
>
<AppIcon
size="xsmall"
url={catalogImageUrl(
catalog.icon,
catalog.darkIcon,
theme.mode
)}
icon={<PrQueueIcon size={32} />}
/>
<StackedText
first={catalog.name}
second={catalog.description}
firstPartialType="subtitle1"
secondPartialType="body2"
/>
</Flex>
<div
css={{
display: 'flex',
gap: theme.spacing.medium,
}}
>
<Button
secondary
startIcon={<PersonIcon />}
onClick={() => setPermissionsOpen(true)}
>
Permissions
</Button>
<CatalogPermissions
catalog={catalog}
refetch={refetch}
open={permissionsOpen}
onClose={() => setPermissionsOpen(false)}
/>
</div>
</div>
<CatalogPRAutomations catalogId={id} />
</Flex>
<Sidecar
height={'fit-content'}
marginLeft={'large'}
width={220}
>
<SidecarItem heading="Author">{catalog.author}</SidecarItem>
{catalog.category && (
<SidecarItem heading="Category">
<Chip
border="none"
size="small"
>
{catalog.category}
</Chip>
</SidecarItem>
)}
</Sidecar>
</Flex>
</div>
</ResponsiveLayoutPage>
)
}
57 changes: 57 additions & 0 deletions assets/src/components/catalog/CatalogPRAutomations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Table } from '@pluralsh/design-system'
import { columns } from '../pr/automations/PrAutomationsColumns.tsx'
import {
DEFAULT_REACT_VIRTUAL_OPTIONS,
useFetchPaginatedData,
} from '../utils/table/useFetchPaginatedData.tsx'
import { usePrAutomationsQuery } from 'generated/graphql'
import { useMemo } from 'react'
import { mapExistingNodes } from '../../utils/graphql.ts'
import { FullHeightTableWrap } from 'components/utils/layout/FullHeightTableWrap'
import { GqlError } from 'components/utils/Alert'
import LoadingIndicator from '../utils/LoadingIndicator.tsx'

export function CatalogPRAutomations({ catalogId }: { catalogId: string }) {
const {
data,
loading,
error,
refetch,
pageInfo,
fetchNextPage,
setVirtualSlice,
} = useFetchPaginatedData(
{ queryHook: usePrAutomationsQuery, keyPath: ['prAutomations'] },
{ catalogId }
)

const prAutomations = useMemo(
() => mapExistingNodes(data?.prAutomations),
[data?.prAutomations]
)

if (error) return <GqlError error={error} />

if (!prAutomations && loading) return <LoadingIndicator />

return (
<FullHeightTableWrap>
<Table
columns={columns}
reactTableOptions={{ meta: { refetch } }}
reactVirtualOptions={DEFAULT_REACT_VIRTUAL_OPTIONS}
data={prAutomations}
virtualizeRows
hasNextPage={pageInfo?.hasNextPage}
fetchNextPage={fetchNextPage}
isFetchingNextPage={loading}
onVirtualSliceChange={setVirtualSlice}
emptyStateProps={{ message: 'No PR automations found.' }}
css={{
maxHeight: 'unset',
height: '100%',
}}
/>
</FullHeightTableWrap>
)
}
Loading

0 comments on commit 44af29a

Please sign in to comment.