mirror of
https://github.com/harness/drone.git
synced 2025-05-20 10:59:56 +08:00
feat: [CODE-2337] add rebase button in PR Conversation page (#2683)
* fix: [CODE-2362] updated message * fix: [CODE-2362] lint * fix: [CODE-2362] memoize sha state * fix: [CODE-2362] add permission check * fix: [CODE-2362] refetch activity on rebase * fix: [CODE-2362] updated activity for rebase * feat: [CODE-2337] add rebase button in PR Conversation page
This commit is contained in:
parent
b9be854b72
commit
2d96b62e07
@ -806,6 +806,7 @@ export interface StringsMap {
|
|||||||
'pr.openForReview': string
|
'pr.openForReview': string
|
||||||
'pr.outdated': string
|
'pr.outdated': string
|
||||||
'pr.prBranchDeleteInfo': string
|
'pr.prBranchDeleteInfo': string
|
||||||
|
'pr.prBranchForcePushInfo': string
|
||||||
'pr.prBranchPushInfo': string
|
'pr.prBranchPushInfo': string
|
||||||
'pr.prCanBeMerged': string
|
'pr.prCanBeMerged': string
|
||||||
'pr.prClosed': string
|
'pr.prClosed': string
|
||||||
@ -870,7 +871,11 @@ export interface StringsMap {
|
|||||||
reactivate: string
|
reactivate: string
|
||||||
readMe: string
|
readMe: string
|
||||||
reader: string
|
reader: string
|
||||||
|
rebase: string
|
||||||
|
rebaseBranch: string
|
||||||
rebaseMerge: string
|
rebaseMerge: string
|
||||||
|
'rebaseSource.message': string
|
||||||
|
'rebaseSource.title': string
|
||||||
recursiveSearchLabel: string
|
recursiveSearchLabel: string
|
||||||
recursiveSearchTooltip: string
|
recursiveSearchTooltip: string
|
||||||
refresh: string
|
refresh: string
|
||||||
@ -1089,7 +1094,9 @@ export interface StringsMap {
|
|||||||
updateLabel: string
|
updateLabel: string
|
||||||
updateUser: string
|
updateUser: string
|
||||||
updateWebhook: string
|
updateWebhook: string
|
||||||
|
updateWithRebase: string
|
||||||
updated: string
|
updated: string
|
||||||
|
updatedBranchMessageRebase: string
|
||||||
upload: string
|
upload: string
|
||||||
uploadAFileError: string
|
uploadAFileError: string
|
||||||
user: string
|
user: string
|
||||||
|
@ -319,6 +319,7 @@ pr:
|
|||||||
prMergedInfo: '{user} merged changes from {source} into {target} as {mergeSha} {time}'
|
prMergedInfo: '{user} merged changes from {source} into {target} as {mergeSha} {time}'
|
||||||
prRebasedInfo: '{user} rebased changes from branch {source} onto {target}, now at {mergeSha} {time}'
|
prRebasedInfo: '{user} rebased changes from branch {source} onto {target}, now at {mergeSha} {time}'
|
||||||
prBranchPushInfo: '{user} pushed a new commit {commit}'
|
prBranchPushInfo: '{user} pushed a new commit {commit}'
|
||||||
|
prBranchForcePushInfo: '{user} force-pushed the {gitRef} branch from {oldCommit} to {newCommit}'
|
||||||
prBranchDeleteInfo: '{user} deleted the source branch with latest commit {commit}'
|
prBranchDeleteInfo: '{user} deleted the source branch with latest commit {commit}'
|
||||||
prStateChanged: '{user} changed pull request state from {old} to {new}.'
|
prStateChanged: '{user} changed pull request state from {old} to {new}.'
|
||||||
prStateChangedDraft: '{user} {changedToDraft|true:marked pull request as draft.,opened pull request for review.}'
|
prStateChangedDraft: '{user} {changedToDraft|true:marked pull request as draft.,opened pull request for review.}'
|
||||||
@ -1122,6 +1123,9 @@ checkSection:
|
|||||||
allReqChecksPassed: All required checks passed
|
allReqChecksPassed: All required checks passed
|
||||||
someChecksFailed: Some checks have failed
|
someChecksFailed: Some checks have failed
|
||||||
someChecksRunning: Some checks are running
|
someChecksRunning: Some checks are running
|
||||||
|
rebaseSource:
|
||||||
|
title: This branch is out-of-date with the base branch
|
||||||
|
message: Merge the latest changes from {target} into {source}
|
||||||
importFailed: Import Failed
|
importFailed: Import Failed
|
||||||
uploadAFileError: There is no image or video uploaded. Please upload an image or video.
|
uploadAFileError: There is no image or video uploaded. Please upload an image or video.
|
||||||
securitySettings:
|
securitySettings:
|
||||||
@ -1256,3 +1260,7 @@ labels:
|
|||||||
addaValue: Add a value
|
addaValue: Add a value
|
||||||
stringMax: '{entity} must be 50 characters or less'
|
stringMax: '{entity} must be 50 characters or less'
|
||||||
noNewLine: '{entity} cannot contain new lines'
|
noNewLine: '{entity} cannot contain new lines'
|
||||||
|
rebase: Rebase
|
||||||
|
rebaseBranch: Rebase branch
|
||||||
|
updateWithRebase: Update with rebase
|
||||||
|
updatedBranchMessageRebase: Updated branch with rebase
|
||||||
|
@ -118,7 +118,7 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||||||
const [ruleViolationArr, setRuleViolationArr] = useState<{ data: { rule_violations: TypesRuleViolations[] } }>()
|
const [ruleViolationArr, setRuleViolationArr] = useState<{ data: { rule_violations: TypesRuleViolations[] } }>()
|
||||||
const [notBypassable, setNotBypassable] = useState(false)
|
const [notBypassable, setNotBypassable] = useState(false)
|
||||||
const [bypass, setBypass] = useState(false)
|
const [bypass, setBypass] = useState(false)
|
||||||
const { mutate: updatePRState, loading: loadingState } = useMutate({
|
const { mutate: updatePRState } = useMutate({
|
||||||
verb: 'POST',
|
verb: 'POST',
|
||||||
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq/${pullReqMetadata.number}/state`
|
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq/${pullReqMetadata.number}/state`
|
||||||
})
|
})
|
||||||
@ -318,9 +318,6 @@ export const PullRequestActionsBox: React.FC<PullRequestActionsBoxProps> = ({
|
|||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<FlexExpander />
|
<FlexExpander />
|
||||||
<Render when={loading || loadingState}>
|
|
||||||
<Icon name={CodeIcon.InputSpinner} size={16} margin={{ right: 'xsmall' }} />
|
|
||||||
</Render>
|
|
||||||
<PullReqSuggestionsBatch />
|
<PullReqSuggestionsBatch />
|
||||||
<Match expr={isDraft}>
|
<Match expr={isDraft}>
|
||||||
<Truthy>
|
<Truthy>
|
||||||
|
@ -81,6 +81,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blueTextColor {
|
||||||
|
:global {
|
||||||
|
.bp3-button-text {
|
||||||
|
color: var(--primary-7) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.requiredText {
|
.requiredText {
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
font-style: normal !important;
|
font-style: normal !important;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
// This is an auto-generated file
|
// This is an auto-generated file
|
||||||
export declare const blueCopyContainer: string
|
export declare const blueCopyContainer: string
|
||||||
export declare const blueText: string
|
export declare const blueText: string
|
||||||
|
export declare const blueTextColor: string
|
||||||
export declare const boldText: string
|
export declare const boldText: string
|
||||||
export declare const borderContainer: string
|
export declare const borderContainer: string
|
||||||
export declare const borderRadius: string
|
export declare const borderRadius: string
|
||||||
|
@ -46,6 +46,7 @@ import MergeSection from './sections/MergeSection'
|
|||||||
import CommentsSection from './sections/CommentsSection'
|
import CommentsSection from './sections/CommentsSection'
|
||||||
import ChangesSection from './sections/ChangesSection'
|
import ChangesSection from './sections/ChangesSection'
|
||||||
import BranchActionsSection from './sections/BranchActionsSection'
|
import BranchActionsSection from './sections/BranchActionsSection'
|
||||||
|
import RebaseSourceSection from './sections/RebaseSourceSection'
|
||||||
import css from './PullRequestOverviewPanel.module.scss'
|
import css from './PullRequestOverviewPanel.module.scss'
|
||||||
|
|
||||||
interface PullRequestOverviewPanelProps {
|
interface PullRequestOverviewPanelProps {
|
||||||
@ -139,7 +140,7 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||||||
path: `/api/v1/repos/${repoMetadata.path}/+/branches`,
|
path: `/api/v1/repos/${repoMetadata.path}/+/branches`,
|
||||||
pathParams: { repo_ref: repoMetadata.path }
|
pathParams: { repo_ref: repoMetadata.path }
|
||||||
})
|
})
|
||||||
const { mutate: mergePR } = useMutate({
|
const { mutate: mergePR, loading: mergeLoading } = useMutate({
|
||||||
verb: 'POST',
|
verb: 'POST',
|
||||||
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq/${pullReqMetadata.number}/merge`
|
path: `/api/v1/repos/${repoMetadata.path}/+/pullreq/${pullReqMetadata.number}/merge`
|
||||||
})
|
})
|
||||||
@ -231,6 +232,11 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||||||
) // eslint-disable-next-line react-hooks/exhaustive-deps
|
) // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [unchecked, pullReqMetadata?.source_sha, activities])
|
}, [unchecked, pullReqMetadata?.source_sha, activities])
|
||||||
|
|
||||||
|
const rebasePossible = useMemo(
|
||||||
|
() => pullReqMetadata.merge_target_sha !== pullReqMetadata.merge_base_sha,
|
||||||
|
[pullReqMetadata]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container margin={{ bottom: 'medium' }} className={css.mainContainer}>
|
<Container margin={{ bottom: 'medium' }} className={css.mainContainer}>
|
||||||
<Layout.Vertical>
|
<Layout.Vertical>
|
||||||
@ -298,6 +304,15 @@ const PullRequestOverviewPanel = (props: PullRequestOverviewPanelProps) => {
|
|||||||
mergeable={mergeable}
|
mergeable={mergeable}
|
||||||
conflictingFiles={conflictingFiles}
|
conflictingFiles={conflictingFiles}
|
||||||
/>
|
/>
|
||||||
|
),
|
||||||
|
[PanelSectionOutletPosition.REBASE_SOURCE_BRANCH]: rebasePossible &&
|
||||||
|
!mergeLoading &&
|
||||||
|
!conflictingFiles?.length && (
|
||||||
|
<RebaseSourceSection
|
||||||
|
pullReqMetadata={pullReqMetadata}
|
||||||
|
repoMetadata={repoMetadata}
|
||||||
|
refetchActivities={refetchActivities}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -30,6 +30,7 @@ const PullRequestPanelSections = (props: PullRequestPanelSectionsProps) => {
|
|||||||
{outlets[PanelSectionOutletPosition.CHECKS]}
|
{outlets[PanelSectionOutletPosition.CHECKS]}
|
||||||
{outlets[PanelSectionOutletPosition.MERGEABILITY]}
|
{outlets[PanelSectionOutletPosition.MERGEABILITY]}
|
||||||
{outlets[PanelSectionOutletPosition.BRANCH_ACTIONS]}
|
{outlets[PanelSectionOutletPosition.BRANCH_ACTIONS]}
|
||||||
|
{outlets[PanelSectionOutletPosition.REBASE_SOURCE_BRANCH]}
|
||||||
</Layout.Vertical>
|
</Layout.Vertical>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ const MergeSection = (props: MergeSectionProps) => {
|
|||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Container className={cx(css.sectionContainer, css.borderRadius)}>
|
<Container className={cx(css.sectionContainer, css.borderContainer)}>
|
||||||
<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>
|
<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>
|
||||||
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
||||||
{(unchecked && <img src={Images.PrUnchecked} width={25} height={25} />) || (
|
{(unchecked && <img src={Images.PrUnchecked} width={25} height={25} />) || (
|
||||||
|
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 Harness, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import React from 'react'
|
||||||
|
import { Color, FontVariation } from '@harnessio/design-system'
|
||||||
|
import cx from 'classnames'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonSize,
|
||||||
|
ButtonVariation,
|
||||||
|
Container,
|
||||||
|
Layout,
|
||||||
|
StringSubstitute,
|
||||||
|
Text,
|
||||||
|
useToaster
|
||||||
|
} from '@harnessio/uicore'
|
||||||
|
import { useMutate } from 'restful-react'
|
||||||
|
import type { RebaseBranchRequestBody, RepoRepositoryOutput, TypesPullReq } from 'services/code'
|
||||||
|
import { useStrings } from 'framework/strings'
|
||||||
|
import { GitRefLink } from 'components/GitRefLink/GitRefLink'
|
||||||
|
import { getErrorMessage, permissionProps } from 'utils/Utils'
|
||||||
|
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||||
|
import { useAppContext } from 'AppContext'
|
||||||
|
import Fail from '../../../../../icons/code-fail-grey.svg?url'
|
||||||
|
import css from '../PullRequestOverviewPanel.module.scss'
|
||||||
|
|
||||||
|
interface RebaseSourceSectionProps {
|
||||||
|
pullReqMetadata: TypesPullReq
|
||||||
|
repoMetadata: RepoRepositoryOutput
|
||||||
|
refetchActivities: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const RebaseSourceSection = (props: RebaseSourceSectionProps) => {
|
||||||
|
const { pullReqMetadata, repoMetadata, refetchActivities } = props
|
||||||
|
const { getString } = useStrings()
|
||||||
|
const { showSuccess, showError } = useToaster()
|
||||||
|
const { mutate: rebase } = useMutate<RebaseBranchRequestBody>({
|
||||||
|
verb: 'POST',
|
||||||
|
path: `/api/v1/repos/${repoMetadata.path}/+/rebase`
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
hooks: { usePermissionTranslate },
|
||||||
|
standalone,
|
||||||
|
routes
|
||||||
|
} = useAppContext()
|
||||||
|
const space = useGetSpaceParam()
|
||||||
|
const permPushResult = usePermissionTranslate(
|
||||||
|
{
|
||||||
|
resource: {
|
||||||
|
resourceType: 'CODE_REPOSITORY',
|
||||||
|
resourceIdentifier: repoMetadata?.identifier as string
|
||||||
|
},
|
||||||
|
permissions: ['code_repo_push']
|
||||||
|
},
|
||||||
|
[space]
|
||||||
|
)
|
||||||
|
|
||||||
|
const rebaseRequestPayload = {
|
||||||
|
base_branch: pullReqMetadata.target_branch,
|
||||||
|
bypass_rules: true,
|
||||||
|
dry_run_rules: false,
|
||||||
|
head_branch: pullReqMetadata.source_branch,
|
||||||
|
head_commit_sha: pullReqMetadata.source_sha
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Container className={cx(css.sectionContainer, css.borderRadius)}>
|
||||||
|
<Layout.Horizontal flex={{ justifyContent: 'space-between' }}>
|
||||||
|
<Layout.Horizontal flex={{ alignItems: 'center' }}>
|
||||||
|
<img alt={getString('failed')} width={26} height={26} color={Color.GREY_500} src={Fail} />
|
||||||
|
<Layout.Vertical padding={{ left: 'medium' }}>
|
||||||
|
<Text padding={{ bottom: 'xsmall' }} className={css.sectionTitle} color={Color.GREY_600}>
|
||||||
|
{getString('rebaseSource.title')}
|
||||||
|
</Text>
|
||||||
|
<Text className={css.sectionSubheader} color={Color.GREY_450} font={{ variation: FontVariation.BODY }}>
|
||||||
|
<StringSubstitute
|
||||||
|
str={getString('rebaseSource.message')}
|
||||||
|
vars={{
|
||||||
|
target: (
|
||||||
|
<GitRefLink
|
||||||
|
text={pullReqMetadata.target_branch as string}
|
||||||
|
url={routes.toCODERepository({
|
||||||
|
repoPath: repoMetadata.path as string,
|
||||||
|
gitRef: pullReqMetadata.target_branch
|
||||||
|
})}
|
||||||
|
showCopy
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
source: (
|
||||||
|
<GitRefLink
|
||||||
|
text={pullReqMetadata.source_branch as string}
|
||||||
|
url={routes.toCODERepository({
|
||||||
|
repoPath: repoMetadata.path as string,
|
||||||
|
gitRef: pullReqMetadata.source_branch
|
||||||
|
})}
|
||||||
|
showCopy
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
</Layout.Vertical>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className={cx(css.blueTextColor)}
|
||||||
|
variation={ButtonVariation.TERTIARY}
|
||||||
|
size={ButtonSize.MEDIUM}
|
||||||
|
text={getString('updateWithRebase')}
|
||||||
|
onClick={() =>
|
||||||
|
rebase(rebaseRequestPayload)
|
||||||
|
.then(() => {
|
||||||
|
showSuccess(getString('updatedBranchMessageRebase'))
|
||||||
|
setTimeout(() => {
|
||||||
|
refetchActivities()
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
.catch(err => showError(getErrorMessage(err)))
|
||||||
|
}
|
||||||
|
{...permissionProps(permPushResult, standalone)}
|
||||||
|
/>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
</Container>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RebaseSourceSection
|
@ -31,6 +31,7 @@ import { CommitActions } from 'components/CommitActions/CommitActions'
|
|||||||
import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator'
|
import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator'
|
||||||
import { TimePopoverWithLocal } from 'utils/timePopoverLocal/TimePopoverWithLocal'
|
import { TimePopoverWithLocal } from 'utils/timePopoverLocal/TimePopoverWithLocal'
|
||||||
import { Label } from 'components/Label/Label'
|
import { Label } from 'components/Label/Label'
|
||||||
|
import { GitRefLink } from 'components/GitRefLink/GitRefLink'
|
||||||
import css from './Conversation.module.scss'
|
import css from './Conversation.module.scss'
|
||||||
|
|
||||||
interface SystemCommentProps extends Pick<GitInfoProps, 'pullReqMetadata'> {
|
interface SystemCommentProps extends Pick<GitInfoProps, 'pullReqMetadata'> {
|
||||||
@ -149,6 +150,58 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||||||
<Layout.Horizontal spacing="small" style={{ alignItems: 'center' }} className={css.mergedBox}>
|
<Layout.Horizontal spacing="small" style={{ alignItems: 'center' }} className={css.mergedBox}>
|
||||||
<Avatar name={payload?.author?.display_name} size="small" hoverCard={false} />
|
<Avatar name={payload?.author?.display_name} size="small" hoverCard={false} />
|
||||||
<Text flex tag="div">
|
<Text flex tag="div">
|
||||||
|
{(payload?.payload as Unknown)?.forced ? (
|
||||||
|
<StringSubstitute
|
||||||
|
str={getString('pr.prBranchForcePushInfo')}
|
||||||
|
vars={{
|
||||||
|
user: (
|
||||||
|
<Text padding={{ right: 'small' }} inline>
|
||||||
|
<strong>{payload?.author?.display_name}</strong>
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
gitRef: (
|
||||||
|
<Container padding={{ left: 'small', right: 'small' }}>
|
||||||
|
<GitRefLink
|
||||||
|
text={pullReqMetadata.source_branch as string}
|
||||||
|
url={routes.toCODERepository({
|
||||||
|
repoPath: repoMetadataPath as string,
|
||||||
|
gitRef: pullReqMetadata.source_branch
|
||||||
|
})}
|
||||||
|
showCopy
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
),
|
||||||
|
oldCommit: (
|
||||||
|
<Container className={css.commitContainer} padding={{ left: 'small', right: 'small' }}>
|
||||||
|
<CommitActions
|
||||||
|
enableCopy
|
||||||
|
sha={(payload?.payload as Unknown)?.old}
|
||||||
|
href={routes.toCODEPullRequest({
|
||||||
|
repoPath: repoMetadataPath as string,
|
||||||
|
pullRequestSection: PullRequestSection.FILES_CHANGED,
|
||||||
|
pullRequestId: String(pullReqMetadata.number),
|
||||||
|
commitSHA: (payload?.payload as Unknown)?.old as string
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
),
|
||||||
|
newCommit: (
|
||||||
|
<Container className={css.commitContainer} padding={{ left: 'small' }}>
|
||||||
|
<CommitActions
|
||||||
|
enableCopy
|
||||||
|
sha={(payload?.payload as Unknown)?.new}
|
||||||
|
href={routes.toCODEPullRequest({
|
||||||
|
repoPath: repoMetadataPath as string,
|
||||||
|
pullRequestSection: PullRequestSection.FILES_CHANGED,
|
||||||
|
pullRequestId: String(pullReqMetadata.number),
|
||||||
|
commitSHA: (payload?.payload as Unknown)?.new as string
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<StringSubstitute
|
<StringSubstitute
|
||||||
str={getString('pr.prBranchPushInfo')}
|
str={getString('pr.prBranchPushInfo')}
|
||||||
vars={{
|
vars={{
|
||||||
@ -173,6 +226,7 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<PipeSeparator height={9} />
|
<PipeSeparator height={9} />
|
||||||
<TimePopoverWithLocal
|
<TimePopoverWithLocal
|
||||||
|
@ -84,7 +84,8 @@ export enum PanelSectionOutletPosition {
|
|||||||
COMMENTS = 'comments',
|
COMMENTS = 'comments',
|
||||||
CHECKS = 'checks',
|
CHECKS = 'checks',
|
||||||
MERGEABILITY = 'mergeability',
|
MERGEABILITY = 'mergeability',
|
||||||
BRANCH_ACTIONS = 'branchActions'
|
BRANCH_ACTIONS = 'branchActions',
|
||||||
|
REBASE_SOURCE_BRANCH = 'rebaseSourceBranch'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMergeOptions = (getString: UseStringsReturn['getString'], mergeable: boolean): PRMergeOption[] => [
|
export const getMergeOptions = (getString: UseStringsReturn['getString'], mergeable: boolean): PRMergeOption[] => [
|
||||||
|
@ -1436,6 +1436,12 @@ export interface TypesPullReqStats {
|
|||||||
unresolved_count?: number
|
unresolved_count?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TypesRebaseResponse {
|
||||||
|
dry_run_rules?: boolean
|
||||||
|
new_head_branch_sha?: ShaSHA
|
||||||
|
rule_violations?: TypesRuleViolations[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface TypesRenameDetails {
|
export interface TypesRenameDetails {
|
||||||
commit_sha_after?: string
|
commit_sha_after?: string
|
||||||
commit_sha_before?: string
|
commit_sha_before?: string
|
||||||
@ -6047,6 +6053,70 @@ export const useGetRaw = ({ repo_ref, path, ...props }: UseGetRawProps) =>
|
|||||||
{ base: getConfig('code/api/v1'), pathParams: { repo_ref, path }, ...props }
|
{ base: getConfig('code/api/v1'), pathParams: { repo_ref, path }, ...props }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export interface RebaseBranchPathParams {
|
||||||
|
repo_ref: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RebaseBranchRequestBody {
|
||||||
|
base_branch?: string
|
||||||
|
bypass_rules?: boolean
|
||||||
|
dry_run_rules?: boolean
|
||||||
|
head_branch?: string
|
||||||
|
head_commit_sha?: ShaSHA
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RebaseBranchProps = Omit<
|
||||||
|
MutateProps<
|
||||||
|
TypesRebaseResponse,
|
||||||
|
UsererrorError | TypesMergeViolations,
|
||||||
|
void,
|
||||||
|
RebaseBranchRequestBody,
|
||||||
|
RebaseBranchPathParams
|
||||||
|
>,
|
||||||
|
'path' | 'verb'
|
||||||
|
> &
|
||||||
|
RebaseBranchPathParams
|
||||||
|
|
||||||
|
export const RebaseBranch = ({ repo_ref, ...props }: RebaseBranchProps) => (
|
||||||
|
<Mutate<
|
||||||
|
TypesRebaseResponse,
|
||||||
|
UsererrorError | TypesMergeViolations,
|
||||||
|
void,
|
||||||
|
RebaseBranchRequestBody,
|
||||||
|
RebaseBranchPathParams
|
||||||
|
>
|
||||||
|
verb="POST"
|
||||||
|
path={`/repos/${repo_ref}/rebase`}
|
||||||
|
base={getConfig('code/api/v1')}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export type UseRebaseBranchProps = Omit<
|
||||||
|
UseMutateProps<
|
||||||
|
TypesRebaseResponse,
|
||||||
|
UsererrorError | TypesMergeViolations,
|
||||||
|
void,
|
||||||
|
RebaseBranchRequestBody,
|
||||||
|
RebaseBranchPathParams
|
||||||
|
>,
|
||||||
|
'path' | 'verb'
|
||||||
|
> &
|
||||||
|
RebaseBranchPathParams
|
||||||
|
|
||||||
|
export const useRebaseBranch = ({ repo_ref, ...props }: UseRebaseBranchProps) =>
|
||||||
|
useMutate<
|
||||||
|
TypesRebaseResponse,
|
||||||
|
UsererrorError | TypesMergeViolations,
|
||||||
|
void,
|
||||||
|
RebaseBranchRequestBody,
|
||||||
|
RebaseBranchPathParams
|
||||||
|
>('POST', (paramsInPath: RebaseBranchPathParams) => `/repos/${paramsInPath.repo_ref}/rebase`, {
|
||||||
|
base: getConfig('code/api/v1'),
|
||||||
|
pathParams: { repo_ref },
|
||||||
|
...props
|
||||||
|
})
|
||||||
|
|
||||||
export interface RestoreRepositoryQueryParams {
|
export interface RestoreRepositoryQueryParams {
|
||||||
/**
|
/**
|
||||||
* The exact time the resource was delete at in epoch format.
|
* The exact time the resource was delete at in epoch format.
|
||||||
@ -8154,6 +8224,59 @@ export const usePurgeSpace = ({ space_ref, ...props }: UsePurgeSpaceProps) =>
|
|||||||
{ base: getConfig('code/api/v1'), pathParams: { space_ref }, ...props }
|
{ base: getConfig('code/api/v1'), pathParams: { space_ref }, ...props }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export interface ListReposQueryParams {
|
||||||
|
/**
|
||||||
|
* The substring which is used to filter the repositories by their path name.
|
||||||
|
*/
|
||||||
|
query?: string
|
||||||
|
/**
|
||||||
|
* The data by which the repositories are sorted.
|
||||||
|
*/
|
||||||
|
sort?: 'identifier' | 'created' | 'updated'
|
||||||
|
/**
|
||||||
|
* The order of the output.
|
||||||
|
*/
|
||||||
|
order?: 'asc' | 'desc'
|
||||||
|
/**
|
||||||
|
* The page to return.
|
||||||
|
*/
|
||||||
|
page?: number
|
||||||
|
/**
|
||||||
|
* The maximum number of results to return.
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListReposPathParams {
|
||||||
|
space_ref: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ListReposProps = Omit<
|
||||||
|
GetProps<TypesRepository[], UsererrorError, ListReposQueryParams, ListReposPathParams>,
|
||||||
|
'path'
|
||||||
|
> &
|
||||||
|
ListReposPathParams
|
||||||
|
|
||||||
|
export const ListRepos = ({ space_ref, ...props }: ListReposProps) => (
|
||||||
|
<Get<TypesRepository[], UsererrorError, ListReposQueryParams, ListReposPathParams>
|
||||||
|
path={`/spaces/${space_ref}/repos`}
|
||||||
|
base={getConfig('code/api/v1')}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export type UseListReposProps = Omit<
|
||||||
|
UseGetProps<TypesRepository[], UsererrorError, ListReposQueryParams, ListReposPathParams>,
|
||||||
|
'path'
|
||||||
|
> &
|
||||||
|
ListReposPathParams
|
||||||
|
|
||||||
|
export const useListRepos = ({ space_ref, ...props }: UseListReposProps) =>
|
||||||
|
useGet<TypesRepository[], UsererrorError, ListReposQueryParams, ListReposPathParams>(
|
||||||
|
(paramsInPath: ListReposPathParams) => `/spaces/${paramsInPath.space_ref}/repos`,
|
||||||
|
{ base: getConfig('code/api/v1'), pathParams: { space_ref }, ...props }
|
||||||
|
)
|
||||||
|
|
||||||
export interface RestoreSpaceQueryParams {
|
export interface RestoreSpaceQueryParams {
|
||||||
/**
|
/**
|
||||||
* The exact time the resource was delete at in epoch format.
|
* The exact time the resource was delete at in epoch format.
|
||||||
|
@ -6070,6 +6070,76 @@ paths:
|
|||||||
description: Internal Server Error
|
description: Internal Server Error
|
||||||
tags:
|
tags:
|
||||||
- repository
|
- repository
|
||||||
|
/repos/{repo_ref}/rebase:
|
||||||
|
post:
|
||||||
|
operationId: rebaseBranch
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: repo_ref
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
base_branch:
|
||||||
|
type: string
|
||||||
|
bypass_rules:
|
||||||
|
type: boolean
|
||||||
|
dry_run_rules:
|
||||||
|
type: boolean
|
||||||
|
head_branch:
|
||||||
|
type: string
|
||||||
|
head_commit_sha:
|
||||||
|
$ref: '#/components/schemas/ShaSHA'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TypesRebaseResponse'
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Bad Request
|
||||||
|
'401':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Unauthorized
|
||||||
|
'403':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Forbidden
|
||||||
|
'404':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Not Found
|
||||||
|
'422':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TypesMergeViolations'
|
||||||
|
description: Unprocessable Entity
|
||||||
|
'500':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Internal Server Error
|
||||||
|
tags:
|
||||||
|
- repository
|
||||||
/repos/{repo_ref}/restore:
|
/repos/{repo_ref}/restore:
|
||||||
post:
|
post:
|
||||||
operationId: restoreRepository
|
operationId: restoreRepository
|
||||||
@ -9225,6 +9295,95 @@ paths:
|
|||||||
description: Internal Server Error
|
description: Internal Server Error
|
||||||
tags:
|
tags:
|
||||||
- space
|
- space
|
||||||
|
/spaces/{space_ref}/repos:
|
||||||
|
get:
|
||||||
|
operationId: listRepos
|
||||||
|
parameters:
|
||||||
|
- description: The substring which is used to filter the repositories by their
|
||||||
|
path name.
|
||||||
|
in: query
|
||||||
|
name: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: The data by which the repositories are sorted.
|
||||||
|
in: query
|
||||||
|
name: sort
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: identifier
|
||||||
|
enum:
|
||||||
|
- identifier
|
||||||
|
- created
|
||||||
|
- updated
|
||||||
|
type: string
|
||||||
|
- description: The order of the output.
|
||||||
|
in: query
|
||||||
|
name: order
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: asc
|
||||||
|
enum:
|
||||||
|
- asc
|
||||||
|
- desc
|
||||||
|
type: string
|
||||||
|
- description: The page to return.
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: 1
|
||||||
|
minimum: 1
|
||||||
|
type: integer
|
||||||
|
- description: The maximum number of results to return.
|
||||||
|
in: query
|
||||||
|
name: limit
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: 30
|
||||||
|
maximum: 100
|
||||||
|
minimum: 1
|
||||||
|
type: integer
|
||||||
|
- in: path
|
||||||
|
name: space_ref
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TypesRepository'
|
||||||
|
type: array
|
||||||
|
description: OK
|
||||||
|
'401':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Unauthorized
|
||||||
|
'403':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Forbidden
|
||||||
|
'404':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UsererrorError'
|
||||||
|
description: Internal Server Error
|
||||||
|
tags:
|
||||||
|
- space
|
||||||
/spaces/{space_ref}/restore:
|
/spaces/{space_ref}/restore:
|
||||||
post:
|
post:
|
||||||
operationId: restoreSpace
|
operationId: restoreSpace
|
||||||
@ -12657,6 +12816,17 @@ components:
|
|||||||
unresolved_count:
|
unresolved_count:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
TypesRebaseResponse:
|
||||||
|
properties:
|
||||||
|
dry_run_rules:
|
||||||
|
type: boolean
|
||||||
|
new_head_branch_sha:
|
||||||
|
$ref: '#/components/schemas/ShaSHA'
|
||||||
|
rule_violations:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TypesRuleViolations'
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
TypesRenameDetails:
|
TypesRenameDetails:
|
||||||
properties:
|
properties:
|
||||||
commit_sha_after:
|
commit_sha_after:
|
||||||
|
Loading…
Reference in New Issue
Block a user