[UI] Consume Latest OpenAPI Specs (#134)

* regenerate CODE service code to match latest API specs

* update readme
jobatzil/rename
Johannes Batzill 2022-12-22 21:58:38 -08:00 committed by GitHub
parent 9da9aa42b5
commit 63c3740e58
10 changed files with 1294 additions and 762 deletions

View File

@ -59,6 +59,18 @@ This project includes a simple user interface for interacting with the system. W
This project includes a swagger specification. When you run the application, you can access the swagger specification by navigating to `http://localhost:3000/swagger` in your browser. This project includes a swagger specification. When you run the application, you can access the swagger specification by navigating to `http://localhost:3000/swagger` in your browser.
## Auto-Generate Gitness API Client used by UI using Swagger
Please make sure to update the autogenerated client code used by the UI when adding new rest APIs.
To regenerate the code, please execute the following steps:
- Run local gitness instance with latest changes
- Get latest OpenAPI specs from `http://localhost:3000/openapi.yaml` and store it in `web/src/services/code/swagger.yaml`
> Simply copy the whole content of the web response and store it in the `swagger.yaml` file
- Regenerate client code by running `yarn services` in the `web` directory
The latest API changes should now be reflected in `web/src/services/code/index.tsx`
# CLI # CLI
This project includes simple command line tools for interacting with the system. Please remember that you must start the server before you can execute commands. This project includes simple command line tools for interacting with the system. Please remember that you must start the server before you can execute commands.

View File

@ -29,8 +29,8 @@ import { useModalHook } from '@harness/use-modal'
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { getErrorMessage } from 'utils/Utils' import { getErrorMessage } from 'utils/Utils'
import { CodeIcon, GitInfoProps } from 'utils/GitUtils' import { CodeIcon, GitInfoProps } from 'utils/GitUtils'
import type { PullRequestPayload, PullRequestResponse } from 'utils/types'
import css from './CreatePullRequestModal.module.scss' import css from './CreatePullRequestModal.module.scss'
import type { OpenapiCreatePullReqRequest, TypesPullReq } from 'services/code'
interface FormData { interface FormData {
title: string title: string
@ -40,7 +40,7 @@ interface FormData {
interface CreatePullRequestModalProps extends Pick<GitInfoProps, 'repoMetadata'> { interface CreatePullRequestModalProps extends Pick<GitInfoProps, 'repoMetadata'> {
targetGitRef: string targetGitRef: string
sourceGitRef: string sourceGitRef: string
onSuccess: (data: PullRequestResponse) => void onSuccess: (data: TypesPullReq) => void
} }
interface CreatePullRequestModalButtonProps extends Omit<ButtonProps, 'onClick'>, CreatePullRequestModalProps {} interface CreatePullRequestModalButtonProps extends Omit<ButtonProps, 'onClick'>, CreatePullRequestModalProps {}
@ -54,18 +54,18 @@ export function useCreatePullRequestModal({
const ModalComponent: React.FC = () => { const ModalComponent: React.FC = () => {
const { getString } = useStrings() const { getString } = useStrings()
const { showError } = useToaster() const { showError } = useToaster()
const { mutate: createPullRequest, loading } = useMutate<PullRequestResponse>({ const { mutate: createPullRequest, loading } = useMutate<TypesPullReq>({
verb: 'POST', verb: 'POST',
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq` path: `/api/v1/repos/${repoMetadata.path}/+/pullreq`
}) })
const handleSubmit = (formData: FormData) => { const handleSubmit = (formData: FormData) => {
const title = get(formData, 'title', '').trim() const title = get(formData, 'title', '').trim()
const description = get(formData, 'description', '').trim() const description = get(formData, 'description', '').trim()
const payload: PullRequestPayload = { const payload: OpenapiCreatePullReqRequest = {
targetBranch: targetGitRef, target_branch: targetGitRef,
sourceBranch: sourceGitRef, source_branch: sourceGitRef,
title, title: title,
description description: description
} }
try { try {

View File

@ -7,13 +7,13 @@ import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
import { getErrorMessage } from 'utils/Utils' import { getErrorMessage } from 'utils/Utils'
import type { PullRequestResponse } from 'utils/types'
import { CodeIcon } from 'utils/GitUtils' import { CodeIcon } from 'utils/GitUtils'
import { PullRequestMetaLine } from './PullRequestMetaLine' import { PullRequestMetaLine } from './PullRequestMetaLine'
import { PullRequestConversation } from './PullRequestConversation/PullRequestConversation' import { PullRequestConversation } from './PullRequestConversation/PullRequestConversation'
import { FilesChanged } from './FilesChanged/FilesChanged' import { FilesChanged } from './FilesChanged/FilesChanged'
import { PullRequestCommits } from './PullRequestCommits/PullRequestCommits' import { PullRequestCommits } from './PullRequestCommits/PullRequestCommits'
import css from './PullRequest.module.scss' import css from './PullRequest.module.scss'
import type { TypesPullReq } from 'services/code'
enum PullRequestSection { enum PullRequestSection {
CONVERSATION = 'conversation', CONVERSATION = 'conversation',
@ -37,7 +37,7 @@ export default function PullRequest() {
data: prData, data: prData,
error: prError, error: prError,
loading: prLoading loading: prLoading
} = useGet<PullRequestResponse>({ } = useGet<TypesPullReq>({
path: `/api/v1/repos/${repoMetadata?.path}/+/pullreq/${pullRequestId}`, path: `/api/v1/repos/${repoMetadata?.path}/+/pullreq/${pullRequestId}`,
lazy: !repoMetadata lazy: !repoMetadata
}) })
@ -110,7 +110,7 @@ export default function PullRequest() {
) )
} }
const PullRequestTitle: React.FC<PullRequestResponse> = ({ title, number }) => ( const PullRequestTitle: React.FC<TypesPullReq> = ({ title, number }) => (
<Text tag="h1" font={{ variation: FontVariation.H4 }}> <Text tag="h1" font={{ variation: FontVariation.H4 }}>
{title} <span className={css.prNumber}>#{number}</span> {title} <span className={css.prNumber}>#{number}</span>
</Text> </Text>

View File

@ -17,7 +17,7 @@ export const PullRequestCommits: React.FC<Pick<GitInfoProps, 'repoMetadata' | 'p
} = useGet<RepoCommit[]>({ } = useGet<RepoCommit[]>({
path: `/api/v1/repos/${repoMetadata?.path}/+/commits`, path: `/api/v1/repos/${repoMetadata?.path}/+/commits`,
queryParams: { queryParams: {
git_ref: pullRequestMetadata.sourceBranch git_ref: pullRequestMetadata.source_branch
}, },
lazy: !repoMetadata lazy: !repoMetadata
}) })

View File

@ -7,14 +7,14 @@ import { useAppContext } from 'AppContext'
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator' import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator'
import { GitRefLink } from 'components/GitRefLink/GitRefLink' import { GitRefLink } from 'components/GitRefLink/GitRefLink'
import type { PullRequestResponse } from 'utils/types'
import css from './PullRequestMetaLine.module.scss' import css from './PullRequestMetaLine.module.scss'
import type { TypesPullReq } from 'services/code'
export const PullRequestMetaLine: React.FC<PullRequestResponse & Pick<GitInfoProps, 'repoMetadata'>> = ({ export const PullRequestMetaLine: React.FC<TypesPullReq & Pick<GitInfoProps, 'repoMetadata'>> = ({
repoMetadata, repoMetadata,
targetBranch, target_branch,
sourceBranch, source_branch,
createdBy = '', author,
updated, updated,
merged, merged,
state state
@ -22,18 +22,18 @@ export const PullRequestMetaLine: React.FC<PullRequestResponse & Pick<GitInfoPro
const { getString } = useStrings() const { getString } = useStrings()
const { routes } = useAppContext() const { routes } = useAppContext()
const vars = { const vars = {
user: <strong>{createdBy}</strong>, user: <strong>{author?.name}</strong>,
number: <strong>5</strong>, // TODO: No data from backend now number: <strong>5</strong>, // TODO: No data from backend now
target: ( target: (
<GitRefLink <GitRefLink
text={targetBranch} text={target_branch!}
url={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef: targetBranch })} url={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef: target_branch })}
/> />
), ),
source: ( source: (
<GitRefLink <GitRefLink
text={sourceBranch} text={source_branch!}
url={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef: sourceBranch })} url={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef: source_branch })}
/> />
) )
} }
@ -47,7 +47,7 @@ export const PullRequestMetaLine: React.FC<PullRequestResponse & Pick<GitInfoPro
</Text> </Text>
<PipeSeparator height={9} /> <PipeSeparator height={9} />
<Text inline className={cx(css.metaline, css.time)}> <Text inline className={cx(css.metaline, css.time)}>
<ReactTimeago date={updated} /> <ReactTimeago date={updated!} />
</Text> </Text>
</Layout.Horizontal> </Layout.Horizontal>
</Container> </Container>

View File

@ -21,11 +21,11 @@ import { useStrings } from 'framework/strings'
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
import { getErrorMessage, LIST_FETCHING_PER_PAGE } from 'utils/Utils' import { getErrorMessage, LIST_FETCHING_PER_PAGE } from 'utils/Utils'
import emptyStateImage from 'images/empty-state.svg' import emptyStateImage from 'images/empty-state.svg'
import type { PullRequestResponse } from 'utils/types'
import { usePageIndex } from 'hooks/usePageIndex' import { usePageIndex } from 'hooks/usePageIndex'
import { PullRequestsContentHeader } from './PullRequestsContentHeader/PullRequestsContentHeader' import { PullRequestsContentHeader } from './PullRequestsContentHeader/PullRequestsContentHeader'
import prOpenImg from './pull-request-open.svg' import prOpenImg from './pull-request-open.svg'
import css from './PullRequests.module.scss' import css from './PullRequests.module.scss'
import type { TypesPullReq } from 'services/code'
export default function PullRequests() { export default function PullRequests() {
const { getString } = useStrings() const { getString } = useStrings()
@ -38,7 +38,7 @@ export default function PullRequests() {
data, data,
error: prError, error: prError,
loading: prLoading loading: prLoading
} = useGet<PullRequestResponse[]>({ } = useGet<TypesPullReq[]>({
path: `/api/v1/repos/${repoMetadata?.path}/+/pullreq`, path: `/api/v1/repos/${repoMetadata?.path}/+/pullreq`,
queryParams: { queryParams: {
per_page: LIST_FETCHING_PER_PAGE, per_page: LIST_FETCHING_PER_PAGE,
@ -50,12 +50,12 @@ export default function PullRequests() {
}, },
lazy: !repoMetadata lazy: !repoMetadata
}) })
const columns: Column<PullRequestResponse>[] = useMemo( const columns: Column<TypesPullReq>[] = useMemo(
() => [ () => [
{ {
id: 'title', id: 'title',
width: '100%', width: '100%',
Cell: ({ row }: CellProps<PullRequestResponse>) => { Cell: ({ row }: CellProps<TypesPullReq>) => {
return ( return (
<Layout.Horizontal spacing="medium" padding={{ left: 'medium' }}> <Layout.Horizontal spacing="medium" padding={{ left: 'medium' }}>
<img src={prOpenImg} /> <img src={prOpenImg} />
@ -69,8 +69,8 @@ export default function PullRequests() {
str={getString('pr.openBy')} str={getString('pr.openBy')}
vars={{ vars={{
number: <Text inline>{row.original.number}</Text>, number: <Text inline>{row.original.number}</Text>,
time: <ReactTimeago date={row.original.updated} />, time: <ReactTimeago date={row.original.created!} />,
user: row.original.createdBy user: row.original.author?.name
}} }}
/> />
</Text> </Text>
@ -131,7 +131,7 @@ export default function PullRequests() {
/> />
{!!data?.length && ( {!!data?.length && (
<Container padding="xlarge"> <Container padding="xlarge">
<TableV2<PullRequestResponse> <TableV2<TypesPullReq>
className={css.table} className={css.table}
hideHeaders hideHeaders
columns={columns} columns={columns}

View File

@ -11,6 +11,8 @@ export type EnumParentResourceType = string
export type EnumPathTargetType = string export type EnumPathTargetType = string
export type EnumPullReqState = string
export type EnumTokenType = string export type EnumTokenType = string
export interface FormDataOpenapiLoginRequest { export interface FormDataOpenapiLoginRequest {
@ -59,6 +61,14 @@ export interface OpenapiCreatePathRequest {
path?: string path?: string
} }
export interface OpenapiCreatePullReqRequest {
description?: string
source_branch?: string
source_repo_ref?: string
target_branch?: string
title?: string
}
export interface OpenapiCreateRepoPathRequest { export interface OpenapiCreateRepoPathRequest {
path?: string path?: string
} }
@ -112,6 +122,11 @@ export interface OpenapiMoveSpaceRequest {
uid?: string | null uid?: string | null
} }
export interface OpenapiUpdatePullReqRequest {
description?: string
title?: string
}
export interface OpenapiUpdateRepoRequest { export interface OpenapiUpdateRepoRequest {
description?: string | null description?: string | null
isPublic?: boolean | null isPublic?: boolean | null
@ -220,6 +235,33 @@ export interface TypesPath {
value?: string value?: string
} }
export type TypesPrincipalInfo = {
email?: string
id?: number
name?: string
uid?: string
} | null
export interface TypesPullReq {
author?: TypesPrincipalInfo
created?: number
description?: string
edited?: number
id?: number
merge_strategy?: string | null
merged?: number | null
merger?: TypesPrincipalInfo
number?: number
source_branch?: string
source_repo_id?: number
state?: EnumPullReqState
target_branch?: string
target_repo_id?: number
title?: string
updated?: number
version?: number
}
export interface TypesRepository { export interface TypesRepository {
created?: number created?: number
createdBy?: number createdBy?: number
@ -911,6 +953,169 @@ export const useDeleteRepositoryPath = ({ repoRef, ...props }: UseDeleteReposito
{ base: getConfigNew('code'), pathParams: { repoRef }, ...props } { base: getConfigNew('code'), pathParams: { repoRef }, ...props }
) )
export interface ListPullReqQueryParams {
/**
* The state of the pull requests to include in the result.
*/
state?: ('open' | 'closed' | 'merged' | 'rejected')[]
/**
* Source repository ref of the pull requests.
*/
source_repo_ref?: string
/**
* Source branch of the pull requests.
*/
source_branch?: string
/**
* Target branch of the pull requests.
*/
target_branch?: string
/**
* The substring by which the pull requests are filtered.
*/
query?: string
/**
* The principal ID who created pull requests.
*/
created_by?: number
/**
* The order of the output.
*/
direction?: 'asc' | 'desc'
/**
* The data by which the pull requests are sorted.
*/
sort?: 'number' | 'created' | 'updated'
/**
* The page to return.
*/
page?: number
/**
* The number of entries returned per page.
*/
per_page?: number
}
export interface ListPullReqPathParams {
repoRef: string
}
export type ListPullReqProps = Omit<
GetProps<TypesPullReq[], UsererrorError, ListPullReqQueryParams, ListPullReqPathParams>,
'path'
> &
ListPullReqPathParams
export const ListPullReq = ({ repoRef, ...props }: ListPullReqProps) => (
<Get<TypesPullReq[], UsererrorError, ListPullReqQueryParams, ListPullReqPathParams>
path={`/repos/${repoRef}/pullreq`}
base={getConfigNew('code')}
{...props}
/>
)
export type UseListPullReqProps = Omit<
UseGetProps<TypesPullReq[], UsererrorError, ListPullReqQueryParams, ListPullReqPathParams>,
'path'
> &
ListPullReqPathParams
export const useListPullReq = ({ repoRef, ...props }: UseListPullReqProps) =>
useGet<TypesPullReq[], UsererrorError, ListPullReqQueryParams, ListPullReqPathParams>(
(paramsInPath: ListPullReqPathParams) => `/repos/${paramsInPath.repoRef}/pullreq`,
{ base: getConfigNew('code'), pathParams: { repoRef }, ...props }
)
export interface CreatePullReqPathParams {
repoRef: string
}
export type CreatePullReqProps = Omit<
MutateProps<TypesPullReq, UsererrorError, void, OpenapiCreatePullReqRequest, CreatePullReqPathParams>,
'path' | 'verb'
> &
CreatePullReqPathParams
export const CreatePullReq = ({ repoRef, ...props }: CreatePullReqProps) => (
<Mutate<TypesPullReq, UsererrorError, void, OpenapiCreatePullReqRequest, CreatePullReqPathParams>
verb="POST"
path={`/repos/${repoRef}/pullreq`}
base={getConfigNew('code')}
{...props}
/>
)
export type UseCreatePullReqProps = Omit<
UseMutateProps<TypesPullReq, UsererrorError, void, OpenapiCreatePullReqRequest, CreatePullReqPathParams>,
'path' | 'verb'
> &
CreatePullReqPathParams
export const useCreatePullReq = ({ repoRef, ...props }: UseCreatePullReqProps) =>
useMutate<TypesPullReq, UsererrorError, void, OpenapiCreatePullReqRequest, CreatePullReqPathParams>(
'POST',
(paramsInPath: CreatePullReqPathParams) => `/repos/${paramsInPath.repoRef}/pullreq`,
{ base: getConfigNew('code'), pathParams: { repoRef }, ...props }
)
export interface GetPullReqPathParams {
repoRef: string
pullreq_number: number
}
export type GetPullReqProps = Omit<GetProps<TypesPullReq, UsererrorError, void, GetPullReqPathParams>, 'path'> &
GetPullReqPathParams
export const GetPullReq = ({ repoRef, pullreq_number, ...props }: GetPullReqProps) => (
<Get<TypesPullReq, UsererrorError, void, GetPullReqPathParams>
path={`/repos/${repoRef}/pullreq/${pullreq_number}`}
base={getConfigNew('code')}
{...props}
/>
)
export type UseGetPullReqProps = Omit<UseGetProps<TypesPullReq, UsererrorError, void, GetPullReqPathParams>, 'path'> &
GetPullReqPathParams
export const useGetPullReq = ({ repoRef, pullreq_number, ...props }: UseGetPullReqProps) =>
useGet<TypesPullReq, UsererrorError, void, GetPullReqPathParams>(
(paramsInPath: GetPullReqPathParams) => `/repos/${paramsInPath.repoRef}/pullreq/${paramsInPath.pullreq_number}`,
{ base: getConfigNew('code'), pathParams: { repoRef, pullreq_number }, ...props }
)
export interface UpdatePullReqPathParams {
repoRef: string
pullreq_number: number
}
export type UpdatePullReqProps = Omit<
MutateProps<TypesPullReq, UsererrorError, void, OpenapiUpdatePullReqRequest, UpdatePullReqPathParams>,
'path' | 'verb'
> &
UpdatePullReqPathParams
export const UpdatePullReq = ({ repoRef, pullreq_number, ...props }: UpdatePullReqProps) => (
<Mutate<TypesPullReq, UsererrorError, void, OpenapiUpdatePullReqRequest, UpdatePullReqPathParams>
verb="PUT"
path={`/repos/${repoRef}/pullreq/${pullreq_number}`}
base={getConfigNew('code')}
{...props}
/>
)
export type UseUpdatePullReqProps = Omit<
UseMutateProps<TypesPullReq, UsererrorError, void, OpenapiUpdatePullReqRequest, UpdatePullReqPathParams>,
'path' | 'verb'
> &
UpdatePullReqPathParams
export const useUpdatePullReq = ({ repoRef, pullreq_number, ...props }: UseUpdatePullReqProps) =>
useMutate<TypesPullReq, UsererrorError, void, OpenapiUpdatePullReqRequest, UpdatePullReqPathParams>(
'PUT',
(paramsInPath: UpdatePullReqPathParams) => `/repos/${paramsInPath.repoRef}/pullreq/${paramsInPath.pullreq_number}`,
{ base: getConfigNew('code'), pathParams: { repoRef, pullreq_number }, ...props }
)
export interface ListRepositoryServiceAccountsPathParams { export interface ListRepositoryServiceAccountsPathParams {
repoRef: string repoRef: string
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@ import type {
OpenapiDirContent, OpenapiDirContent,
OpenapiGetContentOutput, OpenapiGetContentOutput,
RepoCommit, RepoCommit,
TypesPullReq,
TypesRepository TypesRepository
} from 'services/code' } from 'services/code'
import type { PullRequestResponse } from './types'
export interface GitInfoProps { export interface GitInfoProps {
repoMetadata: TypesRepository repoMetadata: TypesRepository
@ -19,7 +19,7 @@ export interface GitInfoProps {
resourceContent: OpenapiGetContentOutput resourceContent: OpenapiGetContentOutput
commitRef: string commitRef: string
commits: RepoCommit[] commits: RepoCommit[]
pullRequestMetadata: PullRequestResponse pullRequestMetadata: TypesPullReq
} }
export enum GitContentType { export enum GitContentType {

View File

@ -1,33 +1,5 @@
import type { DiffFile } from 'diff2html/lib/types' import type { DiffFile } from 'diff2html/lib/types'
export interface PullRequestPayload {
// TODO: Use from service when it's ready
sourceBranch: string
targetBranch: string
sourceRepoRef?: string
title: string
description?: string
}
export interface PullRequestResponse {
// TODO: Use from service when it's ready
id: number
createdBy: number
created: number
updated: number
number: number
state: string
title: string
description: string
sourceRepoID: number
sourceBranch: string
targetRepoID: number
targetBranch: string
mergedBy: Unknown
merged: Unknown
merge_strategy: Unknown
}
export interface DiffFileEntry extends DiffFile { export interface DiffFileEntry extends DiffFile {
containerId: string containerId: string
contentId: string contentId: string