Skip to content

Commit db134a1

Browse files
committed
Add Linear to autolink settings
(#4605, #4613)
1 parent b204f48 commit db134a1

File tree

4 files changed

+65
-18
lines changed

4 files changed

+65
-18
lines changed

src/plus/integrations/authentication/models.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ export function isSupportedCloudIntegrationId(id: string): id is SupportedCloudI
6969
return getSupportedCloudIntegrationIds().includes(id as SupportedCloudIntegrationIds);
7070
}
7171

72+
export function isIssueCloudIntegrationId(id: string): id is IssuesCloudHostIntegrationId {
73+
const issueIds: string[] = Object.values(IssuesCloudHostIntegrationId);
74+
return issueIds.includes(id);
75+
}
76+
7277
export const toIntegrationId: { [key in CloudIntegrationType]: IntegrationIds } = {
7378
jira: IssuesCloudHostIntegrationId.Jira,
7479
linear: IssuesCloudHostIntegrationId.Linear,

src/webviews/apps/settings/settings.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import './settings.scss';
33
import type { ConnectCloudIntegrationsCommandArgs } from '../../../commands/cloudIntegrations';
44
import type { AutolinkConfig } from '../../../config';
5-
import type { IssuesCloudHostIntegrationId, SupportedCloudIntegrationIds } from '../../../constants.integrations';
5+
import type { SupportedCloudIntegrationIds } from '../../../constants.integrations';
6+
import { IssuesCloudHostIntegrationId } from '../../../constants.integrations';
67
import { createCommandLink } from '../../../system/commands';
78
import type { IpcMessage, UpdateConfigurationParams } from '../../protocol';
89
import { DidChangeConfigurationNotification, UpdateConfigurationCommand } from '../../protocol';
910
import type { State } from '../../settings/protocol';
1011
import {
1112
DidChangeAccountNotification,
12-
DidChangeConnectedJiraNotification,
13+
DidChangeIssueIntegrationConnectedNotification,
1314
DidOpenAnchorNotification,
1415
GenerateConfigurationPreviewRequest,
1516
} from '../../settings/protocol';
@@ -159,8 +160,12 @@ export class SettingsApp extends App<State> {
159160
this.renderAutolinkIntegration();
160161
break;
161162

162-
case DidChangeConnectedJiraNotification.is(msg):
163-
this.state.hasConnectedJira = msg.params.hasConnectedJira;
163+
case DidChangeIssueIntegrationConnectedNotification.is(msg):
164+
if (msg.params.integrationId === IssuesCloudHostIntegrationId.Jira) {
165+
this.state.hasConnectedJira = msg.params.connected;
166+
} else if (msg.params.integrationId === IssuesCloudHostIntegrationId.Linear) {
167+
this.state.hasConnectedLinear = msg.params.connected;
168+
}
164169
this.setState(this.state);
165170
this.renderAutolinkIntegration();
166171
break;
@@ -804,8 +809,8 @@ export class SettingsApp extends App<State> {
804809
const $root = document.querySelector('[data-component="autolink-integration"]');
805810
if ($root == null) return;
806811

807-
const { hasAccount, hasConnectedJira } = this.state;
808-
let message = `<a href="${createCommandLink<ConnectCloudIntegrationsCommandArgs>(
812+
const { hasAccount, hasConnectedJira, hasConnectedLinear } = this.state;
813+
let messageJira = `<a href="${createCommandLink<ConnectCloudIntegrationsCommandArgs>(
809814
'gitlens.plus.cloudIntegrations.connect',
810815
{
811816
integrationIds: ['jira' as IssuesCloudHostIntegrationId.Jira] as SupportedCloudIntegrationIds[],
@@ -821,11 +826,30 @@ export class SettingsApp extends App<State> {
821826
hasAccount ? '' : 'sign up and '
822827
}get access to automatic rich Jira autolinks.`;
823828
if (hasAccount && hasConnectedJira) {
824-
message =
829+
messageJira =
825830
'<i class="codicon codicon-check" style="vertical-align: text-bottom"></i> Jira connected &mdash; automatic rich Jira autolinks are enabled.';
826831
}
832+
let messageLinear = `<a href="${createCommandLink<ConnectCloudIntegrationsCommandArgs>(
833+
'gitlens.plus.cloudIntegrations.connect',
834+
{
835+
integrationIds: ['linear' as IssuesCloudHostIntegrationId.Linear] as SupportedCloudIntegrationIds[],
836+
source: {
837+
source: 'settings',
838+
detail: {
839+
action: 'connect',
840+
integration: 'linear',
841+
},
842+
},
843+
},
844+
)}">Connect to Linear</a> &mdash; ${
845+
hasAccount ? '' : 'sign up and '
846+
}get access to automatic rich Linear autolinks.`;
847+
if (hasAccount && hasConnectedLinear) {
848+
messageLinear =
849+
'<i class="codicon codicon-check" style="vertical-align: text-bottom"></i> Linear connected &mdash; automatic rich Linear autolinks are enabled.';
850+
}
827851

828-
$root.innerHTML = message;
852+
$root.innerHTML = `${messageJira}<br/>${messageLinear}`;
829853
}
830854

831855
private renderAutolinks() {

src/webviews/settings/protocol.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Config } from '../../config';
2+
import type { IssuesCloudHostIntegrationId } from '../../constants.integrations';
23
import type { IpcScope, WebviewState } from '../protocol';
34
import { IpcNotification, IpcRequest } from '../protocol';
45

@@ -12,6 +13,7 @@ export interface State extends WebviewState {
1213
scopes: ['user' | 'workspace', string][];
1314
hasAccount: boolean;
1415
hasConnectedJira: boolean;
16+
hasConnectedLinear: boolean;
1517
}
1618

1719
// REQUESTS
@@ -43,10 +45,9 @@ export interface DidChangeAccountParams {
4345
}
4446
export const DidChangeAccountNotification = new IpcNotification<DidChangeAccountParams>(scope, 'didChangeAccount');
4547

46-
export interface DidChangeConnectedJiraParams {
47-
hasConnectedJira: boolean;
48+
export interface DidChangeIssueIntegrationConnectedParams {
49+
integrationId: IssuesCloudHostIntegrationId;
50+
connected: boolean;
4851
}
49-
export const DidChangeConnectedJiraNotification = new IpcNotification<DidChangeConnectedJiraParams>(
50-
scope,
51-
'didChangeConnectedJira',
52-
);
52+
export const DidChangeIssueIntegrationConnectedNotification =
53+
new IpcNotification<DidChangeIssueIntegrationConnectedParams>(scope, 'didChangeIssueIntegrationConnected');

src/webviews/settings/settingsWebview.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import { GitFileChange } from '../../git/models/fileChange';
1010
import { GitFileIndexStatus } from '../../git/models/fileStatus';
1111
import { PullRequest } from '../../git/models/pullRequest';
1212
import type { SubscriptionChangeEvent } from '../../plus/gk/subscriptionService';
13+
import { isIssueCloudIntegrationId } from '../../plus/integrations/authentication/models';
1314
import type { ConnectionStateChangeEvent } from '../../plus/integrations/integrationService';
1415
import type { ConfigPath, CoreConfigPath } from '../../system/-webview/configuration';
1516
import { configuration } from '../../system/-webview/configuration';
1617
import { map } from '../../system/iterable';
18+
import { getSettledValue } from '../../system/promise';
1719
import type { CustomConfigPath, IpcMessage } from '../protocol';
1820
import {
1921
assertsConfigKeyValue,
@@ -25,7 +27,7 @@ import type { WebviewHost, WebviewProvider } from '../webviewProvider';
2527
import type { State } from './protocol';
2628
import {
2729
DidChangeAccountNotification,
28-
DidChangeConnectedJiraNotification,
30+
DidChangeIssueIntegrationConnectedNotification,
2931
DidOpenAnchorNotification,
3032
GenerateConfigurationPreviewRequest,
3133
} from './protocol';
@@ -61,8 +63,12 @@ export class SettingsWebviewProvider implements WebviewProvider<State, State, Se
6163
}
6264

6365
private onIntegrationConnectionStateChanged(e: ConnectionStateChangeEvent) {
64-
if (e.key === 'jira') {
65-
void this.host.notify(DidChangeConnectedJiraNotification, { hasConnectedJira: e.reason === 'connected' });
66+
const key = e.key;
67+
if (isIssueCloudIntegrationId(key)) {
68+
void this.host.notify(DidChangeIssueIntegrationConnectedNotification, {
69+
integrationId: key,
70+
connected: e.reason === 'connected',
71+
});
6672
}
6773
}
6874

@@ -76,12 +82,22 @@ export class SettingsWebviewProvider implements WebviewProvider<State, State, Se
7682
return jira.maybeConnected ?? jira.isConnected();
7783
}
7884

85+
async getLinearConnected(): Promise<boolean> {
86+
const linear = await this.container.integrations.get(IssuesCloudHostIntegrationId.Linear);
87+
if (linear == null) return false;
88+
return linear.maybeConnected ?? linear.isConnected();
89+
}
90+
7991
async includeBootstrap(): Promise<State> {
8092
const scopes: ['user' | 'workspace', string][] = [['user', 'User']];
8193
if (workspace.workspaceFolders?.length) {
8294
scopes.push(['workspace', 'Workspace']);
8395
}
8496

97+
const [jiraConnected, linearConnected] = (
98+
await Promise.allSettled([this.getJiraConnected(), this.getLinearConnected()])
99+
).map(r => getSettledValue(r, false));
100+
85101
return {
86102
...this.host.baseWebviewState,
87103
version: this.container.version,
@@ -91,7 +107,8 @@ export class SettingsWebviewProvider implements WebviewProvider<State, State, Se
91107
scope: 'user',
92108
scopes: scopes,
93109
hasAccount: await this.getAccountState(),
94-
hasConnectedJira: await this.getJiraConnected(),
110+
hasConnectedJira: jiraConnected,
111+
hasConnectedLinear: linearConnected,
95112
};
96113
}
97114

0 commit comments

Comments
 (0)