mirror of https://github.com/harness/drone.git
feat: [CODE-3341] Add PR activity for reviewers AND codeowners that were added on PR creation (#3541)
* fix: [CODE-3341] lint checks * fix: [CODE-3341] lint checks * feat: [CODE-3341] refactor * feat: [CODE-3341] refactor * feat: [CODE-3341] Add PR activity for reviewers AND codeowners that were added on PR creationtry-new-ui
parent
bcc9fc50f1
commit
1e8ae8b47f
|
@ -36,7 +36,9 @@ export enum LabelActivity {
|
|||
export enum ReviewerAddActivity {
|
||||
REQUESTED = 'requested',
|
||||
ASSIGNED = 'assigned',
|
||||
SELF_ASSIGNED = 'self_assigned'
|
||||
SELF_ASSIGNED = 'self_assigned',
|
||||
DEFAULT = 'default',
|
||||
CODEOWNERS = 'code_owners'
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -881,6 +881,8 @@ export interface StringsMap {
|
|||
prHasNoConflicts: string
|
||||
prMustSelectSourceAndTargetBranches: string
|
||||
'prReview.assigned': string
|
||||
'prReview.codeowners': string
|
||||
'prReview.defaultReviewers': string
|
||||
'prReview.filterByReviews': string
|
||||
'prReview.removed': string
|
||||
'prReview.requested': string
|
||||
|
|
|
@ -387,6 +387,8 @@ prReview:
|
|||
removed: '{author} removed the request for review from {reviewer}'
|
||||
selfRemoved: '{author} removed their request for review'
|
||||
filterByReviews: Filter by Reviews
|
||||
codeowners: '{author} requested review from {codeowners} as code owners'
|
||||
defaultReviewers: '{author} requested review from {reviewers} as default reviewers'
|
||||
webhookListingContent: 'create,delete,deployment ...'
|
||||
general: 'General'
|
||||
webhooks: 'Webhooks'
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { Avatar, Container, Layout, StringSubstitute, Text } from '@harnessio/uicore'
|
||||
import { Icon, IconName } from '@harnessio/icons'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
|
@ -48,12 +48,47 @@ interface MergePayload {
|
|||
interface ReviewerAddActivityPayload {
|
||||
reviewer_type: ReviewerAddActivity
|
||||
}
|
||||
|
||||
const formatListWithAndFragment = (names: string[]): React.ReactNode => {
|
||||
const uniqueNames = [...new Set(names)] // Ensure uniqueness
|
||||
|
||||
switch (uniqueNames.length) {
|
||||
case 0:
|
||||
return null
|
||||
case 1:
|
||||
return <strong>{uniqueNames[0]}</strong>
|
||||
case 2:
|
||||
return (
|
||||
<>
|
||||
<strong>{uniqueNames[0]}</strong> and <strong>{uniqueNames[1]}</strong>
|
||||
</>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<>
|
||||
{uniqueNames.slice(0, -1).map((name, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<strong>{name}</strong>
|
||||
{index < uniqueNames.length - 2 ? ', ' : ''}
|
||||
</React.Fragment>
|
||||
))}{' '}
|
||||
and <strong>{uniqueNames[uniqueNames.length - 1]}</strong>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//ToDo : update all comment options with the correct payload type and remove Unknown
|
||||
export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, commentItems, repoMetadataPath }) => {
|
||||
const { getString } = useStrings()
|
||||
const payload = commentItems[0].payload
|
||||
const type = payload?.type
|
||||
const { routes } = useAppContext()
|
||||
const displayNameList = useMemo(() => {
|
||||
const checkList = payload?.metadata?.mentions?.ids ?? []
|
||||
const mentionsMap = payload?.mentions ?? {}
|
||||
return [...new Set(checkList.map(id => mentionsMap[id]?.display_name ?? ''))]
|
||||
}, [payload?.metadata?.mentions?.ids, payload?.mentions])
|
||||
|
||||
switch (type) {
|
||||
case CommentType.MERGE: {
|
||||
|
@ -425,8 +460,8 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
}
|
||||
|
||||
case CommentType.REVIEWER_ADD: {
|
||||
const mentionId = payload?.metadata?.mentions?.ids?.[0] ?? 0
|
||||
const mentionDisplayName = payload?.mentions?.[mentionId]?.display_name ?? ''
|
||||
const activityMentions = formatListWithAndFragment(displayNameList)
|
||||
|
||||
return (
|
||||
<Container className={css.mergedBox}>
|
||||
<Layout.Horizontal spacing="small" style={{ alignItems: 'center' }}>
|
||||
|
@ -438,7 +473,7 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
str={getString('prReview.assigned')}
|
||||
vars={{
|
||||
author: <strong>{payload?.author?.display_name}</strong>,
|
||||
reviewer: <strong>{mentionDisplayName}</strong>
|
||||
reviewer: activityMentions
|
||||
}}
|
||||
/>
|
||||
</Case>
|
||||
|
@ -447,7 +482,7 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
str={getString('prReview.requested')}
|
||||
vars={{
|
||||
author: <strong>{payload?.author?.display_name}</strong>,
|
||||
reviewer: <strong>{mentionDisplayName}</strong>
|
||||
reviewer: activityMentions
|
||||
}}
|
||||
/>
|
||||
</Case>
|
||||
|
@ -455,7 +490,25 @@ export const SystemComment: React.FC<SystemCommentProps> = ({ pullReqMetadata, c
|
|||
<StringSubstitute
|
||||
str={getString('prReview.selfAssigned')}
|
||||
vars={{
|
||||
reviewer: <strong>{mentionDisplayName}</strong>
|
||||
reviewer: activityMentions
|
||||
}}
|
||||
/>
|
||||
</Case>
|
||||
<Case val={ReviewerAddActivity.CODEOWNERS}>
|
||||
<StringSubstitute
|
||||
str={getString('prReview.codeowners')}
|
||||
vars={{
|
||||
author: <strong>{payload?.author?.display_name}</strong>,
|
||||
codeowners: activityMentions
|
||||
}}
|
||||
/>
|
||||
</Case>
|
||||
<Case val={ReviewerAddActivity.DEFAULT}>
|
||||
<StringSubstitute
|
||||
str={getString('prReview.defaultReviewers')}
|
||||
vars={{
|
||||
author: <strong>{payload?.author?.display_name}</strong>,
|
||||
reviewers: activityMentions
|
||||
}}
|
||||
/>
|
||||
</Case>
|
||||
|
|
|
@ -1113,3 +1113,12 @@ export const roleStringKeyMap: Record<EnumMembershipRole, StringKeys> = {
|
|||
reader: 'reader',
|
||||
space_owner: 'owner'
|
||||
}
|
||||
|
||||
export const formatListWithAnd = (list: string[]): string => {
|
||||
if (list) {
|
||||
if (list.length === 0) return ''
|
||||
if (list.length === 1) return list[0]
|
||||
if (list.length === 2) return list.join(' and ')
|
||||
return `${list.slice(0, -1).join(', ')} and ${list[list.length - 1]}`
|
||||
} else return ''
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue