diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c12656e72..710666bfb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,7 @@ jobs: contents: read actions: write runs-on: ubuntu-latest + outputs: artifact-name: ${{ steps.get-artifact-name.outputs.artifact_name }} steps: @@ -29,7 +30,7 @@ jobs: - run: npm ci - env: - GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }} # TODO: fix + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: npm run build:prod:${{ inputs.platform }} - name: Get artifact name diff --git a/.github/workflows/release-asset.yml b/.github/workflows/release-asset.yml index bce69ec27..181388bd1 100644 --- a/.github/workflows/release-asset.yml +++ b/.github/workflows/release-asset.yml @@ -27,4 +27,4 @@ jobs: with: files: dist/${{ inputs.artifact-name }}.zip env: - GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 8cb147a4d..f866748c7 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -28,7 +28,7 @@ jobs: - name: Commit, push changes and create PR env: - GH_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }} + GITHUB_TOKEN: ${{ secrets.CONTENTS_WRITE_PAT }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" diff --git a/package-lock.json b/package-lock.json index 3357a4fed..958c4f407 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "digma-ui", - "version": "16.6.4", + "version": "16.7.0-alpha.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "digma-ui", - "version": "16.6.4", + "version": "16.7.0-alpha.3", "license": "MIT", "dependencies": { "@codemirror/lang-json": "^6.0.2", @@ -91,6 +91,7 @@ "husky": "^9.1.7", "jest": "^30.0.5", "jest-environment-jsdom": "^30.0.5", + "jiti": "^2.5.1", "knip": "^5.62.0", "lint-staged": "^16.1.2", "postcss-styled-syntax": "^0.7.1", @@ -14695,9 +14696,9 @@ } }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", "dev": true, "license": "MIT", "bin": { @@ -18729,7 +18730,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/reselect": { "version": "5.1.1", diff --git a/package.json b/package.json index a5bb6cf80..d8058e87e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "digma-ui", - "version": "16.6.4", + "version": "16.7.0-alpha.3", "description": "Digma UI", "scripts": { "lint:eslint": "eslint --cache .", @@ -96,6 +96,7 @@ "husky": "^9.1.7", "jest": "^30.0.5", "jest-environment-jsdom": "^30.0.5", + "jiti": "^2.5.1", "knip": "^5.62.0", "lint-staged": "^16.1.2", "postcss-styled-syntax": "^0.7.1", diff --git a/src/components/Admin/common/RepositorySidebarOverlay/RepositorySidebar/Header/index.tsx b/src/components/Admin/common/RepositorySidebarOverlay/RepositorySidebar/Header/index.tsx index dc52187e6..1e26c5b80 100644 --- a/src/components/Admin/common/RepositorySidebarOverlay/RepositorySidebar/Header/index.tsx +++ b/src/components/Admin/common/RepositorySidebarOverlay/RepositorySidebar/Header/index.tsx @@ -100,7 +100,7 @@ export const Header = ({ onGoHome={handleGoHome} /> { + const url = `${ideUriScheme}://digma.digma/chat/context/add/file/incident/${incidentId}`; + window.open(url, "_blank", "noopener noreferrer"); +}; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/index.tsx b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/index.tsx new file mode 100644 index 000000000..44fd94e72 --- /dev/null +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/index.tsx @@ -0,0 +1,79 @@ +import { useEffect, useState, type ComponentType } from "react"; +import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent"; +import { uniqueBy } from "../../../../../utils/uniqueBy"; +import { VSCodeLogoIcon } from "../../../../common/icons/100px/VSCodeLogoIcon"; +import { CursorLogoIcon } from "../../../../common/icons/24px/CursorLogoIcon"; +import type { IconProps } from "../../../../common/icons/types"; +import { NewIconButton } from "../../../../common/v3/NewIconButton"; +import { Tooltip } from "../../../../common/v3/Tooltip"; +import { trackingEvents } from "../../../tracking"; +import { addChatContextIncidentFile } from "./addChatContextFile"; +import { scanRunningVSCodeIdeProjects } from "./scanRunningVSCodeIdeProjects"; +import * as s from "./styles"; +import type { IdeToolbarProps, VSCodeExtensionInfo } from "./types"; + +const IDE_ICONS: Record> = { + cursor: CursorLogoIcon, + vscode: VSCodeLogoIcon +}; + +export const IdeToolbar = ({ incidentId }: IdeToolbarProps) => { + const [ides, setIdes] = useState(); + + const handleIdeButtonClick = (ide: string) => { + sendUserActionTrackingEvent(trackingEvents.INCIDENT_IDE_BUTTON_CLICKED, { + ide + }); + addChatContextIncidentFile(ide, incidentId); + }; + + useEffect(() => { + const scan = async () => { + try { + const results = await scanRunningVSCodeIdeProjects(); + const ides = uniqueBy( + results.map((x) => x.response), + "ideUriScheme" + ); + setIdes(ides); + } catch { + setIdes([]); + } + }; + + void scan(); + }, []); + + if (!ides || ides.length === 0) { + return null; + } + + return ( + + {ides + ?.map((ide) => { + const IdeIcon = IDE_ICONS[ide.ideUriScheme]; + + if (!IdeIcon) { + return null; + } + + return ( + + } + onClick={() => handleIdeButtonClick(ide.ideUriScheme)} + /> + + ); + }) + .filter(Boolean)} + + ); +}; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/scanRunningVSCodeIdeProjects.ts b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/scanRunningVSCodeIdeProjects.ts new file mode 100644 index 000000000..6f8181d63 --- /dev/null +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/scanRunningVSCodeIdeProjects.ts @@ -0,0 +1,42 @@ +import axios from "axios"; +import { isString } from "../../../../../typeGuards/isString"; +import type { VSCodeExtensionInfo, VSCodeIdeScanningResult } from "./types"; + +const START_PORT_TO_SCAN = 33100; +const END_PORT_TO_SCAN = 33119; + +const ABOUT_PATH = "api/digma/about"; + +export const scanRunningVSCodeIdeProjects = + async (): Promise => { + const instances = Array.from( + { length: END_PORT_TO_SCAN - START_PORT_TO_SCAN + 1 }, + (_, i) => START_PORT_TO_SCAN + i + ).map((port) => ({ + port, + url: `http://localhost:${port}/${ABOUT_PATH}` + })); + + const responses = await Promise.allSettled( + instances.map((x) => + axios + .get(x.url) + .then((response) => ({ port: x.port, response: response.data })) + .catch((error) => ({ + port: x.port, + response: axios.isAxiosError(error) + ? `${error.message}` + : "Unknown error" + })) + ) + ); + + const successfulResponses = responses.filter( + (x) => x.status === "fulfilled" && !isString(x.value.response) + ) as unknown as PromiseFulfilledResult<{ + port: number; + response: VSCodeExtensionInfo; + }>[]; + + return successfulResponses.map((x) => x.value); + }; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/styles.ts b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/styles.ts new file mode 100644 index 000000000..8d20cee7c --- /dev/null +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/styles.ts @@ -0,0 +1,7 @@ +import styled from "styled-components"; + +export const Container = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/types.ts b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/types.ts new file mode 100644 index 000000000..0732cfd72 --- /dev/null +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/IdeToolbar/types.ts @@ -0,0 +1,15 @@ +export interface IdeToolbarProps { + incidentId: string; +} + +export interface VSCodeExtensionInfo { + ideName: string; + ideUriScheme: string; + ideVersion: string; + workspace: string; +} + +export type VSCodeIdeScanningResult = { + port: number; + response: VSCodeExtensionInfo; +}[]; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/index.tsx b/src/components/Agentic/IncidentDetails/IncidentMetaData/index.tsx index d6bff71da..5d0ff676b 100644 --- a/src/components/Agentic/IncidentDetails/IncidentMetaData/index.tsx +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/index.tsx @@ -12,10 +12,12 @@ import { import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; import { intersperse } from "../../../../utils/intersperse"; import { InfoCircleIcon } from "../../../common/icons/InfoCircleIcon"; +import { NewButton } from "../../../common/v3/NewButton"; import { NewIconButton } from "../../../common/v3/NewIconButton"; import { Tooltip } from "../../../common/v3/Tooltip"; import { trackingEvents } from "../../tracking"; import { Divider } from "./Divider"; +import { IdeToolbar } from "./IdeToolbar"; import * as s from "./styles"; const DATE_FORMAT = "dd MMM, yyyy HH:mm"; @@ -194,24 +196,27 @@ export const IncidentMetaData = () => { return ( {attributes} - {data.status === "active" && ( - - )} - {data.status === "pending" && ( - - )} - {["error", "closed", "canceled"].includes(data.status) && ( - - )} + + {incidentId && } + {data.status === "active" && ( + + )} + {data.status === "pending" && ( + + )} + {["error", "closed", "canceled"].includes(data.status) && ( + + )} + ); }; diff --git a/src/components/Agentic/IncidentDetails/IncidentMetaData/styles.ts b/src/components/Agentic/IncidentDetails/IncidentMetaData/styles.ts index 40a4ef50a..253c40c18 100644 --- a/src/components/Agentic/IncidentDetails/IncidentMetaData/styles.ts +++ b/src/components/Agentic/IncidentDetails/IncidentMetaData/styles.ts @@ -1,6 +1,5 @@ import styled from "styled-components"; import { subheading1RegularTypography } from "../../../common/App/typographies"; -import { NewButton } from "../../../common/v3/NewButton"; export const Container = styled.div` display: flex; @@ -14,6 +13,7 @@ export const AttributesList = styled.div` display: flex; flex-wrap: wrap; align-items: center; + margin-right: auto; `; export const DividerContainer = styled.div` @@ -22,13 +22,6 @@ export const DividerContainer = styled.div` display: flex; `; -export const CloseIncidentButton = styled(NewButton)` - flex-shrink: 0; - margin-top: 12px; - margin-left: auto; - margin-right: 16px; -`; - export const Attribute = styled.div` ${subheading1RegularTypography} display: flex; @@ -77,3 +70,12 @@ export const HiddenServicesCountTag = styled(Tag)` border: 1px solid ${({ theme }) => theme.colors.v3.stroke.primary}; color: ${({ theme }) => theme.colors.v3.text.secondary}; `; + +export const Toolbar = styled.div` + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + margin-top: 12px; + margin-right: 16px; +`; diff --git a/src/components/Agentic/IncidentDirectives/index.tsx b/src/components/Agentic/IncidentDirectives/index.tsx index 4de34421e..550ca8e55 100644 --- a/src/components/Agentic/IncidentDirectives/index.tsx +++ b/src/components/Agentic/IncidentDirectives/index.tsx @@ -279,7 +279,11 @@ export const IncidentDirectives = () => { }, cell: (info) => { const value = info.getValue(); - return {value}; + return ( + + {value} + + ); }, enableSorting: true, sortingFn: (rowA, rowB) => { @@ -313,7 +317,14 @@ export const IncidentDirectives = () => { }, cell: (info) => { const value = info.getValue(); - return {value.join(", ")}; + const valueString = value.join(", "); + return ( + + + {valueString} + + + ); }, enableSorting: true, sortingFn: (rowA, rowB) => { diff --git a/src/components/Agentic/IncidentDirectives/styles.ts b/src/components/Agentic/IncidentDirectives/styles.ts index d6387aa2d..879d71877 100644 --- a/src/components/Agentic/IncidentDirectives/styles.ts +++ b/src/components/Agentic/IncidentDirectives/styles.ts @@ -139,12 +139,26 @@ export const RecordNumber = styled.span` color: ${({ theme }) => theme.colors.v3.text.tertiary}; `; -export const Condition = styled.span` +export const TruncatedTableCellContent = styled.span` + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + &:hover { + padding: 26px 0 16px; + overflow-y: auto; + white-space: normal; + box-sizing: border-box; + height: 100%; + } +`; + +export const Condition = styled(TruncatedTableCellContent)` ${subheading1BoldTypography} color: ${({ theme }) => theme.colors.v3.text.primary}; `; -export const Directive = styled.span` +export const Directive = styled(TruncatedTableCellContent)` ${subheading1RegularTypography} color: ${({ theme }) => theme.colors.v3.text.secondary}; `; diff --git a/src/components/Agentic/tracking.ts b/src/components/Agentic/tracking.ts index 684262cf4..b1f046c6c 100644 --- a/src/components/Agentic/tracking.ts +++ b/src/components/Agentic/tracking.ts @@ -16,6 +16,7 @@ export const trackingEvents = addPrefix( INCIDENT_CANCEL_BUTTON_CLICKED: "incident cancel button clicked", INCIDENT_CLOSE_BUTTON_CLICKED: "incident close button clicked", INCIDENT_DELETE_BUTTON_CLICKED: "incident delete button clicked", + INCIDENT_IDE_BUTTON_CLICKED: "incident IDE button clicked", FLOW_CHART_NODE_CLICKED: "flow chart node clicked", FLOW_CHART_NODE_KEBAB_MENU_CLICKED: "flow chart node kebab menu clicked", FLOW_CHART_NODE_KEBAB_MENU_ITEM_CLICKED: diff --git a/src/components/IdeLauncher/common/IdeProjectSelect/constants.ts b/src/components/IdeLauncher/common/IdeProjectSelect/constants.ts new file mode 100644 index 000000000..68fd5326b --- /dev/null +++ b/src/components/IdeLauncher/common/IdeProjectSelect/constants.ts @@ -0,0 +1 @@ +export const SELECT_VALUE_DELIMITER = ":"; diff --git a/src/components/IdeLauncher/common/IdeProjectSelect/index.tsx b/src/components/IdeLauncher/common/IdeProjectSelect/index.tsx new file mode 100644 index 000000000..3f65096cc --- /dev/null +++ b/src/components/IdeLauncher/common/IdeProjectSelect/index.tsx @@ -0,0 +1,20 @@ +import { Select } from "../../../common/v3/Select"; +import * as s from "./styles"; +import type { IdeProjectSelectProps } from "./types"; + +export const IdeProjectSelect = ({ + items, + onChange +}: IdeProjectSelectProps) => { + const selectedItem = items?.find((item) => item.selected); + + return ( + + { - void handleSelectChange(value); - }} - /> - + void handleSelectChange(value)} + /> ); } diff --git a/src/components/IdeLauncher/scanRunningIdeProjects.ts b/src/components/IdeLauncher/scanRunningIdeProjects.ts deleted file mode 100644 index d65a1bba0..000000000 --- a/src/components/IdeLauncher/scanRunningIdeProjects.ts +++ /dev/null @@ -1,40 +0,0 @@ -import axios from "axios"; -import { isString } from "../../typeGuards/isString"; -import type { IdeScanningResult, PluginInfo } from "./types"; - -const DEFAULT_PORT = 63342; -const PORT_RANGE = 20; -const ABOUT_PATH = "api/digma/about"; - -export const scanRunningIdeProjects = async (): Promise => { - const instances = Array.from( - { length: PORT_RANGE }, - (_, i) => DEFAULT_PORT + i - ).map((port) => ({ - port, - url: `http://localhost:${port}/${ABOUT_PATH}` - })); - - const responses = await Promise.allSettled( - instances.map((x) => - axios - .get(x.url) - .then((response) => ({ port: x.port, response: response.data })) - .catch((error) => ({ - port: x.port, - response: axios.isAxiosError(error) - ? `${error.message}` - : "Unknown error" - })) - ) - ); - - const successfulResponses = responses.filter( - (x) => x.status === "fulfilled" && !isString(x.value) - ) as unknown as PromiseFulfilledResult<{ - port: number; - response: PluginInfo; - }>[]; - - return successfulResponses.map((x) => x.value); -}; diff --git a/src/components/IdeLauncher/scanRunningIntellijIdeProjects.ts b/src/components/IdeLauncher/scanRunningIntellijIdeProjects.ts new file mode 100644 index 000000000..afe3e0852 --- /dev/null +++ b/src/components/IdeLauncher/scanRunningIntellijIdeProjects.ts @@ -0,0 +1,41 @@ +import axios from "axios"; +import { isString } from "../../typeGuards/isString"; +import type { IntellijIdeScanningResult, IntellijPluginInfo } from "./types"; + +const DEFAULT_PORT = 63342; +const PORT_RANGE = 20; +const ABOUT_PATH = "api/digma/about"; + +export const scanRunningIntellijIdeProjects = + async (): Promise => { + const instances = Array.from( + { length: PORT_RANGE }, + (_, i) => DEFAULT_PORT + i + ).map((port) => ({ + port, + url: `http://localhost:${port}/${ABOUT_PATH}` + })); + + const responses = await Promise.allSettled( + instances.map((x) => + axios + .get(x.url) + .then((response) => ({ port: x.port, response: response.data })) + .catch((error) => ({ + port: x.port, + response: axios.isAxiosError(error) + ? `${error.message}` + : "Unknown error" + })) + ) + ); + + const successfulResponses = responses.filter( + (x) => x.status === "fulfilled" && !isString(x.value) + ) as unknown as PromiseFulfilledResult<{ + port: number; + response: IntellijPluginInfo; + }>[]; + + return successfulResponses.map((x) => x.value); + }; diff --git a/src/components/IdeLauncher/showIdeProject.ts b/src/components/IdeLauncher/showIdeProject.ts index 09b37f93a..9dc4911b2 100644 --- a/src/components/IdeLauncher/showIdeProject.ts +++ b/src/components/IdeLauncher/showIdeProject.ts @@ -1,11 +1,11 @@ import axios, { isAxiosError } from "axios"; -import type { ShowIdeProjectResult } from "./types"; +import type { ShowIntellijIdeProjectResult } from "./types"; export const showIdeProject = async ( port: number, project: string, params: Record -): Promise => { +): Promise => { const pluginParams = Object.entries(params).reduce( (acc, [key, value]) => { const KEY_PREFIX = "plugin."; diff --git a/src/components/IdeLauncher/styles.ts b/src/components/IdeLauncher/styles.ts index a62dc50d0..d0009cd58 100644 --- a/src/components/IdeLauncher/styles.ts +++ b/src/components/IdeLauncher/styles.ts @@ -8,7 +8,3 @@ export const ButtonsContainer = styled.div` display: flex; gap: 16px; `; - -export const SelectContainer = styled.div` - width: 560px; -`; diff --git a/src/components/IdeLauncher/types.ts b/src/components/IdeLauncher/types.ts index 081acf0c3..2d361071f 100644 --- a/src/components/IdeLauncher/types.ts +++ b/src/components/IdeLauncher/types.ts @@ -1,4 +1,4 @@ -export interface PluginInfo { +export interface IntellijPluginInfo { name: string; productName: string; edition: string; @@ -11,9 +11,12 @@ export interface PluginInfo { openProjects: string[]; } -export interface ShowIdeProjectResult { +export interface ShowIntellijIdeProjectResult { result: "success" | "failure"; error?: { message: string }; } -export type IdeScanningResult = { port: number; response: PluginInfo }[]; +export type IntellijIdeScanningResult = { + port: number; + response: IntellijPluginInfo; +}[]; diff --git a/src/components/common/icons/100px/VSCodeLogoIcon.tsx b/src/components/common/icons/100px/VSCodeLogoIcon.tsx new file mode 100644 index 000000000..40f9c7365 --- /dev/null +++ b/src/components/common/icons/100px/VSCodeLogoIcon.tsx @@ -0,0 +1,123 @@ +import React from "react"; +import { useIconProps } from "../hooks"; +import type { IconProps } from "../types"; + +const VSCodeLogoIconComponent = (props: IconProps) => { + const { size } = useIconProps(props); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export const VSCodeLogoIcon = React.memo(VSCodeLogoIconComponent); diff --git a/src/components/common/icons/24px/CursorLogoIcon.tsx b/src/components/common/icons/24px/CursorLogoIcon.tsx new file mode 100644 index 000000000..524c5f071 --- /dev/null +++ b/src/components/common/icons/24px/CursorLogoIcon.tsx @@ -0,0 +1,70 @@ +import React from "react"; +import { useIconProps } from "../hooks"; +import type { ThemeableIconProps } from "../types"; + +const CursorLogoIconComponent = (props: ThemeableIconProps) => { + const { size } = useIconProps(props); + + const color = props.themeKind === "light" ? "#000" : "#fff"; + + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export const CursorLogoIcon = React.memo(CursorLogoIconComponent); diff --git a/src/redux/posthogMiddleware.ts b/src/redux/posthogMiddleware.ts index b4d6604fa..37f13e1c1 100644 --- a/src/redux/posthogMiddleware.ts +++ b/src/redux/posthogMiddleware.ts @@ -47,9 +47,7 @@ export const posthogMiddleware = } if ( - rejectedAction.payload.error?.includes( - "Error: TypeError: Failed to fetch" - ) + rejectedAction.payload.error?.includes("TypeError: Failed to fetch") ) { // Ignore network errors return next(action); diff --git a/webpack.dev.ts b/webpack.dev.ts index 3fc78ce6d..bd89608dc 100644 --- a/webpack.dev.ts +++ b/webpack.dev.ts @@ -44,26 +44,22 @@ const apiProxyClient = axios.create({ }); const login = async (credentials: Credentials) => { - const response = await apiProxyClient.post<{ - accessToken: string; - refreshToken: string; - expiration: string; - userId: string; - }>("/authentication/login", credentials); + const response = await apiProxyClient.post( + "/authentication/login", + credentials + ); return response.data; }; const refreshToken = async (session: Session) => { - const response = await apiProxyClient.post<{ - accessToken: string; - refreshToken: string; - expiration: string; - userId: string; - }>("/authentication/refresh-token", { - accessToken: session.accessToken, - refreshToken: session.refreshToken - }); + const response = await apiProxyClient.post( + "/authentication/refresh-token", + { + accessToken: session.accessToken, + refreshToken: session.refreshToken + } + ); return response.data; };