Skip to content

Commit

Permalink
Setup Wizard: Site Admin Repo Sync view (sourcegraph#47141)
Browse files Browse the repository at this point in the history
Closes sourcegraph#47110
([Figma](https://www.figma.com/file/EuRdjjQF8a9kRJMRce4HyI/UX%3A-Instance-setup-experience?node-id=746%3A13794&t=oLVPzFL3CY2X4dkO-0)).
Reuses Site Admin Repo Sync view with a design refresh & button action
updates.

**In action clip**:

https://user-images.githubusercontent.com/59381432/216470321-cda294a0-8821-4a2f-ab17-50c72398d96c.mov
<img width="1378" alt="Screenshot 2023-02-08 at 5 09 35 PM"
src="https://user-images.githubusercontent.com/59381432/217585873-26f4e4c7-527f-4055-a32c-7f35c80a08bc.png">
<img width="1064" alt="Screenshot 2023-02-08 at 5 11 17 PM"
src="https://user-images.githubusercontent.com/59381432/217585949-6aff7078-82c1-4fad-ac37-4f6acdb2d6e6.png">


## Changelog
- Makes `<SiteAdminRepositories />` flexible to be reused in our use
case
- Implement dark/light theme color styles
- Move conditional /setup route with other routes for dark/light theme
color constant access

#### Design refresh for `<SiteAdminRepositoriesPage />`:
- Add Badge for repo status
- Rework `<RepoMirrorInfo />` because new status UI will overtake some
of this visual data
- Add loading state (no % available)

## Test plan
- Turn setup feature flag on in settings (`"experimentalFeatures": {
"setupWizard": true }`)
- Visit `/site-admin/repositories` or `/setup` to view changed
components

## Note
- Note, Footer is out of view on page. I think if we contain this info
in a smaller scrollable vertical space it will be too squished though.
Open to other thoughts!
**Follow up issues**: ~sourcegraph#47393~, sourcegraph#47394, sourcegraph#47395

## App preview:

-
[Web](https://sg-web-becca-setup-wiz-sync-repo-step.onrender.com/search)

Check out the [client app preview
documentation](https://docs.sourcegraph.com/dev/how-to/client_pr_previews)
to learn more.
  • Loading branch information
st0nebreaker committed Feb 21, 2023
1 parent 2dd4394 commit 7bd3a02
Show file tree
Hide file tree
Showing 13 changed files with 664 additions and 520 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
gap: 0.5rem;
max-width: 60%;
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const FilterControl: React.FunctionComponent<React.PropsWithChildren<Filt
onChange={event => onChange(filter, event.currentTarget.value)}
value={values.get(filter.id)?.value}
className="mb-0"
isCustomStyle={true}
>
{filter.values.map(value => (
<option key={value.value} value={value.value} label={value.label} />
Expand Down
18 changes: 18 additions & 0 deletions client/web/src/setup-wizard/Setup.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
:global(.theme-dark) {
--header-gradient: radial-gradient(
130.33% 541.14% at 48.47% 231.96%,
var(--violet-06) 0%,
var(--violet-07) 42.62%,
var(--violet-08) 68.83%
);
}
:global(.theme-light) {
--header-gradient: radial-gradient(
113.96% 113.96% at 50% -8.21%,
var(--violet-06) 0%,
var(--violet-07) 57.81%,
var(--violet-08) 100%
);
}

.root {
width: 100%;
height: 100%;
Expand All @@ -6,6 +23,7 @@
}

.header {
background: var(--header-gradient);
background: radial-gradient(
130.33% 541.14% at 48.47% 231.96%,
var(--violet-06) 17.19%,
Expand Down
18 changes: 16 additions & 2 deletions client/web/src/setup-wizard/SetupWizard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { FC, ReactElement, useCallback } from 'react'

import { useTemporarySetting } from '@sourcegraph/shared/src/settings/temporary'
import { H1, H2 } from '@sourcegraph/wildcard'
import { H1, H2, Text } from '@sourcegraph/wildcard'

import { BrandLogo } from '../components/branding/BrandLogo'
import { PageTitle } from '../components/PageTitle'
import { SiteAdminRepositoriesContainer } from '../site-admin/SiteAdminRepositoriesContainer'

import { RemoteRepositoriesStep } from './components/remote-repositories-step'
import { SetupStepsRoot, StepConfiguration } from './components/setup-steps'
Expand All @@ -27,7 +29,7 @@ const SETUP_STEPS: StepConfiguration[] = [
id: '003',
name: 'Sync repositories',
path: '/setup/sync-repositories',
component: () => <H2>Hello sync repositories step</H2>,
component: SyncRepositoriesStep,
},
]

Expand All @@ -47,6 +49,7 @@ export const SetupWizard: FC = () => {

return (
<div className={styles.root}>
<PageTitle title="Setup" />
<header className={styles.header}>
<BrandLogo variant="logo" isLightTheme={false} className={styles.logo} />

Expand All @@ -63,3 +66,14 @@ export const SetupWizard: FC = () => {
function LocalRepositoriesStep(props: any): ReactElement {
return <H2 {...props}>Hello local repositories step</H2>
}

function SyncRepositoriesStep(props: any): ReactElement {
return (
<section {...props}>
<Text>
It may take a few moments to clone and index each repository. Repository statuses are displayed below.
</Text>
<SiteAdminRepositoriesContainer />
</section>
)
}
38 changes: 38 additions & 0 deletions client/web/src/site-admin/RepositoryNode.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.alert-wrapper {
margin-top: 1rem;
overflow-y: auto;
max-height: 25rem;
}

.badge-wrapper {
min-width: 100px;
}

.alert-content {
white-space: break-spaces;
}

.cloned {
background-color: var(--success) !important;
color: var(--white) !important;
}

.queued {
background-color: transparent !important;
border: 1px solid var(--text-muted);
color: var(--text-muted) !important;
}

.failed {
background-color: var(--warning) !important;
color: var(--white) !important;
}

.error-content {
max-width: 600px;
}

.alert-overflow {
max-height: 300px;
overflow-y: auto;
}
143 changes: 143 additions & 0 deletions client/web/src/site-admin/RepositoryNode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { useState } from 'react'

import { mdiCog, mdiClose, mdiFileDocumentOutline } from '@mdi/js'
import classNames from 'classnames'

import { RepoLink } from '@sourcegraph/shared/src/components/RepoLink'
import {
Alert,
Badge,
Button,
Icon,
Link,
H4,
LoadingSpinner,
Tooltip,
LinkOrSpan,
PopoverTrigger,
PopoverContent,
PopoverTail,
Popover,
Position,
MenuDivider,
} from '@sourcegraph/wildcard'

import { SiteAdminRepositoryFields } from '../graphql-operations'

import { ExternalRepositoryIcon } from './components/ExternalRepositoryIcon'
import { RepoMirrorInfo } from './components/RepoMirrorInfo'

import styles from './RepositoryNode.module.scss'

const RepositoryStatusBadge: React.FunctionComponent<{ status: string }> = ({ status }) => (
<Badge className={classNames(styles[status as keyof typeof styles], 'py-0 px-1 text-uppercase font-weight-normal')}>
{status}
</Badge>
)

const parseRepositoryStatus = (repository: SiteAdminRepositoryFields): string => {
let status = 'queued'
if (repository.mirrorInfo.cloned && !repository.mirrorInfo.lastError) {
status = 'cloned'
} else if (repository.mirrorInfo.cloneInProgress) {
status = 'cloning'
} else if (repository.mirrorInfo.lastError) {
status = 'failed'
}
return status
}

interface RepositoryNodeProps {
node: SiteAdminRepositoryFields
}

export const RepositoryNode: React.FunctionComponent<React.PropsWithChildren<RepositoryNodeProps>> = ({ node }) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false)

return (
<li
className="repository-node list-group-item px-0 py-2"
data-test-repository={node.name}
data-test-cloned={node.mirrorInfo.cloned}
>
<div className="d-flex align-items-center justify-content-between">
<div className="d-flex col-7 pl-0">
<div className={classNames('d-flex col-2 px-0 justify-content-between h-100', styles.badgeWrapper)}>
<RepositoryStatusBadge status={parseRepositoryStatus(node)} />
{node.mirrorInfo.cloneInProgress && <LoadingSpinner />}
</div>

<div className="d-flex flex-column ml-2">
<div>
<ExternalRepositoryIcon externalRepo={node.externalRepository} />
<RepoLink repoName={node.name} to={node.url} />
</div>
<RepoMirrorInfo mirrorInfo={node.mirrorInfo} />
</div>
</div>

<div className="col-auto pr-0">
{/* TODO: Enable 'CLONE NOW' to enqueue the repo
{!node.mirrorInfo.cloned && !node.mirrorInfo.cloneInProgress && !node.mirrorInfo.lastError && (
<Button to={node.url} variant="secondary" size="sm" as={Link}>
<Icon aria-hidden={true} svgPath={mdiCloudDownload} /> Clone now
</Button>
)}{' '} */}
{node.mirrorInfo.cloned && !node.mirrorInfo.lastError && !node.mirrorInfo.cloneInProgress && (
<Tooltip content="Repository settings">
<Button to={`/${node.name}/-/settings`} variant="secondary" size="sm" as={Link}>
<Icon aria-hidden={true} svgPath={mdiCog} /> Settings
</Button>
</Tooltip>
)}
{node.mirrorInfo.lastError && (
<Popover isOpen={isPopoverOpen} onOpenChange={event => setIsPopoverOpen(event.isOpen)}>
<PopoverTrigger as={Button} variant="secondary" size="sm" aria-label="See errors">
<Icon aria-hidden={true} svgPath={mdiFileDocumentOutline} /> See errors
</PopoverTrigger>

<PopoverContent position={Position.left} className={styles.errorContent}>
<div className="d-flex">
<H4 className="m-2">
<RepositoryStatusBadge status={parseRepositoryStatus(node)} />
<ExternalRepositoryIcon
externalRepo={node.externalRepository}
className="mx-2"
/>
<RepoLink repoName={node.name} to={null} />
</H4>

<Button
aria-label="Dismiss error"
variant="icon"
className="ml-auto mr-2"
onClick={() => setIsPopoverOpen(false)}
>
<Icon aria-hidden={true} svgPath={mdiClose} />
</Button>
</div>

<MenuDivider />

<Alert variant="warning" className={classNames('m-2', styles.alertOverflow)}>
<H4>Error syncing repository:</H4>
{node.mirrorInfo.lastError}
</Alert>
</PopoverContent>
<PopoverTail size="sm" />
</Popover>
)}
</div>
</div>

{node.mirrorInfo.isCorrupted && (
<div className={styles.alertWrapper}>
<Alert variant="danger">
Repository is corrupt.{' '}
<LinkOrSpan to={`/${node.name}/-/settings/mirror`}>More details</LinkOrSpan>
</Alert>
</div>
)}
</li>
)
}
Loading

0 comments on commit 7bd3a02

Please sign in to comment.