Add placeholder for Review changes (#193)

This commit is contained in:
Tan Nhu 2023-01-12 09:56:01 -08:00 committed by GitHub
parent 8909037ec7
commit 38fb97b8e2
12 changed files with 181 additions and 32 deletions

View File

@ -8,10 +8,6 @@
padding: var(--spacing-medium) 0 !important;
background-color: var(--white) !important;
z-index: 2;
.hideButton {
visibility: hidden;
}
}
.diffStatsLabel {

View File

@ -3,7 +3,6 @@
declare const styles: {
readonly wrapper: string
readonly header: string
readonly hideButton: string
readonly diffStatsLabel: string
readonly main: string
readonly enableDiffLineBreaks: string

View File

@ -17,6 +17,7 @@ import type { TypesPullReq } from 'services/code'
import { PullRequestTabContentWrapper } from '../../pages/PullRequest/PullRequestTabContentWrapper'
import { ChangesDropdown } from './ChangesDropdown'
import { DiffViewConfiguration } from './DiffViewConfiguration'
import { ReviewDecisionButton } from './ReviewDecisionButton/ReviewDecisionButton'
import css from './Changes.module.scss'
const STICKY_TOP_POSITION = 64
@ -138,11 +139,11 @@ export const Changes: React.FC<ChangesProps> = ({
)}
</Container>
<FlexExpander />
<Button
text={getString('pr.reviewChanges')}
variation={ButtonVariation.PRIMARY}
intent="success"
className={readOnly || pullRequestMetadata?.state === 'merged' ? css.hideButton : undefined}
<ReviewDecisionButton
repoMetadata={repoMetadata}
pullRequestMetadata={pullRequestMetadata}
disable={readOnly || pullRequestMetadata?.state === 'merged'}
/>
</Layout.Horizontal>
</Container>

View File

@ -0,0 +1,15 @@
.btn {
&.hide {
visibility: hidden;
}
}
.popup {
width: 600px;
.markdown {
position: relative;
background: var(--grey-50);
border-radius: 5px;
}
}

View File

@ -0,0 +1,9 @@
/* eslint-disable */
// this is an auto-generated file
declare const styles: {
readonly btn: string
readonly hide: string
readonly popup: string
readonly markdown: string
}
export default styles

View File

@ -0,0 +1,91 @@
import React, { useState } from 'react'
import { Radio, RadioGroup, ButtonVariation, Button, Container, Layout, Text, ButtonSize } from '@harness/uicore'
import cx from 'classnames'
import { useStrings } from 'framework/strings'
import type { GitInfoProps } from 'utils/GitUtils'
import type { TypesPullReq } from 'services/code'
import { MarkdownEditorWithPreview } from 'components/MarkdownEditorWithPreview/MarkdownEditorWithPreview'
import css from './ReviewDecisionButton.module.scss'
enum PullReqReviewDecision {
PENDING = 'pending',
REVIEWED = 'reviewed',
APPROVED = 'approved',
CHANGEREQ = 'changereq'
}
interface ReviewDecisionButtonProps extends Pick<GitInfoProps, 'repoMetadata'> {
disable: boolean
pullRequestMetadata?: TypesPullReq
}
export const ReviewDecisionButton: React.FC<ReviewDecisionButtonProps> = ({
pullRequestMetadata,
repoMetadata,
disable
}) => {
const { getString } = useStrings()
const [content, setContent] = useState('')
const [decision, setDecision] = useState<PullReqReviewDecision>(PullReqReviewDecision.PENDING)
return (
<Button
text={getString('pr.reviewChanges')}
variation={ButtonVariation.PRIMARY}
intent="success"
rightIcon="chevron-down"
className={cx(css.btn, { [css.hide]: disable })}
style={{ '--background-color': 'var(--green-800)' } as React.CSSProperties}
tooltip={
<Container padding="large" className={css.popup}>
<Layout.Vertical spacing="medium">
<Text>Finish your review</Text>
<Container className={css.markdown} padding="medium">
<MarkdownEditorWithPreview
value={content}
hideButtons
i18n={{
placeHolder: getString('leaveAComment'),
tabEdit: getString('write'),
tabPreview: getString('preview'),
save: getString('save'),
cancel: getString('cancel')
}}
editorHeight="100px"
/>
</Container>
<Container padding={{ left: 'xxxlarge' }}>
<RadioGroup>
<Radio
name="decision"
defaultChecked={decision === PullReqReviewDecision.PENDING}
label={getString('comment')}
value={PullReqReviewDecision.PENDING}
onChange={() => setDecision(PullReqReviewDecision.PENDING)}
/>
<Radio
name="decision"
defaultChecked={decision === PullReqReviewDecision.APPROVED}
label={getString('approve')}
value={PullReqReviewDecision.APPROVED}
onChange={() => setDecision(PullReqReviewDecision.APPROVED)}
/>
<Radio
name="decision"
defaultChecked={decision === PullReqReviewDecision.CHANGEREQ}
label={getString('requestChanges')}
value={PullReqReviewDecision.CHANGEREQ}
onChange={() => setDecision(PullReqReviewDecision.CHANGEREQ)}
/>
</RadioGroup>
</Container>
<Container>
<Button variation={ButtonVariation.PRIMARY} text={getString('submitReview')} size={ButtonSize.SMALL} />
</Container>
</Layout.Vertical>
</Container>
}
tooltipProps={{ interactionKind: 'click', position: 'bottom-right', hasBackdrop: true }}
/>
)
}

View File

@ -54,6 +54,22 @@
}
}
.bp3-tab {
font-size: var(--font-size-normal);
line-height: 19px;
color: var(--grey-700);
}
.bp3-tab[aria-selected='true'] {
color: var(--grey-900);
font-weight: 600;
}
.bp3-tab[aria-disabled='true'] {
opacity: 50%;
cursor: not-allowed;
}
.bp3-tab-panel {
margin-top: 0;
}
@ -65,6 +81,8 @@
margin-top: 28px !important;
border: 1px solid var(--color-border) !important;
border-radius: var(--box-radius);
max-height: 400px;
overflow: auto;
:global {
.wmde-markdown .anchor {
@ -109,7 +127,9 @@
.md-editor-content {
padding: var(--spacing-small);
background-color: var(--white);
max-height: var(--max-editor-height, auto);
height: var(--editor-height, auto);
min-height: var(--editor-height, auto);
max-height: var(--max-editor-height, var(--editor-height, auto));
.ͼ1.cm-editor.cm-focused {
outline: none !important;

View File

@ -16,8 +16,8 @@ export interface MarkdownEditorWithPreviewResetProps {
interface MarkdownEditorWithPreviewProps {
value: string
onChange?: (value: string, original: string) => void
onSave: (value: string, original: string) => void
onCancel: () => void
onSave?: (value: string, original: string) => void
onCancel?: () => void
i18n: {
placeHolder: string
tabEdit: string
@ -25,7 +25,9 @@ interface MarkdownEditorWithPreviewProps {
cancel: string
save: string
}
hideButtons?: boolean
hideCancel?: boolean
editorHeight?: string
maxEditorHeight?: string
editorRef?: React.MutableRefObject<MarkdownEditorWithPreviewResetProps>
}
@ -33,10 +35,12 @@ interface MarkdownEditorWithPreviewProps {
export function MarkdownEditorWithPreview({
value,
onChange = noop,
onSave,
onCancel,
onSave = noop,
onCancel = noop,
i18n,
hideButtons,
hideCancel,
editorHeight,
maxEditorHeight,
editorRef
}: MarkdownEditorWithPreviewProps) {
@ -69,7 +73,12 @@ export function MarkdownEditorWithPreview({
panel={
<Container
className={css.markdownEditor}
style={{ '--max-editor-height': maxEditorHeight } as React.CSSProperties}>
style={
{
'--editor-height': editorHeight,
'--max-editor-height': maxEditorHeight
} as React.CSSProperties
}>
<MarkdownEditor
value={val}
visible={false}
@ -97,7 +106,7 @@ export function MarkdownEditorWithPreview({
/>
<Tab
id={MarkdownEditorTab.PREVIEW}
disabled={!value}
disabled={!val}
title={i18n.tabPreview}
panel={
<Container padding="large" className={css.preview}>
@ -106,17 +115,19 @@ export function MarkdownEditorWithPreview({
}
/>
</Tabs>
<Container>
<Layout.Horizontal spacing="small">
<Button
disabled={!(val || '').trim() || val === original}
variation={ButtonVariation.PRIMARY}
onClick={() => onSave(val, original)}
text={i18n.save}
/>
{!hideCancel && <Button variation={ButtonVariation.TERTIARY} onClick={onCancel} text={i18n.cancel} />}
</Layout.Horizontal>
</Container>
{!hideButtons && (
<Container>
<Layout.Horizontal spacing="small">
<Button
disabled={!(val || '').trim() || val === original}
variation={ButtonVariation.PRIMARY}
onClick={() => onSave(val, original)}
text={i18n.save}
/>
{!hideCancel && <Button variation={ButtonVariation.TERTIARY} onClick={onCancel} text={i18n.cancel} />}
</Layout.Horizontal>
</Container>
)}
</Layout.Vertical>
</Container>
)

View File

@ -11,6 +11,7 @@ export interface StringsMap {
all: string
allBranches: string
allEvents: string
approve: string
botAlerts: string
branch: string
branchCreated: string
@ -183,6 +184,7 @@ export interface StringsMap {
'repos.noDataMessage': string
'repos.updated': string
repositories: string
requestChanges: string
samplePayloadUrl: string
save: string
scanAlerts: string
@ -197,6 +199,7 @@ export interface StringsMap {
signUp: string
sslVerificationLabel: string
status: string
submitReview: string
switchBranchesTags: string
tagNotFound: string
tags: string

View File

@ -183,7 +183,7 @@ pr:
failedToSaveComment: Failed to save comment. Please try again.
failedToDeleteComment: Failed to delete comment. Please try again.
prMerged: This Pull Request was merged
prMergedInfo: '{user} merged branch {source} into {target} {time}'
prMergedInfo: '{user} merged branch {source} into {target} {time}.'
webhookListingContent: 'create,delete,deployment ...'
general: 'General'
webhooks: 'Webhooks'
@ -200,7 +200,7 @@ viewed: Viewed
comment: Comment
addComment: Add comment
replyHere: Reply here...
leaveAComment: Leave a comment here...
leaveAComment: Leave a comment...
lineBreaks: Line Breaks
quote: Quote
deleteCommentConfirm: Are you sure you want to delete this comment?
@ -223,3 +223,6 @@ webhookBranchCreated: Branch created
webhookBranchUpdated: Branch updated
webhookBranchDeleted: Branch deleted
nameYourWebhook: Name your webhook
submitReview: Submit Review
approve: Approve
requestChanges: Request changes

View File

@ -5,6 +5,7 @@ import {
Container,
FlexExpander,
FontVariation,
Icon,
Layout,
StringSubstitute,
Text,
@ -12,7 +13,7 @@ import {
} from '@harness/uicore'
import { useGet, useMutate } from 'restful-react'
import ReactTimeago from 'react-timeago'
import type { GitInfoProps } from 'utils/GitUtils'
import { CodeIcon, GitInfoProps } from 'utils/GitUtils'
import { MarkdownViewer } from 'components/SourceCodeViewer/SourceCodeViewer'
import { useStrings } from 'framework/strings'
import { useAppContext } from 'AppContext'
@ -286,6 +287,7 @@ const SystemBox: React.FC<SystemBoxProps> = ({ pullRequestMetadata, commentItems
if (commentItems[0].payload?.type === 'merge') {
return (
<Text className={css.box}>
<Icon name={CodeIcon.PullRequest} color={Color.PURPLE_700} padding={{ right: 'small' }} />
<StringSubstitute
str={getString('pr.prMergedInfo')}
vars={{

View File

@ -45,7 +45,6 @@ export default function PullRequests() {
page: String(pageIndex + 1),
sort: 'date',
order: 'desc',
include_commit: String(true),
query: searchTerm
})