chore(#11742): test connection status modal improvements (#11744)

* chore(#11742): test connection status modal improvements

* fix: unit test

* chore: simplify the checks

* fix: card styling

* refactor: failed badge

* chore: handle reset state

* feat: add test connection timeout widget

* move constants to separate file

* chore: reset progress on test connection

* chore: update message

* chore: remove hardcode condition
This commit is contained in:
Sachin Chaurasiya 2023-05-31 15:12:55 +05:30 committed by GitHub
parent 04a0065f43
commit 67941f548d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 258 additions and 49 deletions

View File

@ -0,0 +1,17 @@
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_47_3311)">
<path d="M42.6836 0.312506C39.4219 1.9336 39.5391 6.69923 42.8594 8.08595C43.3282 8.28126 44.1875 8.39845 45.2617 8.39845H46.9219V9.27735C46.9219 10.0977 46.9024 10.1367 46.2969 10.2344C41.8047 10.918 40.8672 11.1914 40.4766 11.8945C40.125 12.5586 40.2422 13.457 40.7696 13.9649C41.2969 14.5117 42.2735 14.5899 43.6992 14.2578C44.5196 14.0625 49.0508 13.4766 49.793 13.4766C50.2227 13.4766 50.2422 13.5352 50.2422 15.2539C50.2422 17.5977 50.6524 18.3399 51.9414 18.3594C53.3868 18.3594 53.7578 17.7344 53.7578 15.2344V13.457L55.1836 13.5742C57.6446 13.8086 60.8086 14.4141 63.2305 15.1172C65.4961 15.7617 69.9688 17.5391 70.6133 18.0274C70.8868 18.2422 70.8086 18.4375 70.0469 19.7266C69.0899 21.3477 68.9727 22.1289 69.5782 22.9102C70.086 23.5352 70.7891 23.711 71.6094 23.3594C72.1172 23.1445 72.4493 22.7539 73.0743 21.6016C73.543 20.7813 74.0118 20.1172 74.1289 20.1172C74.5391 20.1172 78.4063 23.125 80.2618 24.8828C82.2149 26.7383 83.9532 28.7305 85.6719 31.1328L86.7852 32.6758L85.3594 33.5156C84.5782 33.9844 83.7774 34.5508 83.6016 34.7852C83.1328 35.3516 83.1524 36.3477 83.6602 36.9922C84.2657 37.7735 85.3008 37.6953 86.961 36.7188C87.7032 36.2891 88.3868 35.9375 88.4844 35.9375C88.9336 35.9375 91.2383 41.7578 92.0586 45C92.5274 46.8164 93.211 51.2696 93.211 52.4805V53.3203H91.2578C89.4219 53.3203 89.2461 53.3594 88.8164 53.8086C88.2891 54.3164 88.1719 55.2149 88.543 55.8985C88.875 56.5235 89.9297 56.836 91.6485 56.836H93.211V57.5586C93.211 58.711 92.5078 63.2031 92.0586 64.9805C91.1993 68.3399 88.9532 74.0235 88.4844 74.0235C88.3868 74.0235 87.6641 73.6719 86.8828 73.2422C86.0625 72.793 85.2032 72.461 84.8321 72.461C83.9336 72.461 83.25 73.2032 83.25 74.1797C83.25 75.0782 83.5821 75.4297 85.4375 76.5235L86.7657 77.2852L85.7696 78.7305C83.1719 82.4805 79.0703 86.6016 75.4375 89.0625C74.8125 89.4922 74.2071 89.8438 74.0899 89.8438C73.9922 89.8438 73.5821 89.2969 73.211 88.6133C72.2149 86.8555 71.8633 86.5235 70.9258 86.5235C70.3594 86.5235 70.0078 86.6602 69.6758 87.0117C68.9532 87.7149 69.0508 88.5157 70.0664 90.293L70.9453 91.836L68.9336 92.7735C65.3399 94.4532 61.2188 95.6446 57.0196 96.1914C53.4453 96.6602 53.7578 96.7969 53.7578 94.7071C53.7578 92.3243 53.3477 91.6211 52 91.6211C50.6524 91.6211 50.2422 92.3243 50.2422 94.7266V96.5235L48.4453 96.3868C47.4492 96.3086 45.9258 96.1133 45.0664 95.9766C44.2071 95.8203 43.0157 95.6446 42.3907 95.5664C41.3946 95.4688 41.2383 95.5078 40.7891 95.9571C40.125 96.6211 40.1055 97.6172 40.7305 98.3399C41.043 98.711 41.5117 98.9258 42.4883 99.1407C48.2696 100.352 55.5352 100.293 61.5703 99.0039C64.461 98.3789 68.4453 96.9727 71.4336 95.5078C78.6602 91.9922 84.7149 86.7188 89.2071 79.9805C94.7539 71.6992 97.1953 62.5977 96.6875 52.3047C96.2188 42.832 92.293 32.9883 86.1407 25.8789C85.5157 25.1563 85.0078 24.5117 85.0078 24.4336C85.0078 24.375 85.75 23.5742 86.668 22.6563L88.3282 21.0156L89.5 22.168L90.6719 23.3399L94.1875 19.8242C96.1211 17.8906 97.7032 16.2305 97.7032 16.1133C97.7032 15.9961 96.1211 14.3359 94.1875 12.4024L90.6719 8.88673L87.0586 12.5L83.4453 16.1133L84.6172 17.2852L85.7891 18.457L84.0703 20.1758L82.3321 21.8945L81.375 21.0352C75.3789 15.7031 67.4688 11.9531 59.2657 10.5664L57.1758 10.2149L57.1172 9.31641L57.0586 8.39845H58.7774C60.7891 8.39845 61.7461 8.04688 62.6836 6.97266C64.3633 5.07813 63.9532 2.03126 61.8243 0.585943L61.1016 0.097662L52.2149 0.0585995C44.3633 5.71884e-06 43.2305 0.0390682 42.6836 0.312506Z" fill="black" fill-opacity="0.5"/>
<path d="M27.918 21.6601C27.5078 21.7578 26.9414 21.9922 26.6484 22.207C25.9453 22.6953 25.2422 24.1211 25.2422 25C25.2422 25.957 25.9844 27.3437 26.7656 27.8711C27.625 28.4375 29.0508 28.5742 33.8359 28.4765C37.293 28.418 37.9375 28.3594 38.582 28.0469C40.9844 26.8555 40.9844 23.1445 38.582 21.9531C37.918 21.6211 37.332 21.582 33.25 21.543C30.7305 21.5234 28.3281 21.582 27.918 21.6601Z" fill="black" fill-opacity="0.5"/>
<path d="M18.797 33.6328C17.7618 34.1602 17.2735 34.8047 17.0196 35.918C16.6681 37.4609 17.5274 39.1992 18.9337 39.7656C19.8517 40.1563 37.4493 40.1563 38.3868 39.7656C41.0626 38.6523 41.1017 34.7852 38.4454 33.5742C37.7032 33.2422 36.9806 33.2031 28.6603 33.2031C19.7149 33.2031 19.6563 33.2031 18.797 33.6328Z" fill="black" fill-opacity="0.5"/>
<path d="M71.2383 36.7578C70.3008 37.2852 49.3047 52.5586 48.6601 53.1836C47.0781 54.707 46.5312 57.3438 47.3125 59.4531C48.4648 62.4609 51.5898 64.0234 54.7343 63.125C56.6289 62.5781 56.9804 62.168 65.0859 50.9375C74.4609 38.0078 73.6797 39.1602 73.6797 38.3008C73.6601 37.4609 73.3476 37.0117 72.625 36.7187C71.9609 36.4648 71.7265 36.4844 71.2383 36.7578Z" fill="black"/>
<path d="M10.3984 45.3516C8.03516 46.543 8.03516 50.0781 10.3789 51.3086L11.2578 51.7578L24.7539 51.7188L38.2695 51.6602L38.9922 51.0938C39.8125 50.4688 40.4766 49.2383 40.4766 48.3398C40.4766 47.0898 39.4219 45.5664 38.2695 45.1367C37.8984 44.9805 33.3867 44.9219 24.4805 44.9219H11.2578L10.3984 45.3516Z" fill="black" fill-opacity="0.5"/>
<path d="M3.95312 56.8554C2.72266 57.3437 2 58.5156 2 59.9804C2 61.2109 2.52734 62.2265 3.50391 62.8906L4.22656 63.3789L20.6914 63.4375C31.7461 63.4765 37.4297 63.4179 37.9375 63.2812C40.8477 62.5 41.3164 58.5156 38.6992 57.0507C37.9961 56.6406 37.7812 56.6406 21.2188 56.6601C10.5547 56.6601 4.26562 56.7382 3.95312 56.8554Z" fill="black" fill-opacity="0.5"/>
<path d="M14.5195 68.3594C13.7383 68.5352 13.0156 69.0625 12.4688 69.8047C12.1367 70.2148 12.0586 70.625 12.0586 71.6797C12.0586 73.1641 12.3711 73.7695 13.5234 74.5508L14.168 75H26.0625C37.5078 75 37.9766 74.9805 38.6992 74.6094C40.9258 73.4766 40.9648 70.0781 38.7578 68.7109L38.0352 68.2617L26.6094 68.2227C20.3203 68.2031 14.8906 68.2617 14.5195 68.3594Z" fill="black" fill-opacity="0.5"/>
<path d="M24.3047 80.0391C23.6015 80.2539 22.4883 81.25 22.1953 81.9531C21.5508 83.5156 22.1562 85.4102 23.5625 86.2305L24.4023 86.7188H31.082C38.5234 86.7188 38.6015 86.6992 39.6562 85.4297C41.0625 83.7109 40.4765 81.1719 38.4453 80.2539C37.7226 79.9219 37.0781 79.9023 31.1992 79.9023C27.664 79.9219 24.5586 79.9805 24.3047 80.0391Z" fill="black" fill-opacity="0.5"/>
</g>
<defs>
<clipPath id="clip0_47_3311">
<rect width="100" height="100" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,4 @@
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.88839 1.39985C5.03401 1.62386 4.05949 2.23986 3.37866 2.93986L2.72452 3.62587V2.86986V2.09986H2.25729H1.79005V3.70987V5.31988H3.32526H4.86046V4.82987C4.86046 4.33987 4.86046 4.33987 4.25973 4.33987C3.92599 4.33987 3.659 4.28387 3.659 4.22787C3.659 3.96187 4.72697 3.06586 5.4612 2.70186C6.11533 2.37986 6.44907 2.30986 7.2634 2.30986C9.02555 2.30986 10.494 3.28987 11.295 5.01188C11.6688 5.80988 11.7355 6.08988 11.7355 6.99989C11.7355 7.90989 11.6688 8.1899 11.295 8.9879C9.91997 11.9139 6.51582 12.6139 4.21968 10.4299C3.5789 9.8279 2.91142 8.5119 2.77792 7.61589C2.69782 7.02789 2.68447 6.99989 2.21724 6.99989H1.75L1.84345 7.79789C2.04369 9.6319 3.28521 11.3819 4.96726 12.2219C5.79494 12.6419 5.96848 12.6699 7.2634 12.6699C8.55831 12.6699 8.73186 12.6419 9.55953 12.2219C10.7343 11.6479 11.6955 10.6399 12.2428 9.4079C12.6433 8.5399 12.67 8.3579 12.67 6.99989C12.67 5.64188 12.6433 5.45988 12.2428 4.59187C11.6955 3.37387 10.721 2.35186 9.58623 1.79186C8.86535 1.44186 8.50491 1.35785 7.55709 1.31585C6.91631 1.28785 6.16873 1.32985 5.88839 1.39985Z" fill="#7147E8"/>
<path d="M5.92847 6.99984C5.92847 8.20385 5.98187 9.09985 6.04861 9.09985C6.20881 9.09985 9.39937 7.09784 9.39937 6.99984C9.39937 6.90184 6.20881 4.89983 6.04861 4.89983C5.98187 4.89983 5.92847 5.79583 5.92847 6.99984ZM7.39693 6.99984C7.39693 7.06984 7.27678 7.19584 7.12993 7.27984C6.88964 7.41984 6.86294 7.39184 6.86294 6.99984C6.86294 6.60784 6.88964 6.57984 7.12993 6.71984C7.27678 6.80384 7.39693 6.92984 7.39693 6.99984Z" fill="#7147E8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -51,6 +51,13 @@ import { AIRFLOW_DOCS } from 'constants/docs.constants';
import {
FETCHING_EXPIRY_TIME,
FETCH_INTERVAL,
TEST_CONNECTION_FAILURE_MESSAGE,
TEST_CONNECTION_INFO_MESSAGE,
TEST_CONNECTION_INITIAL_MESSAGE,
TEST_CONNECTION_PROGRESS_PERCENTAGE,
TEST_CONNECTION_SUCCESS_MESSAGE,
TEST_CONNECTION_TESTING_MESSAGE,
TEST_CONNECTION_WARNING_MESSAGE,
WORKFLOW_COMPLETE_STATUS,
} from 'constants/Services.constant';
import { useAirflowStatus } from 'hooks/useAirflowStatus';
@ -70,28 +77,14 @@ const TestConnection: FC<TestConnectionProps> = ({
const { t } = useTranslation();
const { isAirflowAvailable } = useAirflowStatus();
const initialMessage = t(
'message.test-your-connection-before-creating-service'
);
const successMessage = t('message.connection-test-successful');
const failureMessage = t('message.connection-test-failed');
const testingMessage = t(
'message.testing-your-connection-may-take-two-minutes'
);
const infoMessage = t('message.test-connection-taking-too-long');
const warningMessage = t('message.connection-test-warning');
// local state
const [isTestingConnection, setIsTestingConnection] =
useState<boolean>(false);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [message, setMessage] = useState<string>(initialMessage);
const [message, setMessage] = useState<string>(
TEST_CONNECTION_INITIAL_MESSAGE
);
const [testConnectionStep, setTestConnectionStep] = useState<
TestConnectionStep[]
@ -104,7 +97,12 @@ const TestConnection: FC<TestConnectionProps> = ({
const [currentWorkflow, setCurrentWorkflow] = useState<Workflow>();
const [testStatus, setTestStatus] = useState<TestStatus>();
const [progress, setProgress] = useState<number>(0);
const [progress, setProgress] = useState<number>(
TEST_CONNECTION_PROGRESS_PERCENTAGE.ZERO
);
const [isConnectionTimeout, setIsConnectionTimeout] =
useState<boolean>(false);
/**
* Current workflow reference
@ -163,6 +161,8 @@ const TestConnection: FC<TestConnectionProps> = ({
setCurrentWorkflow(undefined);
setTestConnectionStepResult([]);
setTestStatus(undefined);
setIsConnectionTimeout(false);
setProgress(0);
};
const handleDeleteWorkflow = async (workflowId: string) => {
@ -177,7 +177,7 @@ const TestConnection: FC<TestConnectionProps> = ({
// handlers
const testConnection = async () => {
setIsTestingConnection(true);
setMessage(testingMessage);
setMessage(TEST_CONNECTION_TESTING_MESSAGE);
handleResetState();
// current interval id
@ -198,21 +198,21 @@ const TestConnection: FC<TestConnectionProps> = ({
// fetch the connection steps for current connectionType
await fetchConnectionDefinition();
setProgress(10);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.TEN);
// create the workflow
const response = await addWorkflow(createWorkflowData);
setProgress(20);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.TWENTY);
// trigger the workflow
const status = await triggerWorkflowById(response.id);
setProgress(40);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.FORTY);
if (status !== 200) {
setTestStatus(StatusType.Failed);
setMessage(failureMessage);
setMessage(TEST_CONNECTION_FAILURE_MESSAGE);
setIsTestingConnection(false);
return;
@ -224,7 +224,7 @@ const TestConnection: FC<TestConnectionProps> = ({
*/
intervalId = toNumber(
setInterval(async () => {
setProgress((prev) => prev + 1);
setProgress((prev) => prev + TEST_CONNECTION_PROGRESS_PERCENTAGE.ONE);
const workflowResponse = await getWorkflowData(response.id);
const { response: testConnectionResponse } = workflowResponse;
const { status: testConnectionStatus, steps = [] } =
@ -241,10 +241,10 @@ const TestConnection: FC<TestConnectionProps> = ({
return;
}
setProgress(90);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.HUNDRED);
if (isTestConnectionSuccess) {
setTestStatus(StatusType.Successful);
setMessage(successMessage);
setMessage(TEST_CONNECTION_SUCCESS_MESSAGE);
} else {
const isMandatoryStepsFailing = steps.some(
(step) => step.mandatory && !step.passed
@ -253,7 +253,9 @@ const TestConnection: FC<TestConnectionProps> = ({
isMandatoryStepsFailing ? StatusType.Failed : 'Warning'
);
setMessage(
isMandatoryStepsFailing ? failureMessage : warningMessage
isMandatoryStepsFailing
? TEST_CONNECTION_FAILURE_MESSAGE
: TEST_CONNECTION_WARNING_MESSAGE
);
}
@ -265,7 +267,6 @@ const TestConnection: FC<TestConnectionProps> = ({
// delete the workflow once it's finished
await handleDeleteWorkflow(workflowResponse.id);
setProgress(100);
}, FETCH_INTERVAL)
);
@ -283,17 +284,18 @@ const TestConnection: FC<TestConnectionProps> = ({
);
if (!isWorkflowCompleted) {
setMessage(infoMessage);
setMessage(TEST_CONNECTION_INFO_MESSAGE);
setIsConnectionTimeout(true);
}
setIsTestingConnection(false);
setProgress(100);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.HUNDRED);
}, FETCHING_EXPIRY_TIME);
} catch (error) {
setProgress(100);
setProgress(TEST_CONNECTION_PROGRESS_PERCENTAGE.HUNDRED);
clearInterval(intervalId);
setIsTestingConnection(false);
setMessage(failureMessage);
setMessage(TEST_CONNECTION_FAILURE_MESSAGE);
setTestStatus(StatusType.Failed);
showErrorToast(error as AxiosError);
}
@ -402,6 +404,7 @@ const TestConnection: FC<TestConnectionProps> = ({
</Button>
)}
<TestConnectionModal
isConnectionTimeout={isConnectionTimeout}
isOpen={dialogOpen}
isTestingConnection={isTestingConnection}
progress={progress}
@ -409,6 +412,7 @@ const TestConnection: FC<TestConnectionProps> = ({
testConnectionStepResult={testConnectionStepResult}
onCancel={() => setDialogOpen(false)}
onConfirm={() => setDialogOpen(false)}
onTestConnection={handleTestConnection}
/>
</>
);

View File

@ -10,7 +10,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { fireEvent, render, screen } from '@testing-library/react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import TestConnectionModal from './TestConnectionModal';
const onCancelMock = jest.fn();
@ -34,17 +35,23 @@ const testConnectionStepResult = [
},
];
const mockOnTestConnection = jest.fn();
const isConnectionTimeout = false;
describe('TestConnectionModal', () => {
it('Should render the modal title', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
@ -55,12 +62,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
@ -72,12 +81,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
@ -88,12 +99,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
@ -105,11 +118,13 @@ describe('TestConnectionModal', () => {
<TestConnectionModal
isOpen
isTestingConnection
isConnectionTimeout={isConnectionTimeout}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
@ -120,12 +135,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
const cancelButton = screen.getByText('Cancel');
@ -139,12 +156,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={10}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
const okButton = screen.getByText('OK');
@ -158,12 +177,14 @@ describe('TestConnectionModal', () => {
render(
<TestConnectionModal
isOpen
isConnectionTimeout={isConnectionTimeout}
isTestingConnection={false}
progress={90}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
const progressBarValue = screen.getByTestId('progress-bar-value');
@ -172,4 +193,50 @@ describe('TestConnectionModal', () => {
expect(progressBarValue).toHaveTextContent('90%');
});
it('Should render the timeout widget if "isConnectionTimeout" is true', () => {
render(
<TestConnectionModal
isConnectionTimeout
isOpen
isTestingConnection={false}
progress={90}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
expect(
screen.getByTestId('test-connection-timeout-widget')
).toBeInTheDocument();
});
it('Try again button should work', async () => {
render(
<TestConnectionModal
isConnectionTimeout
isOpen
isTestingConnection={false}
progress={90}
testConnectionStep={testConnectionStep}
testConnectionStepResult={testConnectionStepResult}
onCancel={onCancelMock}
onConfirm={onConfirmMock}
onTestConnection={mockOnTestConnection}
/>
);
const tryAgainButton = screen.getByTestId('try-again-button');
expect(tryAgainButton).toBeInTheDocument();
await act(async () => {
userEvent.click(tryAgainButton);
});
expect(mockOnTestConnection).toHaveBeenCalled();
});
});

View File

@ -10,21 +10,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Modal, Progress, Space } from 'antd';
import {
Button,
Modal,
Progress,
ProgressProps,
Space,
Typography,
} from 'antd';
import { ReactComponent as IconTimeOut } from 'assets/svg/ic-time-out.svg';
import { ReactComponent as IconTimeOutButton } from 'assets/svg/ic-timeout-button.svg';
import { TestConnectionStepResult } from 'generated/entity/automations/workflow';
import { TestConnectionStep } from 'generated/entity/services/connections/testConnectionDefinition';
import React, { FC } from 'react';
import { useTranslation } from 'react-i18next';
import ConnectionStepCard from '../ConnectionStepCard/ConnectionStepCard';
import './test-connection-modal.less';
interface TestConnectionModalProps {
isOpen: boolean;
isTestingConnection: boolean;
testConnectionStep: TestConnectionStep[];
testConnectionStepResult: TestConnectionStepResult[];
progress: number;
isConnectionTimeout: boolean;
onCancel: () => void;
onConfirm: () => void;
onTestConnection: () => void;
}
const TestConnectionModal: FC<TestConnectionModalProps> = ({
@ -35,6 +46,8 @@ const TestConnectionModal: FC<TestConnectionModalProps> = ({
testConnectionStepResult,
onCancel,
onConfirm,
isConnectionTimeout,
onTestConnection,
}) => {
const { t } = useTranslation();
@ -44,6 +57,10 @@ const TestConnectionModal: FC<TestConnectionModalProps> = ({
);
};
const getProgressFormat: ProgressProps['format'] = (progress) => {
return <span data-testid="progress-bar-value">{`${progress}%`}</span>;
};
return (
<Modal
centered
@ -59,24 +76,50 @@ const TestConnectionModal: FC<TestConnectionModalProps> = ({
<Space className="p-x-md w-full" direction="vertical" size={16}>
<Progress
className="test-connection-progress-bar"
format={(per) => (
<span data-testid="progress-bar-value">{`${per}%`}</span>
)}
format={getProgressFormat}
percent={progress}
strokeColor="#B3D4F4"
/>
{testConnectionStep.map((step) => {
const currentStepResult = getConnectionStepResult(step);
{isConnectionTimeout ? (
<Space
align="center"
className="timeout-widget justify-center w-full"
data-testid="test-connection-timeout-widget"
direction="vertical"
size={20}>
<IconTimeOut height={100} width={100} />
<Typography.Title level={5}>
{t('label.connection-timeout')}
</Typography.Title>
<Typography.Text className="text-grey-muted">
{t('message.test-connection-taking-too-long')}
</Typography.Text>
<Button
ghost
className="try-again-button"
data-testid="try-again-button"
icon={<IconTimeOutButton height={14} width={14} />}
type="primary"
onClick={onTestConnection}>
{t('label.try-again')}
</Button>
</Space>
) : (
<>
{testConnectionStep.map((step) => {
const currentStepResult = getConnectionStepResult(step);
return (
<ConnectionStepCard
isTestingConnection={isTestingConnection}
key={step.name}
testConnectionStep={step}
testConnectionStepResult={currentStepResult}
/>
);
})}
return (
<ConnectionStepCard
isTestingConnection={isTestingConnection}
key={step.name}
testConnectionStep={step}
testConnectionStepResult={currentStepResult}
/>
);
})}
</>
)}
</Space>
</Modal>
);

View File

@ -0,0 +1,30 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import url('../../../../styles/variables.less');
.timeout-widget {
background: @white;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 56px;
text-align: center;
h5 {
font-weight: 500;
margin-bottom: 0px;
}
.try-again-button {
display: flex;
gap: 2px;
align-items: center;
}
}

View File

@ -315,6 +315,14 @@ export const WORKFLOW_COMPLETE_STATUS = [
WorkflowStatus.Failed,
WorkflowStatus.Successful,
];
export const TEST_CONNECTION_PROGRESS_PERCENTAGE = {
ZERO: 0,
ONE: 1,
TEN: 10,
TWENTY: 20,
FORTY: 40,
HUNDRED: 100,
};
export const INGESTION_GUIDE_MAP = {
[PipelineType.Usage]: addUsageIngestionGuide,
@ -338,3 +346,27 @@ export const BETA_SERVICES = [
DatabaseServiceType.Impala,
PipelineServiceType.Spline,
];
export const TEST_CONNECTION_INITIAL_MESSAGE = i18n.t(
'message.test-your-connection-before-creating-service'
);
export const TEST_CONNECTION_SUCCESS_MESSAGE = i18n.t(
'message.connection-test-successful'
);
export const TEST_CONNECTION_FAILURE_MESSAGE = i18n.t(
'message.connection-test-failed'
);
export const TEST_CONNECTION_TESTING_MESSAGE = i18n.t(
'message.testing-your-connection-may-take-two-minutes'
);
export const TEST_CONNECTION_INFO_MESSAGE = i18n.t(
'message.test-connection-taking-too-long'
);
export const TEST_CONNECTION_WARNING_MESSAGE = i18n.t(
'message.connection-test-warning'
);

View File

@ -142,6 +142,7 @@
"connection-details": "Connection Details",
"connection-entity": "Connection {{entity}}",
"connection-status": "Connection status",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "Connection Timeout",
"connector": "Connector",
"container": "Container",
@ -909,6 +910,7 @@
"trigger": "Trigger",
"trigger-type": "Trigger type",
"triggering-lowercase": "triggering",
"try-again": "Try Again",
"tuesday": "Tuesday",
"type": "Type",
"type-filed-name": "Type {{fieldName}}",

View File

@ -142,6 +142,7 @@
"connection-details": "Detalles de conexión",
"connection-entity": "Conexión {{entity}}",
"connection-status": "Estado de la conexión",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "Tiempo de conexión expirado",
"connector": "Conector",
"container": "Contenedor",
@ -909,6 +910,7 @@
"trigger": "Desencadenador",
"trigger-type": "Trigger type",
"triggering-lowercase": "desencadenamiento",
"try-again": "Try Again",
"tuesday": "Martes",
"type": "Tipo",
"type-filed-name": "Tipo {{fieldName}}",

View File

@ -142,6 +142,7 @@
"connection-details": "Détails de Connexion",
"connection-entity": "Connexion {{entity}}",
"connection-status": "Statut de la Connexion",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "Délais d'Attente de la Connexion",
"connector": "Connecteur",
"container": "Conteneur",
@ -909,6 +910,7 @@
"trigger": "Déclencheur",
"trigger-type": "Type de déclencheur",
"triggering-lowercase": "déclenchement",
"try-again": "Try Again",
"tuesday": "Mardi",
"type": "Type",
"type-filed-name": "Type {{fieldName}}",

View File

@ -142,6 +142,7 @@
"connection-details": "接続の詳細",
"connection-entity": "{{entity}}との接続",
"connection-status": "Connection status",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "接続のタイムアウト",
"connector": "コネクタ",
"container": "コンテナ",
@ -909,6 +910,7 @@
"trigger": "トリガー",
"trigger-type": "Trigger type",
"triggering-lowercase": "triggering",
"try-again": "Try Again",
"tuesday": "火曜日",
"type": "Type",
"type-filed-name": "Type {{fieldName}}",

View File

@ -142,6 +142,7 @@
"connection-details": "Detalhes da conexão",
"connection-entity": "Conexão {{entity}}",
"connection-status": "Connection status",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "tempos limites de conexão",
"connector": "Conector",
"container": "Container",
@ -909,6 +910,7 @@
"trigger": "Disparador",
"trigger-type": "Trigger type",
"triggering-lowercase": "disparador",
"try-again": "Try Again",
"tuesday": "Terça-feira",
"type": "Tipo",
"type-filed-name": "Digite {{fieldName}}",

View File

@ -142,6 +142,7 @@
"connection-details": "连接详细信息",
"connection-entity": "连接{{entity}}",
"connection-status": "连接状态",
"connection-timeout": "Connection Timeout",
"connection-timeout-plural": "连接超时",
"connector": "连接器",
"container": "存储容器",
@ -909,6 +910,7 @@
"trigger": "触发器",
"trigger-type": "触发器类型",
"triggering-lowercase": "触发",
"try-again": "Try Again",
"tuesday": "星期二",
"type": "类型",
"type-filed-name": "{{fieldName}}类型",