Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,69 @@
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Thin.ttf") format("truetype");
font-weight: 100;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-ExtraLight.ttf") format("truetype");
font-weight: 200;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Medium.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-SemiBold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Bold.ttf") format("truetype");
font-weight: 800;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
}

#storybook-root {
height: 100%;
}
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM nginx:1.25.0
FROM nginx:1.27.2

COPY ./dist/ /usr/share/nginx/html/
COPY ./nginx.conf.template /etc/nginx/conf.d/default.conf.template
RUN rm /usr/share/nginx/html/index.html

CMD ["/bin/sh" , "-c" , "envsubst '${PLUGIN_API_URL} ${PLUGIN_API_TOKEN}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
CMD ["/bin/sh" , "-c" , "cp /etc/nginx/conf.d/default.conf.template /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
63 changes: 63 additions & 0 deletions assets/index.web.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,69 @@
font-weight: 500;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Thin.ttf") format("truetype");
font-weight: 100;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-ExtraLight.ttf") format("truetype");
font-weight: 200;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Medium.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-SemiBold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Bold.ttf") format("truetype");
font-weight: 800;
font-style: normal;
}

@font-face {
font-family: "Alexandria";
src: url("/fonts/Alexandria-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
}
</style>
</head>
<body>
Expand Down
10 changes: 0 additions & 10 deletions nginx.conf.template
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
map "${PLUGIN_API_TOKEN}" $headerValue {
"" "";
"~*^(.+)$" "Token $1";
}

server {
listen 80;
root /usr/share/nginx/html;
absolute_redirect off;

location /api/ {
proxy_pass ${PLUGIN_API_URL}/;
proxy_set_header Authorization $headerValue;
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "digma-ui",
"version": "1.1.0",
"version": "2.0.0",
"description": "Digma UI",
"main": "dist/index.js",
"scripts": {
Expand All @@ -15,6 +15,7 @@
"build-storybook": "storybook build",
"build:dashboard:dev": "webpack --config webpack.dev.ts --env app=dashboard",
"build:documentation:dev": "webpack --config webpack.dev.ts --env app=documentation",
"build:ide-launcher:dev": "webpack --config webpack.dev.ts --env app=ideLauncher",
"build:installation-wizard:dev": "webpack --config webpack.dev.ts --env app=installationWizard",
"build:main:dev": "webpack --config webpack.dev.ts --env app=main",
"build:notifications:dev": "webpack --config webpack.dev.ts --env app=notifications",
Expand All @@ -24,6 +25,7 @@
"build:dev:web": "webpack --config webpack.dev.ts --env platform=Web",
"build:dashboard:prod": "webpack --config webpack.prod.ts --env app=dashboard",
"build:documentation:prod": "webpack --config webpack.prod.ts --env app=documentation",
"build:ide-launcher:prod": "webpack --config webpack.prod.ts --env app=ideLauncher",
"build:installation-wizard:prod": "webpack --config webpack.prod.ts --env app=installationWizard",
"build:main:prod": "webpack --config webpack.prod.ts --env app=main",
"build:notifications:prod": "webpack --config webpack.prod.ts --env app=notifications",
Expand Down
Binary file added public/fonts/Alexandria-Black.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-Bold.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-ExtraBold.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-ExtraLight.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-Light.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-Medium.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-Regular.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-SemiBold.ttf
Binary file not shown.
Binary file added public/fonts/Alexandria-Thin.ttf
Binary file not shown.
19 changes: 19 additions & 0 deletions src/components/IdeLauncher/IdeLauncher.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Meta, StoryObj } from "@storybook/react";
import { IdeLauncher } from ".";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof IdeLauncher> = {
title: "IDE Launcher/IdeLauncher",
component: IdeLauncher,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen"
}
};

export default meta;

type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {};
171 changes: 171 additions & 0 deletions src/components/IdeLauncher/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import axios from "axios";
import { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import { useTheme } from "styled-components";
import { isString } from "../../typeGuards/isString";
import { getThemeKind } from "../common/App/styles";
import { Select } from "../common/v3/Select";
import { SelectItem } from "../common/v3/Select/types";
import { scanIDEs } from "./scanIDEs";
import * as s from "./styles";

const SELECT_VALUE_DELIMITER = ":";

const getURLQueryParams = (url: string) => {
const searchParams = new URLSearchParams(url);
const params: Record<string, string> = {};
for (const [key, value] of searchParams.entries()) {
params[key] = value;
}
return params;
};

export const IdeLauncher = () => {
const theme = useTheme();
const themeKind = getThemeKind(theme);
const [isInitialLoading, setInitialLoading] = useState(true);
// const [isOpening, setIsOpening] = useState(false);
const [items, setItems] = useState<SelectItem[]>([]);
const params = getURLQueryParams(window.location.search);
const isMobile = ["Android", "iPhone", "iPad"].some((x) =>
window.navigator.userAgent.includes(x)
);

const handleSelectChange = (value: string | string[]) => {
const selectedValue = isString(value) ? value : value[0];
const [port, project] = selectedValue.split(SELECT_VALUE_DELIMITER);

const pluginParams = Object.entries(params).reduce((acc, [key, value]) => {
const KEY_PREFIX = "plugin.";
if (key.startsWith(KEY_PREFIX)) {
const newKey = key.replace(KEY_PREFIX, "");
acc[newKey] = value;
}

return acc;
}, {} as Record<string, string>);

axios
.get(`http://localhost:${port}/api/digma/show`, {
params: { ...pluginParams, projectName: project }
})
.then(() => {
// TODO: handle response
})
.catch(() => {
// TODO: handle error
});

// setIsOpening(true);

const itemToSelect = items.find((item) => item.value === selectedValue);
setItems(
items.map((item) => ({ ...item, selected: item === itemToSelect }))
);
};

useEffect(() => {
async function getIDEsInfo() {
const ideInfo = await scanIDEs();
const projects = ideInfo
.filter((x) => x.response.isCentralized)
.flatMap((info) =>
info.response.openProjects.map((project) => ({
...info,
project: project,
port: info.port
}))
);

setItems(
projects.map((x) => ({
label: `${x.response.name} (${x.project})`,
description: `${x.response.name} (${x.project})`,
value: [x.port, x.project].join(SELECT_VALUE_DELIMITER),
enabled: true,
selected: false
}))
);
setInitialLoading(false);
}

if (!isMobile) {
void getIDEsInfo();
}
}, [isMobile]);

const selectedItem = items.find((item) => item.selected);

const renderContent = () => {
if (isMobile) {
return (
<s.TextContainer>
<s.Title>Failed to open</s.Title>
<s.Description>
This cannot be opened on your mobile device. Please switch to a
desktop with an IDE installed.
</s.Description>
</s.TextContainer>
);
}

return isInitialLoading ? (
<>Scanning running IDEs...</>
) : (
<>
<s.TextContainer>
<s.Title>Select an IDE to view the Digma issue</s.Title>
<s.Description>
{items.length > 0 ? (
<>
Please select the IDE project you&apos;d like to open all
endpoints in the {params.environment ?? "selected"} environment.
</>
) : (
<>No IDEs with enabled Digma plugin found</>
)}
</s.Description>
</s.TextContainer>
{items.length > 0 && (
<s.SelectContainer>
<Select
placeholder={selectedItem?.label ?? "Select IDE Project"}
items={items}
onChange={handleSelectChange}
/>
</s.SelectContainer>
)}
</>
);
};

return (
<s.Container>
<Helmet>
<title>IDE Launcher</title>
</Helmet>
<s.Header>
<a
target={"_blank"}
rel={"noopener noreferrer"}
href={"https://digma.ai"}
>
<s.Logo src={`/images/digmaLogo_${themeKind}.svg`} />
</a>
</s.Header>

<s.Content>{renderContent()}</s.Content>
<s.Footer>
<span>&copy; {new Date().getFullYear()}</span>
<s.FooterLink
target={"_blank"}
rel={"noopener noreferrer"}
href={"https://digma.ai"}
>
digma.ai
</s.FooterLink>
<span>&#183; All Rights Reserved</span>
</s.Footer>
</s.Container>
);
};
Loading
Loading