Skip to content

feat: allow defining a list of links for cluster and database overviews #2359

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

Merged
merged 1 commit into from
Jun 10, 2025
Merged
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
17 changes: 0 additions & 17 deletions src/components/LogsButton/LogsButton.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/components/MonitoringButton/MonitoringButton.tsx

This file was deleted.

18 changes: 6 additions & 12 deletions src/components/TenantNameWrapper/TenantNameWrapper.tsx
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import {DefinitionList, Flex} from '@gravity-ui/uikit';
import {getTenantPath} from '../../containers/Tenant/TenantPages';
import type {PreparedTenant} from '../../store/reducers/tenants/types';
import type {AdditionalTenantsProps} from '../../types/additionalProps';
import {getDatabaseLinks} from '../../utils/additionalProps';
import {useIsUserAllowedToMakeChanges} from '../../utils/hooks/useIsUserAllowedToMakeChanges';
import {EntityStatus} from '../EntityStatus/EntityStatus';
import {LinkWithIcon} from '../LinkWithIcon/LinkWithIcon';
@@ -37,23 +38,16 @@ export function TenantNameWrapper({tenant, additionalTenantsProps}: TenantNameWr
const backend = getTenantBackend(tenant, additionalTenantsProps);
const isExternalLink = Boolean(backend);

const monitoringLink = additionalTenantsProps?.getMonitoringLink?.(tenant.Name, tenant.Type);
const logsLink = additionalTenantsProps?.getLogsLink?.(tenant.Name);
const links = getDatabaseLinks(additionalTenantsProps, tenant?.Name, tenant?.Type);

const infoPopoverContent =
(monitoringLink || logsLink) && isUserAllowedToMakeChanges ? (
links.length > 0 && isUserAllowedToMakeChanges ? (
<DefinitionList responsive>
<DefinitionList.Item name={i18n('field_links')}>
<Flex gap={2} wrap="wrap">
{monitoringLink && (
<LinkWithIcon
title={i18n('field_monitoring-link')}
url={monitoringLink}
/>
)}
{logsLink && (
<LinkWithIcon title={i18n('field_logs-link')} url={logsLink} />
)}
{links.map(({title, url}) => (
<LinkWithIcon key={title} title={title} url={url} />
))}
</Flex>
</DefinitionList.Item>
</DefinitionList>
3 changes: 3 additions & 0 deletions src/containers/AppWithClusters/AppWithClusters.tsx
Original file line number Diff line number Diff line change
@@ -28,6 +28,8 @@ export function AppWithClusters({store, history, userSettings, children}: AppWit
getLogsLink={uiFactory.getLogsLink}
getMonitoringLink={uiFactory.getMonitoringLink}
getMonitoringClusterLink={uiFactory.getMonitoringClusterLink}
getDatabaseLinks={uiFactory.getDatabaseLinks}
getClusterLinks={uiFactory.getClusterLinks}
/>
);
}}
@@ -39,6 +41,7 @@ export function AppWithClusters({store, history, userSettings, children}: AppWit
component={component}
getLogsLink={uiFactory.getLogsLink}
getMonitoringLink={uiFactory.getMonitoringLink}
getDatabaseLinks={uiFactory.getDatabaseLinks}
/>
);
}}
118 changes: 25 additions & 93 deletions src/containers/AppWithClusters/ExtendedCluster/ExtendedCluster.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import {ClipboardButton} from '@gravity-ui/uikit';
import {isNil} from 'lodash';

import {useClusterBaseInfo} from '../../../store/reducers/cluster/cluster';
import type {AdditionalClusterProps, AdditionalTenantsProps} from '../../../types/additionalProps';
import type {ETenantType} from '../../../types/api/tenant';
import type {AdditionalClusterProps} from '../../../types/additionalProps';
import type {GetClusterLinks, GetDatabaseLinks} from '../../../uiFactory/types';
import {cn} from '../../../utils/cn';
import {USE_CLUSTER_BALANCER_AS_BACKEND_KEY} from '../../../utils/constants';
import {useSetting} from '../../../utils/hooks';
import {useAdditionalNodesProps} from '../../../utils/hooks/useAdditionalNodesProps';
import type {GetLogsLink} from '../../../utils/logs';
import type {GetMonitoringClusterLink, GetMonitoringLink} from '../../../utils/monitoring';
import {getCleanBalancerValue, prepareBackendFromBalancer} from '../../../utils/parseBalancer';
import {getBackendFromBalancerAndNodeId} from '../../../utils/prepareBackend';
import {getCleanBalancerValue} from '../../../utils/parseBalancer';
import type {Cluster} from '../../Cluster/Cluster';
import {useAdditionalTenantsProps} from '../utils/useAdditionalTenantsProps';

import './ExtendedCluster.scss';

@@ -33,133 +30,68 @@ const getAdditionalBalancerInfo = (balancer: string) => {
};

interface GetAdditionalClusterProps {
clusterName: string | undefined;
monitoring: string | undefined;
balancer: string | undefined;
getMonitoringClusterLink?: GetMonitoringClusterLink;
getClusterLinks?: GetClusterLinks;
}

const getAdditionalClusterProps = ({
clusterName,
monitoring,
balancer,
const useAdditionalClusterProps = ({
getMonitoringClusterLink,
getClusterLinks,
}: GetAdditionalClusterProps) => {
const additionalClusterProps: AdditionalClusterProps = {};
const clusterInfo = useClusterBaseInfo();
const {name: clusterName, balancer, monitoring} = clusterInfo;

const additionalClusterProps: AdditionalClusterProps = {};
additionalClusterProps.links = [];
if (monitoring && getMonitoringClusterLink) {
const clusterLink = getMonitoringClusterLink(monitoring, clusterName);

if (clusterLink) {
additionalClusterProps.links = [{title: 'Monitoring', url: clusterLink}];
additionalClusterProps.links.push({title: 'Monitoring', url: clusterLink});
}
}

if (getClusterLinks) {
const clusterLinks = getClusterLinks({clusterInfo});
additionalClusterProps.links.push(...clusterLinks);
}

if (balancer) {
additionalClusterProps.info = [getAdditionalBalancerInfo(balancer)];
}

return additionalClusterProps;
};

interface GetAdditionalTenantsProps {
clusterName: string | undefined;
monitoring: string | undefined;
balancer: string | undefined;
logging: string | undefined;
useClusterBalancerAsBackend: boolean | undefined;
getMonitoringLink?: GetMonitoringLink;
getLogsLink?: GetLogsLink;
}

const getAdditionalTenantsProps = ({
clusterName,
monitoring,
balancer,
logging,
useClusterBalancerAsBackend,
getMonitoringLink,
getLogsLink,
}: GetAdditionalTenantsProps) => {
const additionalTenantsProps: AdditionalTenantsProps = {};

additionalTenantsProps.prepareTenantBackend = (nodeId) => {
// Balancer value is used to create path, so it's necessary
if (!balancer) {
return undefined;
}

if (useClusterBalancerAsBackend) {
return prepareBackendFromBalancer(balancer);
}

if (isNil(nodeId)) {
return undefined;
}

return getBackendFromBalancerAndNodeId(nodeId, balancer) ?? undefined;
};

if (monitoring && getMonitoringLink) {
additionalTenantsProps.getMonitoringLink = (dbName?: string, dbType?: ETenantType) => {
if (dbName && dbType) {
return getMonitoringLink({monitoring, dbName, dbType, clusterName});
}

return null;
};
}

if (logging && getLogsLink) {
additionalTenantsProps.getLogsLink = (dbName?: string) => {
if (dbName) {
return getLogsLink({
dbName,
logging,
});
}

return null;
};
}

return additionalTenantsProps;
};

interface ExtendedClusterProps {
component: typeof Cluster;
getMonitoringLink?: GetMonitoringLink;
getMonitoringClusterLink?: GetMonitoringClusterLink;
getLogsLink?: GetLogsLink;
getDatabaseLinks?: GetDatabaseLinks;
getClusterLinks?: GetClusterLinks;
}
export function ExtendedCluster({
component: ClusterComponent,
getMonitoringLink,
getMonitoringClusterLink,
getLogsLink,
getDatabaseLinks,
getClusterLinks,
}: ExtendedClusterProps) {
const additionalNodesProps = useAdditionalNodesProps();
const {name, balancer, monitoring, logging} = useClusterBaseInfo();

const [useClusterBalancerAsBackend] = useSetting<boolean>(USE_CLUSTER_BALANCER_AS_BACKEND_KEY);

return (
<div className={b()}>
<ClusterComponent
additionalClusterProps={getAdditionalClusterProps({
clusterName: name,
monitoring,
balancer,
additionalClusterProps={useAdditionalClusterProps({
getMonitoringClusterLink,
getClusterLinks,
})}
additionalTenantsProps={getAdditionalTenantsProps({
clusterName: name,
monitoring,
balancer,
logging,
useClusterBalancerAsBackend,
additionalTenantsProps={useAdditionalTenantsProps({
getMonitoringLink,
getLogsLink,
getDatabaseLinks,
})}
additionalNodesProps={additionalNodesProps}
/>
Original file line number Diff line number Diff line change
@@ -1,47 +1,29 @@
import {useClusterBaseInfo} from '../../../store/reducers/cluster/cluster';
import type {ETenantType} from '../../../types/api/tenant';
import type {GetDatabaseLinks} from '../../../uiFactory/types';
import {useAdditionalNodesProps} from '../../../utils/hooks/useAdditionalNodesProps';
import type {GetLogsLink} from '../../../utils/logs';
import type {GetMonitoringLink} from '../../../utils/monitoring';
import type {Tenant} from '../../Tenant/Tenant';
import {useAdditionalTenantsProps} from '../utils/useAdditionalTenantsProps';

export interface ExtendedTenantProps {
component: typeof Tenant;
getMonitoringLink?: GetMonitoringLink;
getLogsLink?: GetLogsLink;
getDatabaseLinks?: GetDatabaseLinks;
}

export function ExtendedTenant({
component: TenantComponent,
getMonitoringLink,
getLogsLink,
getDatabaseLinks,
}: ExtendedTenantProps) {
const {monitoring, logging} = useClusterBaseInfo();
const additionalNodesProps = useAdditionalNodesProps();

const additionalTenantProps = {
getMonitoringLink: (dbName?: string, dbType?: ETenantType) => {
if (monitoring && dbName && dbType && getMonitoringLink) {
return getMonitoringLink({
monitoring,
dbName,
dbType,
});
}

return null;
},
getLogsLink: (dbName?: string) => {
if (logging && dbName && getLogsLink) {
return getLogsLink({
dbName,
logging,
});
}

return null;
},
};
const additionalTenantProps = useAdditionalTenantsProps({
getMonitoringLink,
getLogsLink,
getDatabaseLinks,
});

return (
<TenantComponent
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {isNil} from 'lodash';

import {useClusterBaseInfo} from '../../../store/reducers/cluster/cluster';
import type {AdditionalTenantsProps} from '../../../types/additionalProps';
import type {ETenantType} from '../../../types/api/tenant';
import type {GetDatabaseLinks} from '../../../uiFactory/types';
import {USE_CLUSTER_BALANCER_AS_BACKEND_KEY} from '../../../utils/constants';
import {useSetting} from '../../../utils/hooks';
import type {GetLogsLink} from '../../../utils/logs';
import type {GetMonitoringLink} from '../../../utils/monitoring';
import {prepareBackendFromBalancer} from '../../../utils/parseBalancer';
import {getBackendFromBalancerAndNodeId} from '../../../utils/prepareBackend';

interface GetAdditionalTenantsProps {
getMonitoringLink?: GetMonitoringLink;
getLogsLink?: GetLogsLink;
getDatabaseLinks?: GetDatabaseLinks;
}
export function useAdditionalTenantsProps({
getMonitoringLink,
getLogsLink,
getDatabaseLinks,
}: GetAdditionalTenantsProps) {
const clusterInfo = useClusterBaseInfo();
const [useClusterBalancerAsBackend] = useSetting<boolean>(USE_CLUSTER_BALANCER_AS_BACKEND_KEY);

const {balancer, monitoring, logging, name: clusterName} = clusterInfo;

const additionalTenantsProps: AdditionalTenantsProps = {};
additionalTenantsProps.prepareTenantBackend = (nodeId) => {
// Balancer value is used to create path, so it's necessary
if (!balancer) {
return undefined;
}

if (useClusterBalancerAsBackend) {
return prepareBackendFromBalancer(balancer);
}

if (isNil(nodeId)) {
return undefined;
}

return getBackendFromBalancerAndNodeId(nodeId, balancer) ?? undefined;
};

if (monitoring && getMonitoringLink) {
additionalTenantsProps.getMonitoringLink = (dbName?: string, dbType?: ETenantType) => {
if (dbName && dbType) {
return getMonitoringLink({monitoring, clusterName, dbName, dbType});
}

return null;
};
}

if (logging && getLogsLink) {
additionalTenantsProps.getLogsLink = (dbName?: string) => {
if (dbName) {
return getLogsLink({logging, dbName});
}

return null;
};
}

if (getDatabaseLinks) {
additionalTenantsProps.getLinks = (dbName?: string, dbType?: ETenantType) => {
if (dbName && dbType) {
return getDatabaseLinks({clusterInfo, dbName, dbType});
}
return [];
};
}

return additionalTenantsProps;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import {Flex} from '@gravity-ui/uikit';
import {Button, Flex, Icon} from '@gravity-ui/uikit';

import {EntityStatus} from '../../../../components/EntityStatus/EntityStatus';
import {LoaderWrapper} from '../../../../components/LoaderWrapper/LoaderWrapper';
import {LogsButton} from '../../../../components/LogsButton/LogsButton';
import {MonitoringButton} from '../../../../components/MonitoringButton/MonitoringButton';
import {overviewApi} from '../../../../store/reducers/overview/overview';
import {TENANT_METRICS_TABS_IDS} from '../../../../store/reducers/tenant/constants';
import {tenantApi} from '../../../../store/reducers/tenant/tenant';
import {calculateTenantMetrics} from '../../../../store/reducers/tenants/utils';
import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../../../types/additionalProps';
import {getDatabaseLinks} from '../../../../utils/additionalProps';
import {TENANT_DEFAULT_TITLE} from '../../../../utils/constants';
import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks';
import {useClusterNameFromQuery} from '../../../../utils/hooks/useDatabaseFromQuery';
@@ -141,8 +140,7 @@ export function TenantOverview({
}
};

const monitoringLink = additionalTenantProps?.getMonitoringLink?.(Name, Type);
const logsLink = additionalTenantProps?.getLogsLink?.(Name);
const links = getDatabaseLinks(additionalTenantProps, Name, Type);

return (
<LoaderWrapper loading={tenantLoading}>
@@ -152,8 +150,17 @@ export function TenantOverview({
<Flex alignItems="center" gap="1" className={b('top')}>
{renderName()}
<Flex gap="2">
{monitoringLink && <MonitoringButton href={monitoringLink} />}
{logsLink && <LogsButton href={logsLink} />}
{links.map(({title, url, icon}) => (
<Button
key={title}
href={url}
target="_blank"
size="xs"
title={title}
>
<Icon data={icon} />
</Button>
))}
</Flex>
</Flex>
<Flex direction="column" gap={3}>
2 changes: 2 additions & 0 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -33,3 +33,5 @@ export type {
export type {SettingProps, SettingsInfoFieldProps} from './containers/UserSettings/Setting';
export type {AsideNavigationProps} from './containers/AsideNavigation/AsideNavigation';
export type {GetMonitoringLink, GetMonitoringClusterLink} from './utils/monitoring';

export {configureUIFactory} from './uiFactory/uiFactory';
5 changes: 4 additions & 1 deletion src/services/parsers/parseMetaCluster.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type {TTraceView} from '../../types/api/trace';
import {traceViewSchema} from '../../types/api/trace';

export function parseTraceFields({traceView}: {traceView?: string}) {
export function parseTraceFields({traceView}: {traceView?: string}): {
traceView?: TTraceView;
} {
try {
return {
traceView: traceView ? traceViewSchema.parse(JSON.parse(traceView)) : undefined,
2 changes: 2 additions & 0 deletions src/store/reducers/cluster/cluster.ts
Original file line number Diff line number Diff line change
@@ -158,6 +158,8 @@ export function useClusterBaseInfo() {
};
}

export type ClusterInfo = ReturnType<typeof useClusterBaseInfo> & Record<string, unknown>;

const createClusterInfoSelector = createSelector(
(clusterName?: string) => clusterName,
(clusterName) => clusterApi.endpoints.getClusterInfo.select(clusterName),
6 changes: 5 additions & 1 deletion src/store/reducers/tenant/tenant.ts
Original file line number Diff line number Diff line change
@@ -67,7 +67,11 @@ export const tenantApi = api.injectEndpoints({
} else {
tenantData = await window.api.viewer.getTenantInfo({path}, {signal});
}
return {data: tenantData.TenantInfo?.[0] ?? null};
const databases = tenantData.TenantInfo || [];
// previous meta versions do not support filtering databases by name
const data =
databases.find((tenant) => tenant.Name === path) ?? databases[0] ?? null;
return {data};
} catch (error) {
return {error};
}
9 changes: 9 additions & 0 deletions src/types/additionalProps.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type {IconData} from '@gravity-ui/uikit';

import type {TSystemStateInfo} from './api/nodes';
import type {ETenantType} from './api/tenant';
import type {InfoItem} from './components';
@@ -7,6 +9,12 @@ export interface ClusterLink {
url: string;
}

export interface DatabaseLink {
title: string;
url: string;
icon: IconData;
}

export interface AdditionalClusterProps {
info?: InfoItem[];
links?: ClusterLink[];
@@ -16,6 +24,7 @@ export interface AdditionalTenantsProps {
prepareTenantBackend?: (nodeId?: string | number) => string | undefined;
getMonitoringLink?: (name?: string, type?: ETenantType) => string | null;
getLogsLink?: (name?: string) => string | null;
getLinks?: (name?: string, type?: ETenantType) => DatabaseLink[];
}

export type NodeAddress = Pick<TSystemStateInfo, 'Host' | 'Endpoints' | 'NodeId'>;
14 changes: 14 additions & 0 deletions src/uiFactory/types.ts
Original file line number Diff line number Diff line change
@@ -3,9 +3,12 @@ import type {
GetHealthcheckViewTitles,
GetHealthcheckViewsOrder,
} from '../containers/Tenant/Healthcheck/shared';
import type {ClusterInfo} from '../store/reducers/cluster/cluster';
import type {IssuesTree} from '../store/reducers/healthcheckInfo/types';
import type {PreparedTenant} from '../store/reducers/tenants/types';
import type {ClusterLink, DatabaseLink} from '../types/additionalProps';
import type {MetaBaseClusterInfo} from '../types/api/meta';
import type {ETenantType} from '../types/api/tenant';
import type {GetLogsLink} from '../utils/logs';
import type {GetMonitoringClusterLink, GetMonitoringLink} from '../utils/monitoring';

@@ -22,6 +25,9 @@ export interface UIFactory {
getMonitoringLink?: GetMonitoringLink;
getMonitoringClusterLink?: GetMonitoringClusterLink;

getDatabaseLinks?: GetDatabaseLinks;
getClusterLinks?: GetClusterLinks;

healthcheck: {
getHealthckechViewTitles: GetHealthcheckViewTitles<CommonIssueType>;
getHealthcheckViewsOrder: GetHealthcheckViewsOrder<CommonIssueType>;
@@ -48,3 +54,11 @@ export type HandleAddCluster = () => Promise<boolean>;
export type HandleEditCluster = (params: {clusterData: MetaBaseClusterInfo}) => Promise<boolean>;

export type HandleDeleteCluster = (params: {clusterData: MetaBaseClusterInfo}) => Promise<boolean>;

export type GetDatabaseLinks = (params: {
clusterInfo: ClusterInfo;
dbName?: string;
dbType?: ETenantType;
}) => DatabaseLink[];

export type GetClusterLinks = (params: {clusterInfo: ClusterInfo}) => ClusterLink[];
43 changes: 42 additions & 1 deletion src/utils/additionalProps.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,51 @@
import {FileText} from '@gravity-ui/icons';

import i18n from '../components/TenantNameWrapper/i18n';
import {backend} from '../store';
import type {AdditionalNodesProps} from '../types/additionalProps';
import type {
AdditionalNodesProps,
AdditionalTenantsProps,
DatabaseLink,
} from '../types/additionalProps';
import type {ETenantType} from '../types/api/tenant';

import {getBackendFromBalancerAndNodeId} from './prepareBackend';

import monitoringIcon from '../assets/icons/monitoring.svg';

export const getAdditionalNodesProps = (balancer = backend): AdditionalNodesProps => {
return {
getNodeRef: (node) => getBackendFromBalancerAndNodeId(node?.NodeId, balancer ?? ''),
};
};

export function getDatabaseLinks(
additionalProps?: AdditionalTenantsProps,
name?: string,
type?: ETenantType,
) {
if (!additionalProps) {
return [];
}

const links: DatabaseLink[] = [];
if (additionalProps.getMonitoringLink) {
const link = additionalProps.getMonitoringLink(name, type);
if (link) {
links.push({title: i18n('field_monitoring-link'), url: link, icon: monitoringIcon});
}
}

if (additionalProps.getLogsLink) {
const link = additionalProps.getLogsLink(name);
if (link) {
links.push({title: i18n('field_logs-link'), url: link, icon: FileText});
}
}

if (additionalProps.getLinks) {
links.push(...additionalProps.getLinks(name, type));
}

return links;
}

Unchanged files with check annotations Beta

className?: string;
}
type IllustrationStore = Record<string, Record<string, () => Promise<{default: any}>>>;

Check warning on line 12 in src/components/Illustration/Illustration.tsx

GitHub Actions / Verify Files

Unexpected any. Specify a different type
const store: IllustrationStore = {
light: {
resizeObserver.observe(containerRef.current);
return () => {
if (containerRef.current) {

Check warning on line 50 in src/components/Drawer/DrawerContext.tsx

GitHub Actions / Verify Files

The ref value 'containerRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'containerRef.current' to a variable inside the effect, and use that variable in the cleanup function
resizeObserver.disconnect();
}
};
};
const handleClickInsideDrawer = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
(event.nativeEvent as DrawerEvent)._capturedInsideDrawer = true;

Check warning on line 105 in src/components/Drawer/Drawer.tsx

GitHub Actions / Verify Files

Assignment to property of function parameter 'event'
};
const itemContainer = itemContainerRef?.current;
type RegistryEntity<T = any> = T;

Check warning on line 1 in src/components/ComponentsProvider/registry.ts

GitHub Actions / Verify Files

Unexpected any. Specify a different type
type RegistryEntities = Record<string, RegistryEntity>;
export class Registry<Entities extends RegistryEntities = {}> {
type?: Entities;
private entities: any = {};

Check warning on line 7 in src/components/ComponentsProvider/registry.ts

GitHub Actions / Verify Files

Unexpected any. Specify a different type
set<Id extends keyof Entities>(id: Id, entity: Entities[Id]) {
this.entities[id] = entity;
}
type ComponentType<T> =
T extends React.ComponentType<any>

Check warning on line 27 in src/components/ComponentsProvider/registry.ts

GitHub Actions / Verify Files

Unexpected any. Specify a different type
? React.ComponentType<React.ComponentPropsWithoutRef<T>>
: never;
});
if (env === 'production') {
config.output.path = path.resolve(__dirname, 'build/');

Check warning on line 35 in config-overrides.js

GitHub Actions / Verify Files

Assignment to property of function parameter 'config'
}
config.plugins.push(
new MonacoWebpackPlugin({
// By default jest does not transform anything in node_modules
// So this override excludes node_modules except @gravity-ui
// see https://github.com/timarney/react-app-rewired/issues/241
config.transformIgnorePatterns = ['node_modules/(?!(@gravity-ui|@mjackson)/)'];

Check warning on line 61 in config-overrides.js

GitHub Actions / Verify Files

Assignment to property of function parameter 'config'
// Add .github directory to roots
config.roots = ['<rootDir>/src', '<rootDir>/.github'];

Check warning on line 64 in config-overrides.js

GitHub Actions / Verify Files

Assignment to property of function parameter 'config'
// Update testMatch to include .github directory
config.testMatch = [

Check warning on line 67 in config-overrides.js

GitHub Actions / Verify Files

Assignment to property of function parameter 'config'
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}',
'<rootDir>/.github/**/*.{spec,test}.{js,jsx,ts,tsx}',