Skip to content

Commit 2e9eca7

Browse files
committed
AXON-1333: Add mentions provider for BB AKE (#1168)
* AXON-1333: Add mentions provider for BB AKE * AXON-1333: Fix mentions for DC
1 parent cf52b45 commit 2e9eca7

File tree

8 files changed

+95
-20
lines changed

8 files changed

+95
-20
lines changed

src/react/atlascode/common/CommentForm.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type CommentFormProps = {
1111
onSave: (content: string) => Promise<void>;
1212
onCancel?: () => void;
1313
fetchUsers?: (input: string) => Promise<User[]>;
14+
mentionsProvider: AtlascodeMentionProvider | undefined;
1415
};
1516

1617
const CommentForm: React.FC<CommentFormProps> = (props: CommentFormProps) => {
@@ -27,9 +28,9 @@ const CommentForm: React.FC<CommentFormProps> = (props: CommentFormProps) => {
2728
defaultValue={props.initialContent}
2829
onSave={props.onSave}
2930
onCancel={props.onCancel}
30-
mentionProvider={Promise.resolve({
31-
unsubscribe: () => {},
32-
} as any as AtlascodeMentionProvider)}
31+
mentionProvider={
32+
props.mentionsProvider ? Promise.resolve(props.mentionsProvider) : undefined
33+
}
3334
isBitbucket={true}
3435
/>
3536
</div>

src/react/atlascode/pullrequest/InlineRenderedTextEditor.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type InlineTextEditorProps = {
3737
htmlContent: string;
3838
onSave?: (value: string) => void;
3939
fetchUsers?: (input: string) => Promise<User[]>;
40+
mentionsProvider?: AtlascodeMentionProvider;
4041
};
4142

4243
const InlineRenderedTextEditor: React.FC<InlineTextEditorProps> = (props: InlineTextEditorProps) => {
@@ -64,7 +65,7 @@ const InlineRenderedTextEditor: React.FC<InlineTextEditorProps> = (props: Inline
6465
defaultValue={props.htmlContent}
6566
onSave={handleSave}
6667
onCancel={exitEditMode}
67-
mentionProvider={Promise.resolve({ unsubscribe: () => {} } as any as AtlascodeMentionProvider)}
68+
mentionProvider={props.mentionsProvider ? Promise.resolve(props.mentionsProvider) : undefined}
6869
isBitbucket={true}
6970
/>
7071
</div>

src/react/atlascode/pullrequest/NestedComment.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Avatar, Box, Button, CircularProgress, Grid, Tooltip, Typography } from
22
import { makeStyles } from '@mui/styles';
33
import { format, parseISO } from 'date-fns';
44
import React, { useCallback, useContext, useEffect, useState } from 'react';
5+
import { AtlascodeMentionProvider } from 'src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider';
56

67
import { Comment, PullRequestState, User } from '../../../bitbucket/model';
78
import CommentForm from '../common/CommentForm';
@@ -55,6 +56,7 @@ type NestedCommentProps = {
5556
fetchUsers: (input: string) => Promise<User[]>;
5657
onDelete: (comment: Comment) => Promise<void>;
5758
pullRequestState: PullRequestState;
59+
mentionsProvider?: AtlascodeMentionProvider;
5860
};
5961

6062
export const NestedComment: React.FunctionComponent<NestedCommentProps> = ({
@@ -63,6 +65,7 @@ export const NestedComment: React.FunctionComponent<NestedCommentProps> = ({
6365
fetchUsers,
6466
onDelete,
6567
pullRequestState,
68+
mentionsProvider,
6669
}) => {
6770
const classes = useStyles();
6871
const [isReplying, setIsReplying] = useState(false);
@@ -215,6 +218,7 @@ export const NestedComment: React.FunctionComponent<NestedCommentProps> = ({
215218
onSave={handleSave}
216219
onCancel={handleCancel}
217220
fetchUsers={fetchUsers}
221+
mentionsProvider={mentionsProvider}
218222
/>
219223
</Box>
220224
)}
@@ -227,6 +231,7 @@ export const NestedComment: React.FunctionComponent<NestedCommentProps> = ({
227231
onDelete={onDelete}
228232
fetchUsers={fetchUsers}
229233
pullRequestState={pullRequestState}
234+
mentionsProvider={mentionsProvider}
230235
/>
231236
</Box>
232237
</Grid>
@@ -243,6 +248,7 @@ export const NestedComment: React.FunctionComponent<NestedCommentProps> = ({
243248
onSave={handleEdit}
244249
onCancel={handleCancelEdit}
245250
fetchUsers={fetchUsers}
251+
mentionsProvider={mentionsProvider}
246252
/>
247253
</Box>
248254
)}

src/react/atlascode/pullrequest/NestedCommentList.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Grid } from '@mui/material';
22
import { makeStyles } from '@mui/styles';
33
import React from 'react';
4+
import { AtlascodeMentionProvider } from 'src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider';
45

56
import { Comment, PullRequestState, User } from '../../../bitbucket/model';
67
import { NestedComment } from './NestedComment';
@@ -11,6 +12,7 @@ type NestedCommentListProps = {
1112
fetchUsers: (input: string) => Promise<User[]>;
1213
onDelete: (comment: Comment) => Promise<void>;
1314
pullRequestState: PullRequestState;
15+
mentionsProvider?: AtlascodeMentionProvider;
1416
};
1517

1618
const useStyles = makeStyles({
@@ -25,6 +27,7 @@ export const NestedCommentList: React.FunctionComponent<NestedCommentListProps>
2527
fetchUsers,
2628
onDelete,
2729
pullRequestState,
30+
mentionsProvider,
2831
}) => {
2932
const classes = useStyles();
3033
return (
@@ -37,6 +40,7 @@ export const NestedCommentList: React.FunctionComponent<NestedCommentListProps>
3740
fetchUsers={fetchUsers}
3841
onDelete={onDelete}
3942
pullRequestState={pullRequestState}
43+
mentionsProvider={mentionsProvider}
4044
/>
4145
</Grid>
4246
))}

src/react/atlascode/pullrequest/PullRequestDetailsPage.tsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { MentionNameStatus } from '@atlaskit/mention';
12
import { setGlobalTheme } from '@atlaskit/tokens';
23
import { InlineTextEditor } from '@atlassianlabs/guipi-core-components';
34
import {
@@ -14,8 +15,9 @@ import {
1415
} from '@mui/material';
1516
import { makeStyles } from '@mui/styles';
1617
import AwesomeDebouncePromise from 'awesome-debounce-promise';
17-
import React, { useEffect } from 'react';
18+
import React, { useEffect, useMemo } from 'react';
1819
import { AnalyticsView } from 'src/analyticsTypes';
20+
import { AtlascodeMentionProvider } from 'src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider';
1921

2022
import { User } from '../../../bitbucket/model';
2123
import { AtlascodeErrorBoundary } from '../common/ErrorBoundary';
@@ -171,6 +173,49 @@ function PullRequestDetailsPageContent({ state, controller }: PullRequestDetails
171173
300,
172174
{ leading: false },
173175
);
176+
177+
const mentionsProvider = useMemo(() => {
178+
if (!state?.pr?.site?.details?.baseApiUrl) {
179+
return;
180+
}
181+
return AtlascodeMentionProvider.init(
182+
{
183+
url: '',
184+
mentionNameResolver: {
185+
lookupName: async (id: string) => {
186+
const accountId = id.split('accountid:')[1];
187+
if (!accountId) {
188+
return {
189+
id,
190+
name: 'Unknown User',
191+
status: MentionNameStatus.UNKNOWN,
192+
};
193+
}
194+
const users = await handleFetchUsers(accountId);
195+
if (users.length === 0) {
196+
return {
197+
id,
198+
name: 'Unknown User',
199+
status: MentionNameStatus.UNKNOWN,
200+
};
201+
}
202+
const resolvedMention = {
203+
id,
204+
name: users[0].displayName,
205+
status: MentionNameStatus.OK,
206+
};
207+
return resolvedMention;
208+
},
209+
cacheName: (_id: string, _name: string) => {
210+
// currently this method is never called by Atlaskit. So it is implemented only to satisfy the interface
211+
},
212+
},
213+
isBitbucketCloud: state.pr.site.details.isCloud,
214+
},
215+
handleFetchUsers,
216+
);
217+
}, [state?.pr?.site.details, handleFetchUsers]);
218+
174219
return (
175220
<>
176221
<PullRequestHeader state={state} controller={controller} />
@@ -184,6 +229,7 @@ function PullRequestDetailsPageContent({ state, controller }: PullRequestDetails
184229
state={state}
185230
controller={controller}
186231
handleFetchUsers={handleFetchUsers}
232+
mentionsProvider={mentionsProvider}
187233
/>
188234
</Paper>
189235
</Grid>

src/react/atlascode/pullrequest/PullRequestMainContent.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Grid } from '@mui/material';
22
import React from 'react';
3+
import { AtlascodeMentionProvider } from 'src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider';
34

45
import { User } from '../../../bitbucket/model';
56
import { BasicPanel } from '../common/BasicPanel';
@@ -16,12 +17,14 @@ interface PullRequestMainContentProps {
1617
state: PullRequestDetailsState;
1718
controller: PullRequestDetailsControllerApi;
1819
handleFetchUsers: (input: string, abortSignal?: AbortSignal) => Promise<User[]>;
20+
mentionsProvider?: AtlascodeMentionProvider;
1921
}
2022

2123
export const PullRequestMainContent: React.FC<PullRequestMainContentProps> = ({
2224
state,
2325
controller,
2426
handleFetchUsers,
27+
mentionsProvider,
2528
}) => {
2629
return (
2730
<Box margin={2}>
@@ -35,6 +38,7 @@ export const PullRequestMainContent: React.FC<PullRequestMainContentProps> = ({
3538
fetchUsers={handleFetchUsers}
3639
isLoading={state.loadState.basicData}
3740
summaryChange={controller.updateSummary}
41+
mentionsProvider={mentionsProvider}
3842
/>
3943
</Grid>
4044
{state.relatedJiraIssues.length > 0 && (
@@ -86,13 +90,15 @@ export const PullRequestMainContent: React.FC<PullRequestMainContentProps> = ({
8690
fetchUsers={handleFetchUsers}
8791
onDelete={controller.deleteComment}
8892
pullRequestState={state.pr.data.state}
93+
mentionsProvider={mentionsProvider}
8994
/>
9095
</Grid>
9196
<Grid item>
9297
<CommentForm
9398
currentUser={state.currentUser}
9499
fetchUsers={handleFetchUsers}
95100
onSave={controller.postComment}
101+
mentionsProvider={mentionsProvider}
96102
/>
97103
</Grid>
98104
</Grid>

src/react/atlascode/pullrequest/SummaryPanel.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { memo, useCallback } from 'react';
2+
import { AtlascodeMentionProvider } from 'src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider';
23

34
import { User } from '../../../bitbucket/model';
45
import { BasicPanel } from '../common/BasicPanel';
@@ -11,10 +12,11 @@ interface SummaryPanelProps {
1112
summaryChange: (text: string) => void;
1213
isLoading: boolean;
1314
isDefaultExpanded?: boolean;
15+
mentionsProvider?: AtlascodeMentionProvider;
1416
}
1517

1618
export const SummaryPanel: React.FC<SummaryPanelProps> = memo(
17-
({ rawSummary, htmlSummary, fetchUsers, summaryChange, isLoading, isDefaultExpanded }) => {
19+
({ rawSummary, htmlSummary, fetchUsers, summaryChange, isLoading, isDefaultExpanded, mentionsProvider }) => {
1820
const handleFetchUsers = useCallback(
1921
async (input: string) => {
2022
return await fetchUsers(input);
@@ -41,6 +43,7 @@ export const SummaryPanel: React.FC<SummaryPanelProps> = memo(
4143
htmlContent={htmlSummary}
4244
onSave={handleSummaryChange}
4345
fetchUsers={handleFetchUsers}
46+
mentionsProvider={mentionsProvider}
4447
/>
4548
</BasicPanel>
4649
);

src/webviews/components/issue/common/AtlaskitEditor/AtlascodeMentionsProvider.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@ import {
55
MentionResourceConfig,
66
ResolvingMentionProvider,
77
} from '@atlaskit/mention';
8+
import { User } from 'src/bitbucket/model';
89

910
import { MentionInfo } from '../../AbstractIssueEditorPage';
11+
type FetchJiraUsersFunc = (input: string, accountId?: string) => Promise<MentionInfo[]>;
12+
type FetchBBUsersFunc = (input: string, abortSignal?: AbortSignal) => Promise<User[]>;
13+
14+
type ExtendedMentionResourceConfig = MentionResourceConfig & {
15+
isBitbucketCloud?: boolean;
16+
};
1017

1118
export class AtlascodeMentionProvider extends AbstractMentionResource implements ResolvingMentionProvider {
1219
static #instance: AtlascodeMentionProvider;
1320

14-
private config: MentionResourceConfig;
15-
private fetchUsers: (input: string, accountId?: string) => Promise<MentionInfo[]>;
21+
private config: ExtendedMentionResourceConfig;
22+
private fetchUsers: FetchJiraUsersFunc | FetchBBUsersFunc;
1623
private mentionRequests: Map<
1724
string,
1825
{
@@ -23,8 +30,8 @@ export class AtlascodeMentionProvider extends AbstractMentionResource implements
2330
private cacheDuration = 300000; // 5 minutes
2431

2532
public static init(
26-
config: MentionResourceConfig,
27-
fetchUsers: (input: string, accountId?: string) => Promise<MentionInfo[]>,
33+
config: ExtendedMentionResourceConfig,
34+
fetchUsers: FetchJiraUsersFunc | FetchBBUsersFunc,
2835
): AtlascodeMentionProvider {
2936
if (!AtlascodeMentionProvider.#instance) {
3037
AtlascodeMentionProvider.#instance = new AtlascodeMentionProvider(config, fetchUsers);
@@ -34,24 +41,25 @@ export class AtlascodeMentionProvider extends AbstractMentionResource implements
3441
}
3542

3643
// Making the constructor private to enforce singleton pattern
37-
private constructor(
38-
_config: MentionResourceConfig,
39-
_fetchUsers: (input: string, accountId?: string) => Promise<MentionInfo[]>,
40-
) {
44+
private constructor(_config: ExtendedMentionResourceConfig, _fetchUsers: FetchJiraUsersFunc | FetchBBUsersFunc) {
4145
super();
4246
this.config = _config;
4347
this.fetchUsers = _fetchUsers;
4448
}
4549

4650
override filter(query?: string): void {
51+
const isBitbucketCloud = this.config.isBitbucketCloud;
4752
setTimeout(async () => {
4853
const users = await this.fetchUsers(query || '');
49-
const mentions = users.map((user) => ({
50-
id: `${user.accountId}`,
51-
name: user.displayName,
52-
mentionName: user.mention,
53-
avatarUrl: user.avatarUrl,
54-
}));
54+
const mentions = users.map((user) => {
55+
const mention = {
56+
id: isBitbucketCloud ? `{${user.accountId}}` : `${user.accountId}`,
57+
name: user.displayName,
58+
mentionName: user.mention,
59+
avatarUrl: user.avatarUrl,
60+
};
61+
return mention;
62+
});
5563
this._notifyListeners({ mentions, query: query || '' }, {});
5664
this._notifyAllResultsListeners({ mentions, query: query || '' });
5765
}, 30 + 1);

0 commit comments

Comments
 (0)