Skip to content

Commit 8e085c7

Browse files
Add IDE buttons to Incident details page (#1445)
* Add IDE buttons to Incident page * Add jiti as explicit dependency for ESLint * Improve styling in Directives table --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 3b99bef commit 8e085c7

File tree

32 files changed

+544
-148
lines changed

32 files changed

+544
-148
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
contents: read
1717
actions: write
1818
runs-on: ubuntu-latest
19+
1920
outputs:
2021
artifact-name: ${{ steps.get-artifact-name.outputs.artifact_name }}
2122
steps:
@@ -29,7 +30,7 @@ jobs:
2930
- run: npm ci
3031

3132
- env:
32-
GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }} # TODO: fix
33+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3334
run: npm run build:prod:${{ inputs.platform }}
3435

3536
- name: Get artifact name

.github/workflows/release-asset.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ jobs:
2727
with:
2828
files: dist/${{ inputs.artifact-name }}.zip
2929
env:
30-
GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }}
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/update-dependencies.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
2929
- name: Commit, push changes and create PR
3030
env:
31-
GH_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }}
31+
GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }}
3232
run: |
3333
git config user.name "github-actions[bot]"
3434
git config user.email "github-actions[bot]@users.noreply.github.com"

package-lock.json

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "digma-ui",
3-
"version": "16.6.4",
3+
"version": "16.7.0-alpha.3",
44
"description": "Digma UI",
55
"scripts": {
66
"lint:eslint": "eslint --cache .",
@@ -96,6 +96,7 @@
9696
"husky": "^9.1.7",
9797
"jest": "^30.0.5",
9898
"jest-environment-jsdom": "^30.0.5",
99+
"jiti": "^2.5.1",
99100
"knip": "^5.62.0",
100101
"lint-staged": "^16.1.2",
101102
"postcss-styled-syntax": "^0.7.1",

src/components/Admin/common/RepositorySidebarOverlay/RepositorySidebar/Header/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const Header = ({
100100
onGoHome={handleGoHome}
101101
/>
102102
<ScopeBar
103-
isExpanded={false}
103+
isExpanded={isSpanInfoVisible}
104104
isSpanInfoEnabled={isSpanInfoEnabled}
105105
linkedEndpoints={linkedEndpoints}
106106
scope={scope}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const addChatContextIncidentFile = (
2+
ideUriScheme: string,
3+
incidentId: string
4+
): void => {
5+
const url = `${ideUriScheme}://digma.digma/chat/context/add/file/incident/${incidentId}`;
6+
window.open(url, "_blank", "noopener noreferrer");
7+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { useEffect, useState, type ComponentType } from "react";
2+
import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent";
3+
import { uniqueBy } from "../../../../../utils/uniqueBy";
4+
import { VSCodeLogoIcon } from "../../../../common/icons/100px/VSCodeLogoIcon";
5+
import { CursorLogoIcon } from "../../../../common/icons/24px/CursorLogoIcon";
6+
import type { IconProps } from "../../../../common/icons/types";
7+
import { NewIconButton } from "../../../../common/v3/NewIconButton";
8+
import { Tooltip } from "../../../../common/v3/Tooltip";
9+
import { trackingEvents } from "../../../tracking";
10+
import { addChatContextIncidentFile } from "./addChatContextFile";
11+
import { scanRunningVSCodeIdeProjects } from "./scanRunningVSCodeIdeProjects";
12+
import * as s from "./styles";
13+
import type { IdeToolbarProps, VSCodeExtensionInfo } from "./types";
14+
15+
const IDE_ICONS: Record<string, ComponentType<IconProps>> = {
16+
cursor: CursorLogoIcon,
17+
vscode: VSCodeLogoIcon
18+
};
19+
20+
export const IdeToolbar = ({ incidentId }: IdeToolbarProps) => {
21+
const [ides, setIdes] = useState<VSCodeExtensionInfo[]>();
22+
23+
const handleIdeButtonClick = (ide: string) => {
24+
sendUserActionTrackingEvent(trackingEvents.INCIDENT_IDE_BUTTON_CLICKED, {
25+
ide
26+
});
27+
addChatContextIncidentFile(ide, incidentId);
28+
};
29+
30+
useEffect(() => {
31+
const scan = async () => {
32+
try {
33+
const results = await scanRunningVSCodeIdeProjects();
34+
const ides = uniqueBy(
35+
results.map((x) => x.response),
36+
"ideUriScheme"
37+
);
38+
setIdes(ides);
39+
} catch {
40+
setIdes([]);
41+
}
42+
};
43+
44+
void scan();
45+
}, []);
46+
47+
if (!ides || ides.length === 0) {
48+
return null;
49+
}
50+
51+
return (
52+
<s.Container>
53+
{ides
54+
?.map((ide) => {
55+
const IdeIcon = IDE_ICONS[ide.ideUriScheme];
56+
57+
if (!IdeIcon) {
58+
return null;
59+
}
60+
61+
return (
62+
<Tooltip
63+
title={"Attach to chat in " + ide.ideName}
64+
key={ide.ideUriScheme}
65+
>
66+
<NewIconButton
67+
buttonType={"secondaryBorderless"}
68+
size={"large"}
69+
key={ide.ideUriScheme}
70+
icon={(props) => <IdeIcon {...props} />}
71+
onClick={() => handleIdeButtonClick(ide.ideUriScheme)}
72+
/>
73+
</Tooltip>
74+
);
75+
})
76+
.filter(Boolean)}
77+
</s.Container>
78+
);
79+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import axios from "axios";
2+
import { isString } from "../../../../../typeGuards/isString";
3+
import type { VSCodeExtensionInfo, VSCodeIdeScanningResult } from "./types";
4+
5+
const START_PORT_TO_SCAN = 33100;
6+
const END_PORT_TO_SCAN = 33119;
7+
8+
const ABOUT_PATH = "api/digma/about";
9+
10+
export const scanRunningVSCodeIdeProjects =
11+
async (): Promise<VSCodeIdeScanningResult> => {
12+
const instances = Array.from(
13+
{ length: END_PORT_TO_SCAN - START_PORT_TO_SCAN + 1 },
14+
(_, i) => START_PORT_TO_SCAN + i
15+
).map((port) => ({
16+
port,
17+
url: `http://localhost:${port}/${ABOUT_PATH}`
18+
}));
19+
20+
const responses = await Promise.allSettled(
21+
instances.map((x) =>
22+
axios
23+
.get<VSCodeExtensionInfo>(x.url)
24+
.then((response) => ({ port: x.port, response: response.data }))
25+
.catch((error) => ({
26+
port: x.port,
27+
response: axios.isAxiosError(error)
28+
? `${error.message}`
29+
: "Unknown error"
30+
}))
31+
)
32+
);
33+
34+
const successfulResponses = responses.filter(
35+
(x) => x.status === "fulfilled" && !isString(x.value.response)
36+
) as unknown as PromiseFulfilledResult<{
37+
port: number;
38+
response: VSCodeExtensionInfo;
39+
}>[];
40+
41+
return successfulResponses.map((x) => x.value);
42+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from "styled-components";
2+
3+
export const Container = styled.div`
4+
display: flex;
5+
align-items: center;
6+
gap: 8px;
7+
`;

0 commit comments

Comments
 (0)