diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 000000000..49a205275
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,109 @@
+# Copilot Instructions
+
+Digma UI is a React-based frontend for the Digma continuous feedback platform, designed to help developers analyze and improve code quality and runtime behavior. The project is a monorepo for multiple React applications and provides the distributions for different platforms: Web and IDEs (JetBrains, Visual Studio and VS Code)
+
+Tech stack: TypeScript, React, React Router, Tanstack Table, React Hook Form, Recharts, styled-components, RTK Query, zustand (deprecated), axios, Storybook, Jest, Webpack, ESLint.
+
+## Project Structure
+
+- **.github/**
+ GitHub-specific files such as workflows
+
+- **scripts/**
+ Utility scripts for development, build, and CI/CD automation.
+
+- **.husky/**
+ Git hooks managed by Husky for enforcing code quality and workflow automation.
+
+- **.storybook/**
+ Storybook configuration files for UI component development and documentation.
+
+- **.vscode/**
+ Visual Studio Code workspace settings and recommended extensions.
+
+- **src/**
+ Main source code for the Digma UI applications, including all React components, features, hooks, utilities, and configuration.
+
+- **src/components/**
+ Shared, reusable React components used across features and apps.
+
+- **src/api/**
+ Contains custom message API-related code, including service definitions, types, and API clients for communicating with backend services.
+
+- **src/containers/**
+ Entry points for React applications.
+
+- **src/history/**
+ Custom container for application history state management.
+
+- **src/hooks/**
+ Custom React hooks for shared logic across the applications.
+
+- **src/logging/**
+ Logger for application events and errors.
+
+- **src/redux/**
+ Redux store configuration, slices, and RTK Query services.
+
+- **src/store/**
+ Zustand stores and state management logic (deprecated).
+
+- **src/stories/**
+ Storybook stories for UI components.
+
+- **src/typeGuards/**
+ TypeScript type guard functions for runtime type checking.
+
+- **src/utils/**
+ General utility functions and helpers used throughout the project.
+
+- **public/**
+ Static assets served by the app (e.g., images, fonts).
+
+- **apps.ts**
+ Entry points and configuration for each distributive.
+
+## Code Style
+
+### JavaScript/TypeScript
+
+- Use Boolean() constructor instead of !! operator for boolean casting.
+- Follow the ESLint rules from `eslint.config.mjs`.
+
+### TypeScript
+
+- Use `import type` for all type-only imports.
+- Define all type definitions and props in a `types.ts` file.
+
+### React
+
+- Each React component should reside in its own folder under the relevant feature/component directory.
+- The main component file must be named `[Component]/index.tsx`.
+- Do not import React at the top of files for JSX usage (React 18+).
+- Do not import the React namespace unless it is actually needed (e.g., for types or APIs not available via direct import).
+- Use implicit return for functional components when possible.
+- Destructure component props in the function signature.
+
+### Styles
+
+- Import styles as: `import * as s from "./styles"`.
+- Use a `styles.ts` file for styled-components definitions.
+- The top-level styled component should be named `Container`.
+- Do not use inline styles; use props with semantic names instead.
+- Do not use the `font-family` CSS rule for `SF Pro Text` (treat as the default OS font). Only specify `font-family` if a non-default font is required.
+- Use semantic color tokens from the theme (e.g., `theme.colors.v3.surface.primary`) instead of hardcoded color values or direct palette imports.
+- Use typography mixins from `typographies.ts` wherever Figma specifies a typography variable. Do not hardcode font-size, font-weight, or line-height if a corresponding typography token exists.
+- Avoid hardcoded colors, font sizes, and font weights if a semantic or design token exists.
+- All styled-components should use theme values via the `theme` prop for colors and typography, ensuring support for both dark and light themes.
+- Do not use inline types for styled-components. Always create and import interfaces for props used in styled-components from the component's `types.ts` file.
+- Do not use className prop without the need
+- Follow Stylelint rules for all CSS/styled-components code from `stylelint.config.js`.
+
+### Images
+
+- Use standard `
` tags for images, styled via styled-components if needed.
+
+### Storybook & Tests
+
+- Create a Storybook file named `[Component].stories.tsx` for stories.
+- Create a test file named `[Component].test.tsx` for tests.
diff --git a/.github/prompts/create-app.prompt.md b/.github/prompts/create-app.prompt.md
new file mode 100644
index 000000000..49d42b303
--- /dev/null
+++ b/.github/prompts/create-app.prompt.md
@@ -0,0 +1,8 @@
+---
+mode: "agent"
+tools: []
+---
+
+Add the infrastructure for a new app called "" for the "" platform.
+Take an existing app for the same platform as an example, but do not add any business logic yet—just the necessary boilerplate and wiring.
+Update all relevant files (such as apps.ts, containers, and routing) to register the new app and ensure it builds and runs like the other apps for this platform.
diff --git a/README.md b/README.md
index b429b796c..5cdf2e25f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Digma UI
+Digma UI is a React-based frontend for the Digma continuous feedback platform. The project is a monorepo for multiple React applications and provides the distributions for different platforms: Web and IDEs (JetBrains, Visual Studio and VS Code)
+
Install dependencies:
```shell
@@ -57,7 +59,7 @@ To set environment variables use .env file
## Jaeger UI
-The Digma UI distributive includes a [Digma fork of Jaeger UI](https://github.com/digma-ai/jaeger-ui). You can find the linked version in the [./dependencies.json](./dependencies.json) file.
+The Digma UI distribution includes a [Digma fork of Jaeger UI](https://github.com/digma-ai/jaeger-ui). You can find the linked version in the [./dependencies.json](./dependencies.json) file.
To use a custom build of Jaeger UI during development set `JAEGER_UI_PATH` environment variable.
diff --git a/scripts/get-jaeger-ui.mts b/scripts/get-jaeger-ui.mts
index 6b5055710..581a0eeb6 100644
--- a/scripts/get-jaeger-ui.mts
+++ b/scripts/get-jaeger-ui.mts
@@ -91,13 +91,13 @@ if (process.env.JAEGER_UI_PATH) {
if (!fs.existsSync(customJaegerUIPath)) {
// eslint-disable-next-line no-console
console.error(
- `Jaeger UI distributive has not been found at ${customJaegerUIPath}`
+ `Jaeger UI distribution has not been found at ${customJaegerUIPath}`
);
process.exit(1);
}
// eslint-disable-next-line no-console
- console.log(`Using Jaeger UI distributive from ${customJaegerUIPath}`);
+ console.log(`Using Jaeger UI distribution from ${customJaegerUIPath}`);
fs.copySync(customJaegerUIPath, extractPath);
diff --git a/src/api/index.ts b/src/api/index.ts
index b65b88710..b1604a26e 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -65,8 +65,6 @@ export const initializeDigmaMessageListener = (
break;
}
- window.addEventListener("message", handleDigmaMessage);
-
return () => {
switch (platform) {
case "Visual Studio":
diff --git a/src/components/Admin/index.tsx b/src/components/Admin/index.tsx
index 952ef6be8..946c24faf 100644
--- a/src/components/Admin/index.tsx
+++ b/src/components/Admin/index.tsx
@@ -32,7 +32,7 @@ export const Admin = () => {
FeatureFlag.IsUserIdEnabled
);
- // Clear issues report state when user changes
+ // Clear state when user changes
useEffect(() => {
if (isUserIdEnabled && userProfile) {
if (currentUser?.uid !== userProfile?.uid) {
diff --git a/src/components/Main/index.tsx b/src/components/Main/index.tsx
index e032a44b1..65fb9efd1 100644
--- a/src/components/Main/index.tsx
+++ b/src/components/Main/index.tsx
@@ -41,7 +41,7 @@ const getURLToNavigateOnCodeLensClick = (scope: Scope): string | undefined => {
}
const codeLens = scope.context.payload.codeLens;
- if (!codeLens.scopeCodeObjectId.startsWith("span:")) {
+ if (!codeLens.scopeCodeObjectId?.startsWith("span:")) {
return;
}
diff --git a/src/components/common/App/index.tsx b/src/components/common/App/index.tsx
index 235f4c610..93bdf6bca 100644
--- a/src/components/common/App/index.tsx
+++ b/src/components/common/App/index.tsx
@@ -332,7 +332,9 @@ export const App = ({ theme, children, id }: AppProps) => {
};
scope = newScope;
- setGlobalErrorsSearch(newScope.context.payload.codeLens.codeMethod);
+ if (newScope.method?.methodId) {
+ setGlobalErrorsSearch(newScope.method?.methodId);
+ }
}
setScope(scope);
diff --git a/src/components/common/App/types.ts b/src/components/common/App/types.ts
index a1582b211..8c15ac810 100644
--- a/src/components/common/App/types.ts
+++ b/src/components/common/App/types.ts
@@ -57,8 +57,14 @@ export interface ScopeSpan {
role: ScopeSpanRole | null;
}
+export interface MethodScope {
+ methodId: string;
+ displayName: string | null;
+}
+
export interface Scope {
span: ScopeSpan | null;
+ method?: MethodScope;
code: {
relatedCodeDetailsList: CodeDetails[];
codeDetailsList: CodeDetails[];
@@ -77,7 +83,7 @@ export interface Scope {
export interface CodeLens {
id: string;
codeMethod: string;
- scopeCodeObjectId: string;
+ scopeCodeObjectId?: string;
lensTitle: string;
importance: number;
}
diff --git a/src/components/common/IssuesReport/Header/styles.ts b/src/components/common/IssuesReport/Header/styles.ts
index 421a73219..f1aa0d334 100644
--- a/src/components/common/IssuesReport/Header/styles.ts
+++ b/src/components/common/IssuesReport/Header/styles.ts
@@ -54,7 +54,7 @@ export const Filters = styled(Row)`
const StyledToggle = styled(Toggle)`
align-items: center;
- background-color: transparent;
+ background: transparent;
border-radius: 8px;
border-color: ${({ theme }) => theme.colors.v3.stroke.primaryLight};
`;
diff --git a/src/components/common/JiraTicket/ActionableTextField/styles.ts b/src/components/common/JiraTicket/ActionableTextField/styles.ts
index 8609aef53..dfddea8dd 100644
--- a/src/components/common/JiraTicket/ActionableTextField/styles.ts
+++ b/src/components/common/JiraTicket/ActionableTextField/styles.ts
@@ -15,7 +15,7 @@ export const TextFieldContainer = styled.div`
export const RelativeTextField = styled(TextField)`
position: relative;
- background-color: transparent;
+ background: transparent;
border: 1px solid ${({ theme }) => theme.colors.field.border};
& > input {
diff --git a/src/components/common/NewPopover/index.tsx b/src/components/common/NewPopover/index.tsx
index 924f9e790..e738ff2f2 100644
--- a/src/components/common/NewPopover/index.tsx
+++ b/src/components/common/NewPopover/index.tsx
@@ -99,6 +99,7 @@ export const NewPopover = ({
setMinWidth(rects.reference.width);
setMaxWidth(rects.reference.width);
} else {
+ // TODO: Check if needed
const safeAvailableWidth = Math.max(availableWidth, 0);
const viewportWidth = window.innerWidth;
const anchorLeft = rects.reference.x;
diff --git a/src/logging/Logger.ts b/src/logging/Logger.ts
index cac412b9e..eafc37d68 100644
--- a/src/logging/Logger.ts
+++ b/src/logging/Logger.ts
@@ -20,13 +20,17 @@ export class Logger {
return format(new Date(), "HH:mm:ss");
}
- private getLogLevelTag(): string {
- return LogLevel[this.minLogLevel];
+ private getLogLevelTag(level: LogLevel): string {
+ return LogLevel[level];
}
- private getFormattedMessage(tags: string[], message: unknown): string {
+ private getFormattedMessage(
+ level: LogLevel,
+ tags: string[],
+ message: unknown
+ ): string {
if (this.showLogLevel) {
- tags.unshift(this.getLogLevelTag());
+ tags.unshift(this.getLogLevelTag(level));
}
if (this.showTimeStamp) {
@@ -48,7 +52,7 @@ export class Logger {
message?: unknown,
...optionalParams: unknown[]
): void {
- const formattedMessage = this.getFormattedMessage(tags, message);
+ const formattedMessage = this.getFormattedMessage(level, tags, message);
if (this.minLogLevel > level) {
return;