Skip to content

Commit

Permalink
Merge branch 'v3' into PMM-13569-portal-env-variable
Browse files Browse the repository at this point in the history
  • Loading branch information
matejkubinec committed Dec 20, 2024
2 parents 9c64ea4 + 266da08 commit 0cd9c6c
Show file tree
Hide file tree
Showing 27 changed files with 100 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import { FormApi, FormState } from 'final-form';
import React from 'react';
import { Form } from 'react-final-form';
Expand All @@ -13,6 +13,8 @@ import { trackingOptions, rdsTrackingOptions } from './FormParts.constants';
import { LabelsFormPart } from './Labels/Labels';
import { MainDetailsFormPart } from './MainDetails/MainDetails';

jest.mock('app/percona/inventory/Inventory.service');

const form: Partial<FormApi> = {
change: jest.fn(),
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
Expand All @@ -31,7 +33,7 @@ describe('MainDetailsFormPart ::', () => {
);

const fields = container.querySelectorAll('input');
expect(fields.length).toBe(8);
await waitFor(() => expect(fields.length).toBe(8));

expect(screen.getByTestId('address-text-input')).toBeDisabled();
expect(screen.getByTestId('serviceName-text-input')).not.toBeDisabled();
Expand All @@ -51,7 +53,7 @@ describe('MainDetailsFormPart ::', () => {
);

const fields = container.querySelectorAll('input');
expect(fields.length).toBe(8);
await waitFor(() => expect(fields.length).toBe(8));

expect(screen.getByTestId('address-text-input')).not.toBeDisabled();
expect(screen.getByTestId('serviceName-text-input')).not.toBeDisabled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import { Form } from 'react-final-form';
import { Provider } from 'react-redux';
Expand All @@ -7,8 +7,10 @@ import { configureStore } from 'app/store/configureStore';

import { MongoDBConnectionDetails } from './MongoDBConnectionDetails';

jest.mock('app/percona/inventory/Inventory.service');

describe('MongoDB connection details:: ', () => {
it('should have max query length attribute', () => {
it('should have max query length attribute', async () => {
render(
<Provider store={configureStore()}>
<Form onSubmit={jest.fn()} render={() => <MongoDBConnectionDetails remoteInstanceCredentials={{}} />} />
Expand All @@ -18,6 +20,6 @@ describe('MongoDB connection details:: ', () => {
const textInput = screen.getByTestId('maxQueryLength-text-input');
fireEvent.change(textInput, { target: { value: '1000' } });

expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000');
await waitFor(() => expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000'));
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import { Form } from 'react-final-form';
import { Provider } from 'react-redux';
Expand All @@ -7,8 +7,10 @@ import { configureStore } from 'app/store/configureStore';

import { MySQLConnectionDetails } from './MySQLConnectionDetails';

jest.mock('app/percona/inventory/Inventory.service');

describe('MySQL connection details:: ', () => {
it('should have max query length attribute', () => {
it('should have max query length attribute', async () => {
render(
<Provider store={configureStore()}>
<Form onSubmit={jest.fn()} render={() => <MySQLConnectionDetails remoteInstanceCredentials={{}} />} />
Expand All @@ -18,6 +20,6 @@ describe('MySQL connection details:: ', () => {
const textInput = screen.getByTestId('maxQueryLength-text-input');
fireEvent.change(textInput, { target: { value: '1000' } });

expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000');
await waitFor(() => expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000'));
});
});
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const PMM_SERVER_NODE_ID = 'pmm-server';
export const PMM_SERVER_NODE_AGENT_ID = 'pmm-server';
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ describe('Nodes Agents:: ', () => {
submitMock.mockClear();
});

it('should pick pmm-server node by default when available', async () => {
jest.spyOn(InventoryService, 'getNodes').mockReturnValue(Promise.resolve({ nodes: nodesMock }));

setup();

await waitFor(() => expect(fetchNodesActionActionSpy).toHaveBeenCalled());

await waitFor(() => expect(screen.getByTestId('node')).toHaveTextContent(nodesMock[0].node_id));
});

it('should not pick any agent when the selected node is not pmm-server', async () => {
jest
.spyOn(InventoryService, 'getNodes')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import React, { FC, useCallback, useEffect, useMemo } from 'react';
import { useField } from 'react-final-form';

import { useStyles2 } from '@grafana/ui';
import { Messages } from 'app/percona/add-instance/components/AddRemoteInstance/FormParts/FormParts.messages';
import { getStyles } from 'app/percona/add-instance/components/AddRemoteInstance/FormParts/FormParts.styles';
import { PMM_SERVER_NODE_AGENT_ID } from 'app/percona/add-instance/components/AddRemoteInstance/FormParts/NodesAgents/NodesAgents.constants';
import {
PMM_SERVER_NODE_AGENT_ID,
PMM_SERVER_NODE_ID,
} from 'app/percona/add-instance/components/AddRemoteInstance/FormParts/NodesAgents/NodesAgents.constants';
import { NodesAgentsProps } from 'app/percona/add-instance/components/AddRemoteInstance/FormParts/NodesAgents/NodesAgents.types';
import { GET_NODES_CANCEL_TOKEN } from 'app/percona/inventory/Inventory.constants';
import { AgentsOption, NodesOption } from 'app/percona/inventory/Inventory.types';
Expand All @@ -14,15 +18,18 @@ import { fetchNodesAction } from 'app/percona/shared/core/reducers/nodes/nodes';
import { getNodes } from 'app/percona/shared/core/selectors';
import { isApiCancelError } from 'app/percona/shared/helpers/api';
import { logger } from 'app/percona/shared/helpers/logger';
import { validators } from 'app/percona/shared/helpers/validatorsForm';
import { useAppDispatch } from 'app/store/store';
import { useSelector } from 'app/types';

export const NodesAgents: FC<NodesAgentsProps> = ({ form }) => {
const styles = useStyles2(getStyles);
const dispatch = useAppDispatch();
const [generateToken] = useCancelToken();
const [selectedNode, setSelectedNode] = useState<NodesOption>();
const { nodes } = useSelector(getNodes);
const {
input: { value: selectedNode },
} = useField('node');

const nodesOptions = useMemo<NodesOption[]>(() => nodesOptionsMapper(nodes), [nodes]);

Expand All @@ -49,7 +56,7 @@ export const NodesAgents: FC<NodesAgentsProps> = ({ form }) => {
};

const setNodeAndAgent = (value: NodesOption) => {
setSelectedNode(value);
form?.change('node', value);

let selectedAgent: AgentsOption | undefined;
if (value.agents && value.agents?.length > 1) {
Expand All @@ -68,6 +75,12 @@ export const NodesAgents: FC<NodesAgentsProps> = ({ form }) => {
useEffect(() => {
if (nodesOptions.length === 0) {
loadData();
} else if (!selectedNode) {
// preselect pmm-server node
const pmmServerNode = nodesOptions.find((node) => node.value === PMM_SERVER_NODE_ID);
if (pmmServerNode) {
setNodeAndAgent(pmmServerNode);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [nodesOptions]);
Expand All @@ -84,8 +97,8 @@ export const NodesAgents: FC<NodesAgentsProps> = ({ form }) => {
data-testid="nodes-selectbox"
onChange={(event) => setNodeAndAgent(event as NodesOption)}
className={styles.selectField}
value={selectedNode}
aria-label={Messages.form.labels.nodesAgents.nodes}
validators={[validators.required]}
/>
</div>
<div className={styles.selectFieldWrapper}>
Expand All @@ -99,6 +112,7 @@ export const NodesAgents: FC<NodesAgentsProps> = ({ form }) => {
onChange={(event) => changeAgentValue(event as AgentsOption)}
className={styles.selectField}
aria-label={Messages.form.labels.nodesAgents.agents}
validators={selectedNode ? [validators.required] : undefined}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import { Form } from 'react-final-form';
import { Provider } from 'react-redux';
Expand All @@ -7,8 +7,10 @@ import { configureStore } from 'app/store/configureStore';

import { PostgreSQLConnectionDetails } from './PostgreSQLConnectionDetails';

jest.mock('app/percona/inventory/Inventory.service');

describe('PostgreSQL connection details:: ', () => {
it('should have database attribute', () => {
it('should have database attribute', async () => {
render(
<Provider store={configureStore()}>
<Form onSubmit={jest.fn()} render={() => <PostgreSQLConnectionDetails remoteInstanceCredentials={{}} />} />
Expand All @@ -18,10 +20,10 @@ describe('PostgreSQL connection details:: ', () => {
const textInput = screen.getByTestId('database-text-input');
fireEvent.change(textInput, { target: { value: 'db1' } });

expect(screen.getByTestId('database-text-input')).toHaveValue('db1');
await waitFor(() => expect(screen.getByTestId('database-text-input')).toHaveValue('db1'));
});

it('should have max query length attribute', () => {
it('should have max query length attribute', async () => {
render(
<Provider store={configureStore()}>
<Form onSubmit={jest.fn()} render={() => <PostgreSQLConnectionDetails remoteInstanceCredentials={{}} />} />
Expand All @@ -31,6 +33,6 @@ describe('PostgreSQL connection details:: ', () => {
const textInput = screen.getByTestId('maxQueryLength-text-input');
fireEvent.change(textInput, { target: { value: '1000' } });

expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000');
await waitFor(() => expect(screen.getByTestId('maxQueryLength-text-input')).toHaveValue('1000'));
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export const DATA_INTERVAL = 5000;
export const LIST_ARTIFACTS_CANCEL_TOKEN = 'listArtifacts';
export const BACKUP_CANCEL_TOKEN = 'backup';
export const RESTORE_CANCEL_TOKEN = 'restore';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { BackupInventory } from './BackupInventory';

jest.mock('./BackupInventory.service');
jest.mock('app/percona/backup/components/StorageLocations/StorageLocations.service');
jest.mock('../../hooks/recurringCall.hook');
jest.mock('app/percona/shared/core/hooks/recurringCall.hook');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { DeleteModal } from 'app/percona/shared/components/Elements/DeleteModal'
import { FeatureLoader } from 'app/percona/shared/components/Elements/FeatureLoader';
import { ExtendedColumn, FilterFieldTypes, Table } from 'app/percona/shared/components/Elements/Table';
import { useCancelToken } from 'app/percona/shared/components/hooks/cancelToken.hook';
import { ApiVerboseError, Databases, DATABASE_LABELS } from 'app/percona/shared/core';
import { ApiVerboseError, Databases, DATABASE_LABELS, DATA_INTERVAL } from 'app/percona/shared/core';
import { useRecurringCall } from 'app/percona/shared/core/hooks/recurringCall.hook';
import { fetchStorageLocations } from 'app/percona/shared/core/reducers/backups/backupLocations';
import { getBackupLocations, getPerconaSettingFlag } from 'app/percona/shared/core/selectors';
import { apiErrorParser, isApiCancelError } from 'app/percona/shared/helpers/api';
Expand All @@ -24,12 +25,11 @@ import { useSelector } from 'app/types';
import { NEW_BACKUP_URL, RESTORES_URL } from '../../Backup.constants';
import { Messages } from '../../Backup.messages';
import { BackupModeMap, formatBackupMode } from '../../Backup.utils';
import { useRecurringCall } from '../../hooks/recurringCall.hook';
import { DetailedDate } from '../DetailedDate';
import { Status } from '../Status';
import { LocationType } from '../StorageLocations/StorageLocations.types';

import { DATA_INTERVAL, LIST_ARTIFACTS_CANCEL_TOKEN, RESTORE_CANCEL_TOKEN } from './BackupInventory.constants';
import { LIST_ARTIFACTS_CANCEL_TOKEN, RESTORE_CANCEL_TOKEN } from './BackupInventory.constants';
import { BackupInventoryService } from './BackupInventory.service';
import { getStyles } from './BackupInventory.styles';
import { BackupRow } from './BackupInventory.types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React, { FC, useCallback, useEffect, useState, useRef } from 'react';

import { ClipboardButton, useStyles } from '@grafana/ui';
import { useCancelToken } from 'app/percona/shared/components/hooks/cancelToken.hook';
import { useRecurringCall } from 'app/percona/shared/core/hooks/recurringCall.hook';
import { isApiCancelError } from 'app/percona/shared/helpers/api';
import { logger } from 'app/percona/shared/helpers/logger';

import { BackupLogChunk } from '../../Backup.types';
import { useRecurringCall } from '../../hooks/recurringCall.hook';

import { LIMIT, LOGS_CANCEL_TOKEN, STREAM_INTERVAL } from './ChunkedLogsViewer.constants';
import { Messages } from './ChunkedLogsViewer.messages';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FeatureLoader } from 'app/percona/shared/components/Elements/FeatureLoa
import { ExtendedColumn, FilterFieldTypes, Table } from 'app/percona/shared/components/Elements/Table';
import { useCancelToken } from 'app/percona/shared/components/hooks/cancelToken.hook';
import { Databases, DATABASE_LABELS } from 'app/percona/shared/core';
import { useRecurringCall } from 'app/percona/shared/core/hooks/recurringCall.hook';
import { fetchStorageLocations } from 'app/percona/shared/core/reducers/backups/backupLocations';
import { getBackupLocations, getPerconaSettingFlag } from 'app/percona/shared/core/selectors';
import { isApiCancelError } from 'app/percona/shared/helpers/api';
Expand All @@ -18,7 +19,6 @@ import { useSelector } from 'app/types';

import { Messages } from '../../Backup.messages';
import { formatLocationsToMap } from '../../Backup.utils';
import { useRecurringCall } from '../../hooks/recurringCall.hook';
import { DetailedDate } from '../DetailedDate';
import { Status } from '../Status';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const AlertRuleTemplateService = {
return api
.get<TemplatesListAPI, AlertRuleTemplateGetPayload>(BASE_URL, false, {
cancelToken: token,
params: { ...payload },
params: { ...payload, reload: true },
})
.then(
({ totals, templates = [] }): TemplatesList => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface AlertRuleTemplateGetPayload {
page_size: number;
index: number;
};
reload?: boolean;
}

interface AlertRuleTemplatesTotals {
Expand Down
16 changes: 12 additions & 4 deletions public/app/percona/inventory/Tabs/Services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { ReadMoreLink } from 'app/percona/shared/components/Elements/TechnicalPr
import { TabbedPage, TabbedPageContents } from 'app/percona/shared/components/TabbedPage';
import { useCancelToken } from 'app/percona/shared/components/hooks/cancelToken.hook';
import { usePerconaNavModel } from 'app/percona/shared/components/hooks/perconaNavModel';
import { DATA_INTERVAL } from 'app/percona/shared/core';
import { useRecurringCall } from 'app/percona/shared/core/hooks/recurringCall.hook';
import { fetchActiveServiceTypesAction, fetchServicesAction } from 'app/percona/shared/core/reducers/services';
import { getServices } from 'app/percona/shared/core/selectors';
import { isApiCancelError } from 'app/percona/shared/helpers/api';
Expand All @@ -32,11 +34,13 @@ export const Services = () => {
const [modalVisible, setModalVisible] = useState(false);
const [selected, setSelectedRows] = useState<Array<Row<FlattenService>>>([]);
const [actionItem, setActionItem] = useState<FlattenService | null>(null);
const [triggerTimeout] = useRecurringCall();
const navModel = usePerconaNavModel('inventory-services');
const [generateToken] = useCancelToken();
const dispatch = useAppDispatch();
const { isLoading, services: fetchedServices } = useSelector(getServices);
const { services: fetchedServices } = useSelector(getServices);
const styles = useStyles2(getStyles);
const [isLoading, setIsLoading] = useState(true);
const flattenServices = useMemo(
() =>
fetchedServices.map((value) => {
Expand Down Expand Up @@ -69,10 +73,14 @@ export const Services = () => {
}, []);

useEffect(() => {
loadData();

loadData()
.then(() => {
triggerTimeout(loadData, DATA_INTERVAL);
setIsLoading(false);
})
.catch(() => setIsLoading(false));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [loadData]);

const handleSelectionChange = useCallback((rows: Array<Row<FlattenService>>) => {
setSelectedRows(rows);
Expand Down
5 changes: 3 additions & 2 deletions public/app/percona/pmm-dump/PMMDump.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { Row } from 'react-table';
import { HorizontalGroup, Icon, useStyles2, Badge, BadgeColor, LinkButton, Button } from '@grafana/ui';
import appEvents from 'app/core/app_events';
import { Page } from 'app/core/components/Page/Page';
import { DATA_INTERVAL } from 'app/percona/backup/components/BackupInventory/BackupInventory.constants';
import { DetailedDate } from 'app/percona/backup/components/DetailedDate';
import { useRecurringCall } from 'app/percona/backup/hooks/recurringCall.hook';
import { DumpStatus, DumpStatusColor, DumpStatusText, PMMDumpServices } from 'app/percona/pmm-dump/PmmDump.types';
import { DetailsRow } from 'app/percona/shared/components/Elements/DetailsRow/DetailsRow';
import { Action } from 'app/percona/shared/components/Elements/MultipleActions';
import { ExtendedColumn, FilterFieldTypes, Table } from 'app/percona/shared/components/Elements/Table';
import { PMM_DUMP_PAGE } from 'app/percona/shared/components/PerconaBootstrapper/PerconaNavigation';
import { DATA_INTERVAL } from 'app/percona/shared/core';
import { useRecurringCall } from 'app/percona/shared/core/hooks/recurringCall.hook';
import {
deletePmmDumpAction,
downloadPmmDumpAction,
Expand All @@ -32,6 +32,7 @@ import { Messages } from './PMMDump.messages';
import { getStyles } from './PmmDump.styles';
import { SendToSupportModal } from './SendToSupportModal';
import { PmmDumpLogsModal } from './components/PmmDumpLogsModal/PmmDumpLogsModal';

export const NEW_BACKUP_URL = '/pmm-dump/new';

export const PMMDump = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export const Messages = {
titleOneUpdate: 'New update available',
titleMultipleUpdates: 'New updates available',
howToUpdate: 'How to update',
howToUpdateDescription:
"We are inaugurating a new process for updating PMM. It's a new interface with an improved user experience and is ready for the future of PMM. Click on Go to Updates Page to find out more.",
newVersions: 'New Versions',
readMore: 'Read more',
fullReleaseNotes: 'Full release notes here',
goToUpdatesPage: 'Go to updates page',
snooze: 'Dismiss',
readyForAnUpdate: 'Ready for an upgrade?',
updateDescription:
"We've streamlined our update process with a new, user-friendly interface. One click gets you all the latest improvements.",
};
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ export const getStyles = ({ v1: { spacing, colors, typography } }: GrafanaTheme2
color: ${colors.textBlue};
},
`,
readyForUpdate: css`
margin-top: 10px;
`,
});
Loading

0 comments on commit 0cd9c6c

Please sign in to comment.