import type React from 'react'; import type {EmptyStateProps} from '../components/EmptyState'; import type {YDBDefinitionListItem} from '../components/YDBDefinitionList/YDBDefinitionList'; import type { CommonIssueCategory, GetHealthcheckViewTitles, GetHealthcheckViewsOrder, } from '../containers/Tenant/Healthcheck/shared'; import type { HealthcheckAssistantActionProps, HealthcheckAssistantTarget, } from '../containers/Tenant/Healthcheck/types'; import type {ClusterInfo} from '../store/reducers/cluster/cluster'; import type {PreparedStorageNode} from '../store/reducers/storage/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 {TUserToken} from '../types/api/whoami'; import type {GetLogsLink} from '../utils/logs'; import type {GetMonitoringClusterLink, GetMonitoringLink} from '../utils/monitoring'; export type IllustrationComponent = React.ComponentType>; export type CreateGraphLayoutWorker = () => Worker; export type IllustrationName = | 'InternalError' | 'AccessDenied' | 'Unauthenticated' | 'NoSearchResults' | 'SuccessOperation'; export interface UIFactory { onCreateDB?: HandleCreateDB; onEditDB?: HandleEditDB; onDeleteDB?: HandleDeleteDB; getAdditionalDatabaseInfoItems?: GetAdditionalDatabaseInfoItems; onAddCluster?: HandleAddCluster; onEditCluster?: HandleEditCluster; onDeleteCluster?: HandleDeleteCluster; homePageTitle?: string; getLogsLink?: GetLogsLink; getMonitoringLink?: GetMonitoringLink; getMonitoringClusterLink?: GetMonitoringClusterLink; getDatabaseLinks?: GetDatabaseLinks; getClusterLinks?: GetClusterLinks; renderBackups?: RenderBackups; renderEvents?: RenderEvents; renderMonitoring?: RenderMonitoring; renderNodeTooltipActions?: RenderNodeTooltipActions; renderChatPanel?: RenderChatPanel; clusterOrDatabaseAccessError?: Partial; /** Defaults to true. Undefined preserves the current value when configuring the UI. */ enableMultiTabQueryEditor?: boolean; /** Creates a fresh computation-graph layout worker for each layout run. */ createGraphLayoutWorker?: CreateGraphLayoutWorker; healthcheck: { issueCategories: ReadonlyArray; isIssueTypeOfCategory: (type: string, category: H) => boolean; getHealthckechViewTitles: GetHealthcheckViewTitles; getHealthcheckViewsOrder: GetHealthcheckViewsOrder; renderAssistantAction?: RenderHealthcheckAssistantAction; /** * Renders after the drawer header and before Healthcheck content. * Stays mounted while the drawer is open, independent of loading, error or issue state. */ renderDrawerExtension?: (props: HealthcheckDrawerExtensionProps) => React.ReactNode; }; hasAccess: HasAccess; hideGrantAccess?: boolean; hasDeveloperUi?: boolean; useDatabaseId?: boolean; emMetaAvailable?: boolean; useMetaProxy?: boolean; useClusterDomain?: boolean; clustersDomain?: string; settingsBackend?: { /** * Settings service endpoint (base URL) for `/meta/*` settings contract. */ getEndpoint: () => string | undefined; /** * User identifier to scope settings in the remote store (Yandex users). */ getUserId: () => string | undefined; }; yaMetricaConfig?: { yaMetricaMap: Record; goals: UiMetricaGoals; getMetricaName: (goalKey: UiMetricaGoal) => T; }; databasesEnvironmentsConfig?: DatabasesEnvironmentsConfig; getReportProblemUrl?: GetReportProblemUrl; isDetailedStorageViewAvailable?: IsDetailedStorageViewAvailable; /** Maximum number of disks in a storage group. */ maxVDisksInStorageGroup?: number; illustrations?: Partial>; hideNewFeaturesNotifications?: { navigationV2?: boolean; }; /** * First URL path segment for Developer UI routes. * Must be a single path segment without leading/trailing slashes, for example `devui`. * Do not pass `/devui/` or nested paths like `devui/node`. */ developerUiFirstPathSegment?: string; /** * Documentation configuration. * When omitted, documentation links are not rendered. */ docs?: DocsConfig; } /** * Documentation configuration. * Holds the base path for the documentation and paths to specific articles. */ export interface DocsConfig { /** Base path (URL) for the documentation. */ basePath: string; /** Path to the article about the auto partitioning max partitions count setting. */ autoPartitioningMaxPartitionsCount?: string; /** Path to the distributed storage channel glossary entry. */ distributedStorageChannel?: string; } export type HandleCreateDB = (params: { clusterName: string; domainRoot?: string; }) => Promise; export type HandleEditDB = (params: { clusterName: string; databaseData: PreparedTenant; }) => Promise; export type HandleDeleteDB = (params: { clusterName: string; databaseData: PreparedTenant; }) => Promise; export type GetAdditionalDatabaseInfoItems = (params: { databaseData: PreparedTenant; }) => YDBDefinitionListItem[]; export type HandleAddCluster = () => Promise; export type HandleEditCluster = (params: {clusterData: MetaBaseClusterInfo}) => Promise; export type HandleDeleteCluster = (params: {clusterData: MetaBaseClusterInfo}) => Promise; export type GetDatabaseLinks = (params: { clusterInfo: ClusterInfo; dbName?: string; dbType?: ETenantType; }) => DatabaseLink[]; export type GetClusterLinks = (params: {clusterInfo: ClusterInfo}) => ClusterLink[]; /** * Determines whether the Access tab should be shown. * Receives the user's permission flags so the visibility can depend on user rights. * `userPermissions` is `undefined` while the whoami request is still loading or unavailable. */ export type HasAccess = (params: { userPermissions?: Pick< TUserToken, 'IsAdministrationAllowed' | 'IsDatabaseAllowed' | 'IsMonitoringAllowed' | 'IsViewerAllowed' >; }) => boolean; export type IsDetailedStorageViewAvailable = (params: {clusterInfo: ClusterInfo}) => boolean; export type RenderBackups = (props: { database: string; scrollContainerRef: React.RefObject; }) => React.ReactNode; export type RenderEvents = (props: { scrollContainerRef: React.RefObject; }) => React.ReactNode; export type RenderMonitoring = (props: { database: string; databaseFullPath?: string; }) => React.ReactNode; export type RenderNodeTooltipActions = (props: {data?: PreparedStorageNode}) => React.ReactNode; export type RenderChatPanel = () => React.ReactNode; export interface HealthcheckDrawerExtensionProps { target?: HealthcheckAssistantTarget; } export type RenderHealthcheckAssistantAction = ( props: HealthcheckAssistantActionProps, ) => React.ReactNode; export interface UiMetricaGoals { /** Creation attempt after form validation. Params: objectType (row_table, column_table, topic). */ createObject?: string; /** Successful creation response. Params: objectType. */ createObjectSuccess?: string; /** Failed creation. Params: objectType, errorType (ydb, http, network, timeout, cancelled, unknown), httpStatus (HTTP errors only). */ createObjectError?: string; runQuery?: string; explainAnalyzeQuery?: string; stopQuery?: string; openManagePartitioning?: string; applyManagePartitioning?: string; openCompactionDialog?: string; startCompaction?: string; createQueryTab?: string; closeQueryTab?: string; duplicateQueryTab?: string; renameQueryTab?: string; saveQueryFromTab?: string; } export type UiMetricaGoal = keyof UiMetricaGoals; /** * Configuration for managing database environments in multi-cluster mode. * Affects environments that are shown on Databases tab on HomePage */ export interface DatabasesEnvironmentsConfig { /** The environment to select by default when no environment is specified */ getDefaultEnvironment?: () => string | undefined; /** * Environments can work in two modes: * * 1. **Filtered backend list**: If `getEnvironments` is not provided, the list of environments * is fetched from the backend and filtered by `getSupportedEnvironments`. Only environments * that exist in both the backend response and `getSupportedEnvironments` will be shown. * * 2. **Determined list**: If `getEnvironments` is provided, it returns the list of * available environments, ignoring the backend response. * Backend response with `getSupportedEnvironments` is used as fallback if function returns nothing */ getSupportedEnvironments: () => string[] | undefined; getEnvironments?: () => string[] | undefined; /** Custom display title for each environment (falls back to environment name) */ getEnvironmentTitle?: (env: string) => string | undefined; /** If provided, clicking an environment tab will redirect to that domain instead of changing the environment in the current context */ getEnvironmentDomain?: (env: string) => string | undefined; } export type GetReportProblemUrl = (params: { errorTitle?: string; requestUrl?: string; traceId?: string; }) => string | undefined;