mirror of https://github.com/harness/drone.git
fix: [code-1797] PR Description issues (#2001)
parent
7103d88109
commit
a692707c6c
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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, { useState } from 'react'
|
||||
import { Button, ButtonSize, ButtonVariation, Container, Text } from '@harnessio/uicore'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import type { Identifier } from 'utils/types'
|
||||
|
||||
const EnableAidaBanner: React.FC<React.PropsWithChildren<unknown>> = () => {
|
||||
const { getString } = useStrings()
|
||||
const { standalone, hooks, routingId, defaultSettingsURL } = useAppContext()
|
||||
const [aidaEnableBanner, setAidaEnableBanner] = useState<boolean>(true)
|
||||
const { orgIdentifier, projectIdentifier } = useParams<Identifier>()
|
||||
const { data: aidaSettingResponse, loading: isAidaSettingLoading } = hooks?.useGetSettingValue({
|
||||
identifier: 'aida',
|
||||
queryParams: { accountIdentifier: routingId, orgIdentifier, projectIdentifier }
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{!standalone && aidaSettingResponse?.data?.value != 'true' && !isAidaSettingLoading && aidaEnableBanner && (
|
||||
<Container
|
||||
background={Color.AI_PURPLE_50}
|
||||
padding="small"
|
||||
margin={{ top: 'xsmall', right: 'small', left: 'xsmall' }}
|
||||
style={{ position: 'relative' }}>
|
||||
<Text
|
||||
font={{ variation: FontVariation.BODY2 }}
|
||||
margin={{ bottom: 'small' }}
|
||||
icon="info-messaging"
|
||||
iconProps={{ size: 15 }}>
|
||||
{getString('enableAIDAPRDescription')}
|
||||
</Text>
|
||||
<Text font={{ variation: FontVariation.BODY2_SEMI }} margin={{ bottom: 'small' }} color={Color.GREY_450}>
|
||||
{getString('enableAIDAPRMessange')}
|
||||
</Text>
|
||||
<Link to={defaultSettingsURL} color={Color.AI_PURPLE_800}>
|
||||
{getString('reviewProjectSettings')}
|
||||
</Link>
|
||||
<Button
|
||||
variation={ButtonVariation.ICON}
|
||||
minimal
|
||||
icon="main-close"
|
||||
role="close"
|
||||
iconProps={{ size: 12 }}
|
||||
style={{ position: 'absolute', top: '3px', right: '3px' }}
|
||||
size={ButtonSize.SMALL}
|
||||
onClick={() => {
|
||||
setAidaEnableBanner(false)
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default EnableAidaBanner
|
|
@ -23,6 +23,7 @@ import { Color, FontVariation } from '@harnessio/design-system'
|
|||
import { Link, useParams } from 'react-router-dom'
|
||||
import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import type { Identifier } from 'utils/types'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { SEARCH_MODE } from 'components/CodeSearch/CodeSearch'
|
||||
import svg from '../CodeSearch/search-background.svg?url'
|
||||
|
@ -37,12 +38,6 @@ interface CodeSearchBarProps {
|
|||
searchMode: SEARCH_MODE
|
||||
}
|
||||
|
||||
interface Identifier {
|
||||
accountId: string
|
||||
orgIdentifier: string
|
||||
projectIdentifier: string
|
||||
}
|
||||
|
||||
const KEYWORD_REGEX = /((?:(?:-{0,1})(?:repo|lang|file|case|count)):\S*|(?: or|and ))/gi
|
||||
|
||||
const CodeSearchBar: FC<CodeSearchBarProps> = ({ value, onChange, onSearch, onKeyDown, searchMode, setSearchMode }) => {
|
||||
|
|
|
@ -281,10 +281,30 @@
|
|||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.aidaFeedback {
|
||||
position: absolute !important;
|
||||
width: 100%;
|
||||
right: -4.5px;
|
||||
padding: 5px 10px !important;
|
||||
margin: 10px 5px !important;
|
||||
.feedbackContainer {
|
||||
position: relative;
|
||||
// overwriting the extra close button in feedback form UsefulOrNot
|
||||
> div {
|
||||
> div {
|
||||
> button {
|
||||
span[data-icon='main-close'] {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.aidaFeedback {
|
||||
margin: 0 0 9px 0 !important;
|
||||
padding: 7px 10px !important;
|
||||
width: 100%;
|
||||
background-color: var(--ai-purple-100) !important;
|
||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
export declare const aidaFeedback: string
|
||||
export declare const aidaGenText: string
|
||||
export declare const buttonsBar: string
|
||||
export declare const closeButton: string
|
||||
export declare const container: string
|
||||
export declare const dialog: string
|
||||
export declare const feedbackContainer: string
|
||||
export declare const hidden: string
|
||||
export declare const main: string
|
||||
export declare const markdownEditor: string
|
||||
|
|
|
@ -176,10 +176,12 @@ export function MarkdownEditorWithPreview({
|
|||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const [selectedTab, setSelectedTab] = useState(MarkdownEditorTab.WRITE)
|
||||
const viewRef = useRef<EditorView>()
|
||||
const feedbackRef = useRef<HTMLDivElement>()
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const [dirty, setDirty] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [file, setFile] = useState<File>()
|
||||
const [showFeedback, setShowFeedback] = useState<boolean>(false)
|
||||
const { showError } = useToaster()
|
||||
const [markdownContent, setMarkdownContent] = useState('')
|
||||
const { customComponents } = useAppContext()
|
||||
|
@ -218,18 +220,19 @@ export function MarkdownEditorWithPreview({
|
|||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(event: any) => {
|
||||
const editorDom = viewRef?.current?.dom
|
||||
if (!editorDom?.contains(event.target)) {
|
||||
if (!editorDom?.contains(event.target) && !feedbackRef?.current?.contains(event.target)) {
|
||||
// Clicked outside the editor
|
||||
viewRef?.current?.dispatch({
|
||||
effects: removeDecorationEffect.of({})
|
||||
})
|
||||
setShowFeedback(false)
|
||||
}
|
||||
},
|
||||
[viewRef]
|
||||
)
|
||||
|
||||
useEventListener('mousedown', handleMouseDown)
|
||||
const [generating, setGenerating] = useState<boolean>(false)
|
||||
|
||||
const dispatchContent = (content: string, userEvent: boolean, decoration = false) => {
|
||||
const view = viewRef.current
|
||||
const { from, to } = view?.state.selection.main ?? { from: 0, to: 0 }
|
||||
|
@ -256,19 +259,20 @@ export function MarkdownEditorWithPreview({
|
|||
})
|
||||
removeSpecificTextOptimized(viewRef, getString('aidaGenSummary'))
|
||||
}
|
||||
setData({})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (flag) {
|
||||
if (handleCopilotClick) {
|
||||
setGenerating(true)
|
||||
dispatchContent(getString('aidaGenSummary'), false, true)
|
||||
setShowFeedback(false)
|
||||
mutate({
|
||||
head_ref: normalizeGitRef(sourceGitRef),
|
||||
base_ref: normalizeGitRef(targetGitRef)
|
||||
})
|
||||
.then(res => {
|
||||
setGenerating(false)
|
||||
res.summary && setShowFeedback(true)
|
||||
setData(res.summary || '')
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -284,6 +288,7 @@ export function MarkdownEditorWithPreview({
|
|||
dispatchContent(`${data}`, true)
|
||||
}
|
||||
}, [data]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const onToolbarAction = useCallback((action: ToolbarAction) => {
|
||||
const view = viewRef.current
|
||||
|
||||
|
@ -630,7 +635,42 @@ export function MarkdownEditorWithPreview({
|
|||
{selectedTab === MarkdownEditorTab.PREVIEW && (
|
||||
<MarkdownViewer source={viewRef.current?.state.doc.toString() || ''} maxHeight={800} />
|
||||
)}
|
||||
{!standalone && showFeedback && (
|
||||
<Container
|
||||
ref={feedbackRef}
|
||||
className={cx(css.feedbackContainer, { [css.hidden]: selectedTab === MarkdownEditorTab.PREVIEW })}>
|
||||
<AIDAFeedback
|
||||
className={css.aidaFeedback}
|
||||
allowCreateTicket={true}
|
||||
allowFeedback={true}
|
||||
telemetry={{
|
||||
aidaClient: AidaClient.CODE_PR_SUMMARY,
|
||||
metadata: {
|
||||
query: getString('generateSummary'),
|
||||
generatedResponse: isString(data) ? data : getString('invalidResponse')
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variation={ButtonVariation.ICON}
|
||||
minimal
|
||||
icon="main-close"
|
||||
role="close"
|
||||
iconProps={{ size: 12 }}
|
||||
size={ButtonSize.SMALL}
|
||||
className={css.closeButton}
|
||||
onClick={() => {
|
||||
viewRef?.current?.dispatch({
|
||||
effects: removeDecorationEffect.of({})
|
||||
})
|
||||
setShowFeedback(false)
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
)}
|
||||
{selectedTab === MarkdownEditorTab.WRITE && outlets[CommentBoxOutletPosition.ENABLE_AIDA_PR_DESC_BANNER]}
|
||||
</Container>
|
||||
|
||||
{!hideButtons && (
|
||||
<Container className={css.buttonsBar}>
|
||||
<Layout.Horizontal spacing="small">
|
||||
|
@ -642,20 +682,6 @@ export function MarkdownEditorWithPreview({
|
|||
</Layout.Horizontal>
|
||||
</Container>
|
||||
)}
|
||||
{!isEmpty(data) && !generating && !standalone && (
|
||||
<AIDAFeedback
|
||||
className={css.aidaFeedback}
|
||||
allowCreateTicket={true}
|
||||
allowFeedback={true}
|
||||
telemetry={{
|
||||
aidaClient: AidaClient.CODE_PR_SUMMARY,
|
||||
metadata: {
|
||||
query: getString('generateSummary'),
|
||||
generatedResponse: isString(data) ? data : getString('invalidResponse')
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
> p + div {
|
||||
// flex-grow: 1;
|
||||
|
||||
ul + div + div {
|
||||
ul + div {
|
||||
height: calc(100% - 47px);
|
||||
|
||||
> div {
|
||||
|
|
|
@ -33,7 +33,7 @@ import {
|
|||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { PopoverPosition } from '@blueprintjs/core'
|
||||
import cx from 'classnames'
|
||||
import { Link, useHistory, useParams } from 'react-router-dom'
|
||||
import { useHistory, useParams } from 'react-router-dom'
|
||||
import { useGet, useMutate } from 'restful-react'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||
|
@ -59,20 +59,15 @@ import Config from 'Config'
|
|||
import { usePageIndex } from 'hooks/usePageIndex'
|
||||
import { TabContentWrapper } from 'components/TabContentWrapper/TabContentWrapper'
|
||||
import { useSetPageContainerWidthVar } from 'hooks/useSetPageContainerWidthVar'
|
||||
import type { Identifier } from 'utils/types'
|
||||
import EnableAidaBanner from 'components/Aida/EnableAidaBanner'
|
||||
import { CompareContentHeader, PRCreationType } from './CompareContentHeader/CompareContentHeader'
|
||||
import { CompareCommits } from './CompareCommits'
|
||||
import css from './Compare.module.scss'
|
||||
|
||||
interface Identifier {
|
||||
accountId: string
|
||||
orgIdentifier: string
|
||||
projectIdentifier: string
|
||||
}
|
||||
|
||||
export default function Compare() {
|
||||
const { routes, standalone, hooks, routingId, defaultSettingsURL } = useAppContext()
|
||||
const { routes, standalone, hooks, routingId } = useAppContext()
|
||||
const [flag, setFlag] = useState(false)
|
||||
const { SEMANTIC_SEARCH_ENABLED } = hooks?.useFeatureFlags()
|
||||
const { orgIdentifier, projectIdentifier } = useParams<Identifier>()
|
||||
const { data: aidaSettingResponse, loading: isAidaSettingLoading } = hooks?.useGetSettingValue({
|
||||
identifier: 'aida',
|
||||
|
@ -317,7 +312,6 @@ export default function Compare() {
|
|||
<>
|
||||
{!isAidaSettingLoading &&
|
||||
aidaSettingResponse?.data?.value == 'true' &&
|
||||
SEMANTIC_SEARCH_ENABLED &&
|
||||
!standalone ? (
|
||||
<Button
|
||||
size={ButtonSize.SMALL}
|
||||
|
@ -349,34 +343,10 @@ export default function Compare() {
|
|||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
),
|
||||
[CommentBoxOutletPosition.ENABLE_AIDA_PR_DESC_BANNER]: <EnableAidaBanner />
|
||||
}}
|
||||
/>
|
||||
{aidaSettingResponse?.data?.value != 'true' &&
|
||||
SEMANTIC_SEARCH_ENABLED &&
|
||||
!isAidaSettingLoading && (
|
||||
<Container
|
||||
background={Color.AI_PURPLE_50}
|
||||
padding="small"
|
||||
margin={{ top: 'xsmall', right: 'small', left: 'xsmall' }}>
|
||||
<Text
|
||||
font={{ variation: FontVariation.BODY2 }}
|
||||
margin={{ bottom: 'small' }}
|
||||
icon="info-messaging"
|
||||
iconProps={{ size: 15 }}>
|
||||
{getString('enableAIDAPRDescription')}
|
||||
</Text>
|
||||
<Text
|
||||
font={{ variation: FontVariation.BODY2_SEMI }}
|
||||
margin={{ bottom: 'small' }}
|
||||
color={Color.GREY_450}>
|
||||
{getString('enableAIDAPRMessange')}
|
||||
</Text>
|
||||
<Link to={defaultSettingsURL} color={Color.AI_PURPLE_800}>
|
||||
{getString('reviewProjectSettings')}
|
||||
</Link>
|
||||
</Container>
|
||||
)}
|
||||
</Layout.Vertical>
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { Button, ButtonSize, ButtonVariation, Container, Layout, useToaster, Text } from '@harnessio/uicore'
|
||||
import cx from 'classnames'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { useMutate } from 'restful-react'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { PopoverPosition } from '@blueprintjs/core'
|
||||
|
@ -26,7 +27,9 @@ import type { OpenapiUpdatePullReqRequest } from 'services/code'
|
|||
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
||||
import { MarkdownEditorWithPreview } from 'components/MarkdownEditorWithPreview/MarkdownEditorWithPreview'
|
||||
import { NavigationCheck } from 'components/NavigationCheck/NavigationCheck'
|
||||
import EnableAidaBanner from 'components/Aida/EnableAidaBanner'
|
||||
import { CommentBoxOutletPosition, getErrorMessage } from 'utils/Utils'
|
||||
import type { Identifier } from 'utils/types'
|
||||
import Config from 'Config'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import type { ConversationProps } from './Conversation'
|
||||
|
@ -47,7 +50,6 @@ export const DescriptionBox: React.FC<DescriptionBoxProps> = ({
|
|||
const { hooks } = useAppContext()
|
||||
|
||||
const [flag, setFlag] = useState(false)
|
||||
const { SEMANTIC_SEARCH_ENABLED } = hooks?.useFeatureFlags()
|
||||
const [edit, setEdit] = useState(false)
|
||||
const [dirty, setDirty] = useState(false)
|
||||
|
||||
|
@ -55,6 +57,11 @@ export const DescriptionBox: React.FC<DescriptionBoxProps> = ({
|
|||
const [content, setContent] = useState(originalContent)
|
||||
const { getString } = useStrings()
|
||||
const { showError } = useToaster()
|
||||
const { orgIdentifier, projectIdentifier } = useParams<Identifier>()
|
||||
const { data: aidaSettingResponse, loading: isAidaSettingLoading } = hooks?.useGetSettingValue({
|
||||
identifier: 'aida',
|
||||
queryParams: { accountIdentifier: routingId, orgIdentifier, projectIdentifier }
|
||||
})
|
||||
|
||||
const { mutate } = useMutate({
|
||||
verb: 'PATCH',
|
||||
|
@ -103,7 +110,7 @@ export const DescriptionBox: React.FC<DescriptionBoxProps> = ({
|
|||
outlets={{
|
||||
[CommentBoxOutletPosition.START_OF_MARKDOWN_EDITOR_TOOLBAR]: (
|
||||
<>
|
||||
{SEMANTIC_SEARCH_ENABLED && !standalone ? (
|
||||
{!isAidaSettingLoading && aidaSettingResponse?.data?.value == 'true' && !standalone ? (
|
||||
<Button
|
||||
size={ButtonSize.SMALL}
|
||||
variation={ButtonVariation.ICON}
|
||||
|
@ -132,7 +139,8 @@ export const DescriptionBox: React.FC<DescriptionBoxProps> = ({
|
|||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
),
|
||||
[CommentBoxOutletPosition.ENABLE_AIDA_PR_DESC_BANNER]: <EnableAidaBanner />
|
||||
}}
|
||||
onSave={value => {
|
||||
if (value?.split('\n').some(line => line.length > Config.MAX_TEXT_LINE_SIZE_LIMIT)) {
|
||||
|
|
|
@ -650,7 +650,8 @@ export const PAGE_CONTAINER_WIDTH = '--page-container-width'
|
|||
|
||||
// Outlets are used to insert additional components into CommentBox
|
||||
export enum CommentBoxOutletPosition {
|
||||
START_OF_MARKDOWN_EDITOR_TOOLBAR = 'start_of_markdown_editor_toolbar'
|
||||
START_OF_MARKDOWN_EDITOR_TOOLBAR = 'start_of_markdown_editor_toolbar',
|
||||
ENABLE_AIDA_PR_DESC_BANNER = 'enable_aida_pr_desc_banner'
|
||||
}
|
||||
|
||||
// Helper function to escape special characters for use in regex
|
||||
|
|
|
@ -48,3 +48,9 @@ enum Vote {
|
|||
Up,
|
||||
Down
|
||||
}
|
||||
|
||||
export interface Identifier {
|
||||
accountId: string
|
||||
orgIdentifier: string
|
||||
projectIdentifier: string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue