Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [SIG-526]: UI Integrations V0 #4595

Merged
merged 41 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
21cff8e
feat: integrations v0 base setup routes and components
vikrantgupta25 Feb 26, 2024
4f5ff38
chore: typecheck fix
vikrantgupta25 Feb 26, 2024
4e63d52
feat: integrations landing page changes
vikrantgupta25 Feb 27, 2024
effca48
feat: initial header setup
vikrantgupta25 Feb 27, 2024
115f58f
feat: integrations list page setup
vikrantgupta25 Feb 27, 2024
56d2a53
feat: integrations details content root setup
vikrantgupta25 Feb 27, 2024
f197a75
feat: integration detail content setup
vikrantgupta25 Feb 27, 2024
1d7a9bf
feat: added overview tab
vikrantgupta25 Feb 27, 2024
60beb33
feat: added data tab
vikrantgupta25 Feb 27, 2024
d34a904
feat: handle configuration tab
vikrantgupta25 Feb 27, 2024
3aedf62
feat: add min height for the container
vikrantgupta25 Feb 27, 2024
56bd860
feat: generate apis and hooks for usage
vikrantgupta25 Feb 27, 2024
eb4d37d
feat: added remove integration modal
vikrantgupta25 Feb 27, 2024
1fa0397
feat: added remove integration modal
vikrantgupta25 Feb 27, 2024
799fea0
feat: added remove integration modal
vikrantgupta25 Feb 27, 2024
a8e5650
feat: added test connection bars
vikrantgupta25 Feb 28, 2024
20f8b80
chore: add bottom margins
vikrantgupta25 Feb 28, 2024
97d5119
feat: added test connection modal
vikrantgupta25 Feb 28, 2024
0622963
feat: add all types of test connection
vikrantgupta25 Feb 28, 2024
885211d
feat: add all types of test connection
vikrantgupta25 Feb 28, 2024
3127b6c
fix: address review comments
vikrantgupta25 Feb 28, 2024
c87a675
fix: address review comments
vikrantgupta25 Feb 28, 2024
a4bc8e4
feat: added get all integrations API and search bar implemnetation
vikrantgupta25 Mar 4, 2024
ff92857
feat: navigate to overview section in case of row click and configure…
vikrantgupta25 Mar 4, 2024
47b472b
feat: integrate get integration details api
vikrantgupta25 Mar 4, 2024
1f9cddd
feat: handle integration details page gracefully
vikrantgupta25 Mar 4, 2024
b8ce0eb
feat: integrate uninstall API and the connection states
vikrantgupta25 Mar 4, 2024
9777d9f
feat: add install integration API call
vikrantgupta25 Mar 4, 2024
b100a8c
feat: added api error handling
vikrantgupta25 Mar 4, 2024
359d343
feat: handle error states for list and details api
vikrantgupta25 Mar 4, 2024
8f521d6
feat: handle the logs and metrics columns
vikrantgupta25 Mar 4, 2024
c6b3756
feat: add TODOs for pending tasks
vikrantgupta25 Mar 4, 2024
d65f87b
feat: comment from side nav
vikrantgupta25 Mar 4, 2024
e53aa69
feat: added support for custom tags in react markdown
vikrantgupta25 Mar 4, 2024
29efaab
chore: revert the temporary change for merge
vikrantgupta25 Mar 5, 2024
fa37f33
feat: integrate the status api calls and polling logic
vikrantgupta25 Mar 5, 2024
5fe4253
chore: add markdown components and correct the polling issue
vikrantgupta25 Mar 6, 2024
87e723a
chore: handle light mode
vikrantgupta25 Mar 6, 2024
c124ab1
chore: remove integrations from sideNav
vikrantgupta25 Mar 6, 2024
2595337
fix: address review comments
vikrantgupta25 Mar 6, 2024
aa207e5
fix: address review comments
vikrantgupta25 Mar 6, 2024
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
5 changes: 3 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"react-virtuoso": "4.0.3",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"rehype-raw": "7.0.0",
"stream": "^0.0.2",
"style-loader": "1.3.0",
"styled-components": "^5.3.11",
Expand Down Expand Up @@ -203,6 +204,7 @@
"jest-styled-components": "^7.0.8",
"lint-staged": "^12.5.0",
"msw": "1.3.2",
"npm-run-all": "latest",
"portfinder-sync": "^0.0.2",
"prettier": "2.2.1",
"raw-loader": "4.0.2",
Expand All @@ -216,8 +218,7 @@
"ts-node": "^10.2.1",
"typescript-plugin-css-modules": "5.0.1",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2",
"npm-run-all": "latest"
"webpack-cli": "^4.9.2"
},
"lint-staged": {
"*.(js|jsx|ts|tsx)": [
Expand Down
1 change: 1 addition & 0 deletions frontend/public/Icons/redis-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion frontend/public/locales/en/titles.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@
"LOGS_SAVE_VIEWS": "SigNoz | Logs Saved Views",
"TRACES_SAVE_VIEWS": "SigNoz | Traces Saved Views",
"DEFAULT": "Open source Observability Platform | SigNoz",
"SHORTCUTS": "SigNoz | Shortcuts"
"SHORTCUTS": "SigNoz | Shortcuts",
"INTEGRATIONS_INSTALLED": "SigNoz | Integrations"
}
15 changes: 15 additions & 0 deletions frontend/src/AppRoutes/pageComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,18 @@ export const WorkspaceBlocked = Loadable(
export const ShortcutsPage = Loadable(
() => import(/* webpackChunkName: "ShortcutsPage" */ 'pages/Shortcuts'),
);

export const InstalledIntegrations = Loadable(
() =>
import(
/* webpackChunkName: "InstalledIntegrations" */ 'pages/IntegrationsModulePage'
),
);

export const IntegrationsMarketPlace = Loadable(
// eslint-disable-next-line sonarjs/no-identical-functions
() =>
import(
/* webpackChunkName: "IntegrationsMarketPlace" */ 'pages/IntegrationsModulePage'
),
);
22 changes: 19 additions & 3 deletions frontend/src/AppRoutes/routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import ROUTES from 'constants/routes';
import Shortcuts from 'pages/Shortcuts/Shortcuts';
import WorkspaceBlocked from 'pages/WorkspaceLocked';
import { RouteProps } from 'react-router-dom';

import {
Expand All @@ -16,6 +14,8 @@ import {
EditRulesPage,
ErrorDetails,
IngestionSettings,
InstalledIntegrations,
IntegrationsMarketPlace,
LicensePage,
ListAllALertsPage,
LiveLogs,
Expand All @@ -35,6 +35,7 @@ import {
ServiceMetricsPage,
ServicesTablePage,
SettingsPage,
ShortcutsPage,
SignupPage,
SomethingWentWrong,
StatusPage,
Expand All @@ -45,6 +46,7 @@ import {
TracesSaveViews,
UnAuthorized,
UsageExplorerPage,
WorkspaceBlocked,
} from './pageComponents';

const routes: AppRoutes[] = [
Expand Down Expand Up @@ -331,10 +333,24 @@ const routes: AppRoutes[] = [
{
path: ROUTES.SHORTCUTS,
exact: true,
component: Shortcuts,
component: ShortcutsPage,
isPrivate: true,
key: 'SHORTCUTS',
},
{
path: ROUTES.INTEGRATIONS_INSTALLED,
exact: true,
component: InstalledIntegrations,
isPrivate: true,
key: 'INTEGRATIONS_INSTALLED',
},
{
path: ROUTES.INTEGRATIONS_MARKETPLACE,
exact: true,
component: IntegrationsMarketPlace,
isPrivate: true,
key: 'INTEGRATIONS_MARKETPLACE',
},
];

export const SUPPORT_ROUTE: AppRoutes = {
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/api/Integrations/getAllIntegrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import { AllIntegrationsProps } from 'types/api/integrations/types';

export const getAllIntegrations = (): Promise<
AxiosResponse<AllIntegrationsProps>
> => axios.get(`/integrations`);
11 changes: 11 additions & 0 deletions frontend/src/api/Integrations/getIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import {
GetIntegrationPayloadProps,
GetIntegrationProps,
} from 'types/api/integrations/types';

export const getIntegration = (
props: GetIntegrationPayloadProps,
): Promise<AxiosResponse<GetIntegrationProps>> =>
axios.get(`/integrations/${props.integrationId}`);
11 changes: 11 additions & 0 deletions frontend/src/api/Integrations/getIntegrationStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import {
GetIntegrationPayloadProps,
GetIntegrationStatusProps,
} from 'types/api/integrations/types';

export const getIntegrationStatus = (
props: GetIntegrationPayloadProps,
): Promise<AxiosResponse<GetIntegrationStatusProps>> =>
axios.get(`/integrations/${props.integrationId}/connection_status`);
31 changes: 31 additions & 0 deletions frontend/src/api/Integrations/installIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
InstalledIntegrationsSuccessResponse,
InstallIntegrationKeyProps,
} from 'types/api/integrations/types';

const installIntegration = async (
props: InstallIntegrationKeyProps,
): Promise<
SuccessResponse<InstalledIntegrationsSuccessResponse> | ErrorResponse
> => {
try {
const response = await axios.post('/integrations/install', {
...props,
});

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

export default installIntegration;
31 changes: 31 additions & 0 deletions frontend/src/api/Integrations/uninstallIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
UninstallIntegrationProps,
UninstallIntegrationSuccessResponse,
} from 'types/api/integrations/types';

const unInstallIntegration = async (
props: UninstallIntegrationProps,
): Promise<
SuccessResponse<UninstallIntegrationSuccessResponse> | ErrorResponse
> => {
try {
const response = await axios.post('/integrations/uninstall', {
...props,
});

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

export default unInstallIntegration;
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable @typescript-eslint/explicit-function-return-type */

import ReactMarkdown from 'react-markdown';
import { CodeProps } from 'react-markdown/lib/ast-to-react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import rehypeRaw from 'rehype-raw';

import CodeCopyBtn from './CodeCopyBtn/CodeCopyBtn';

Expand Down Expand Up @@ -74,6 +76,10 @@ const interpolateMarkdown = (
return interpolatedContent;
};

function CustomTag({ color }: { color: string }): JSX.Element {
return <h1 style={{ color }}>This is custom element</h1>;
}

function MarkdownRenderer({
markdownContent,
variables,
Expand All @@ -85,12 +91,14 @@ function MarkdownRenderer({

return (
<ReactMarkdown
rehypePlugins={[rehypeRaw as any]}
components={{
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
a: Link,
pre: Pre,
code: Code,
customtag: CustomTag,
}}
>
{interpolatedMarkdown}
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const ROUTES = {
TRACES_SAVE_VIEWS: '/traces/saved-views',
WORKSPACE_LOCKED: '/workspace-locked',
SHORTCUTS: '/shortcuts',
INTEGRATIONS_BASE: '/integrations',
INTEGRATIONS_INSTALLED: '/integrations/installed',
INTEGRATIONS_MARKETPLACE: '/integrations/marketplace',
} as const;

export default ROUTES;
7 changes: 7 additions & 0 deletions frontend/src/container/SideNav/menuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ScrollText,
Settings,
Slack,
// Unplug,
vikrantgupta25 marked this conversation as resolved.
Show resolved Hide resolved
UserPlus,
} from 'lucide-react';

Expand Down Expand Up @@ -89,6 +90,11 @@ const menuItems: SidebarItem[] = [
label: 'Alerts',
icon: <BellDot size={16} />,
},
// {
vikrantgupta25 marked this conversation as resolved.
Show resolved Hide resolved
// key: ROUTES.INTEGRATIONS_INSTALLED,
// label: 'Integrations',
// icon: <Unplug size={16} />,
// },
{
key: ROUTES.ALL_ERROR,
label: 'Exceptions',
Expand Down Expand Up @@ -121,6 +127,7 @@ export const NEW_ROUTES_MENU_ITEM_KEY_MAP: Record<string, string> = {
[ROUTES.TRACES_EXPLORER]: ROUTES.TRACE,
[ROUTES.TRACE_EXPLORER]: ROUTES.TRACE,
[ROUTES.LOGS_BASE]: ROUTES.LOGS_EXPLORER,
[ROUTES.INTEGRATIONS_BASE]: ROUTES.INTEGRATIONS_INSTALLED,
};

export default menuItems;
3 changes: 3 additions & 0 deletions frontend/src/container/TopNav/DateTimeSelectionV2/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ export const routesToSkip = [
ROUTES.TRACES_EXPLORER,
ROUTES.TRACES_SAVE_VIEWS,
ROUTES.SHORTCUTS,
ROUTES.INTEGRATIONS_BASE,
ROUTES.INTEGRATIONS_INSTALLED,
ROUTES.INTEGRATIONS_MARKETPLACE,
];

export const routesToDisable = [ROUTES.LOGS_EXPLORER, ROUTES.LIVE_LOGS];
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/hooks/Integrations/useGetAllIntegrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getAllIntegrations } from 'api/Integrations/getAllIntegrations';
import { AxiosError, AxiosResponse } from 'axios';
import { useQuery, UseQueryResult } from 'react-query';
import { AllIntegrationsProps } from 'types/api/integrations/types';

export const useGetAllIntegrations = (): UseQueryResult<
AxiosResponse<AllIntegrationsProps>,
AxiosError
> =>
useQuery<AxiosResponse<AllIntegrationsProps>, AxiosError>({
queryKey: ['Integrations'],
queryFn: () => getAllIntegrations(),
});
18 changes: 18 additions & 0 deletions frontend/src/hooks/Integrations/useGetIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getIntegration } from 'api/Integrations/getIntegration';
import { AxiosError, AxiosResponse } from 'axios';
import { useQuery, UseQueryResult } from 'react-query';
import {
GetIntegrationPayloadProps,
GetIntegrationProps,
} from 'types/api/integrations/types';

export const useGetIntegration = ({
integrationId,
}: GetIntegrationPayloadProps): UseQueryResult<
AxiosResponse<GetIntegrationProps>,
AxiosError
> =>
useQuery<AxiosResponse<GetIntegrationProps>, AxiosError>({
queryKey: ['Integration', integrationId],
queryFn: () => getIntegration({ integrationId }),
});
20 changes: 20 additions & 0 deletions frontend/src/hooks/Integrations/useGetIntegrationStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { getIntegrationStatus } from 'api/Integrations/getIntegrationStatus';
import { AxiosError, AxiosResponse } from 'axios';
import { useQuery, UseQueryResult } from 'react-query';
import {
GetIntegrationPayloadProps,
GetIntegrationStatusProps,
} from 'types/api/integrations/types';

export const useGetIntegrationStatus = ({
integrationId,
enabled,
}: GetIntegrationPayloadProps): UseQueryResult<
AxiosResponse<GetIntegrationStatusProps>,
AxiosError
> =>
useQuery<AxiosResponse<GetIntegrationStatusProps>, AxiosError>({
queryKey: ['Integration', integrationId, Date.now()],
queryFn: () => getIntegrationStatus({ integrationId }),
enabled,
});
37 changes: 37 additions & 0 deletions frontend/src/pages/Integrations/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import './Integrations.styles.scss';

import { Color } from '@signozhq/design-tokens';
import { Input, Typography } from 'antd';
import { Search } from 'lucide-react';
import { Dispatch, SetStateAction } from 'react';

interface HeaderProps {
searchTerm: string;
setSearchTerm: Dispatch<SetStateAction<string>>;
}

function Header(props: HeaderProps): JSX.Element {
const { searchTerm, setSearchTerm } = props;

const handleSearch = (e: React.ChangeEvent<HTMLInputElement>): void => {
setSearchTerm(e.target.value);
};
return (
<div className="integrations-header">
<Typography.Title className="title">Integrations</Typography.Title>
<Typography.Text className="subtitle">
Manage Integrations for this workspace
</Typography.Text>

<Input
placeholder="Search for an integration..."
prefix={<Search size={12} color={Color.BG_VANILLA_400} />}
value={searchTerm}
onChange={handleSearch}
className="integrations-search-input"
/>
</div>
);
}

export default Header;
Loading
Loading