[UI] Consume Latest OpenAPI Specs (#134)

* regenerate CODE service code to match latest API specs

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,8 @@ export type EnumParentResourceType = string
export type EnumPathTargetType = string
export type EnumPullReqState = string
export type EnumTokenType = string
export interface FormDataOpenapiLoginRequest {
@ -59,6 +61,14 @@ export interface OpenapiCreatePathRequest {
path?: string
}
export interface OpenapiCreatePullReqRequest {
description?: string
source_branch?: string
source_repo_ref?: string
target_branch?: string
title?: string
}
export interface OpenapiCreateRepoPathRequest {
path?: string
}
@ -112,6 +122,11 @@ export interface OpenapiMoveSpaceRequest {
uid?: string | null
}
export interface OpenapiUpdatePullReqRequest {
description?: string
title?: string
}
export interface OpenapiUpdateRepoRequest {
description?: string | null
isPublic?: boolean | null
@ -220,6 +235,33 @@ export interface TypesPath {
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 {
created?: number
createdBy?: number
@ -911,6 +953,169 @@ export const useDeleteRepositoryPath = ({ repoRef, ...props }: UseDeleteReposito
{ 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 {
repoRef: string
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,33 +1,5 @@
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 {
containerId: string
contentId: string