frontend: fix react-bootstrap modal with radix modal

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8706
Co-authored-by: Varun Choudhary <68095256+Varun-Choudhary@users.noreply.github.com>
Co-authored-by: Vijay Prasanna <11921040+vijayprasanna13@users.noreply.github.com>
GitOrigin-RevId: 7b6db44363bd797d1af00517d6a7b2ef6471fff7
This commit is contained in:
Abhijeet Khangarot 2023-04-11 15:18:49 +05:30 committed by hasura-bot
parent 4696b60ec7
commit 51afe114a5
14 changed files with 477 additions and 469 deletions

View File

@ -84,6 +84,7 @@ export { default as PageNotFound } from './lib/components/Error/PageNotFound';
export * from './lib/new-components/Button/';
export * from './lib/new-components/Tooltip/';
export * from './lib/new-components/Badge/';
export * from './lib/new-components/Dialog';
export { default as dataHeaders } from './lib/components/Services/Data/Common/Headers';
export { handleMigrationErrors } from './lib/components/Services/Data/TableModify/ModifyActions';
export { loadMigrationStatus } from './lib/components/Main/Actions';

View File

@ -164,7 +164,7 @@ const ViewRows = props => {
Header: '',
accessor: 'tableRowActionButtons',
id: 'tableRowActionButtons',
width: 182,
width: 'auto',
});
_gridHeadings.push({

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Modal from 'react-bootstrap/lib/Modal';
import { Dialog } from '../../../../../new-components/Dialog';
import AceEditor from 'react-ace';
import { connect } from 'react-redux';
//TODO: check
@ -99,7 +99,7 @@ class InvokeManualTrigger extends React.PureComponent {
}
return (
<div className="flex">
<div className={`pl-0 w-1/2`}>
<div className={`pl-0 w-1/2 mr-sm`}>
<div> Request </div>
<AceEditor
mode="json"
@ -155,22 +155,21 @@ class InvokeManualTrigger extends React.PureComponent {
</div>
</div>
);
if (!isModalOpen) return null;
return (
<div key={identifier}>
<Modal
show={isModalOpen}
style={{
minHeight: '100px',
}}
onHide={this.onModalClose}
dialogClassName="w-3/4"
<Dialog
onClose={this.onModalClose}
id="invokeEventTrigger"
title={`Invoking ${name}`}
className="min-h-[100px]"
size="xxxl"
hasBackdrop
>
<Modal.Header closeButton>
<Modal.Title>Invoking {name}</Modal.Title>
</Modal.Header>
<Modal.Body>{getEventData()}</Modal.Body>
</Modal>
<div className="p-md ">{getEventData()}</div>
</Dialog>
</div>
);
}

View File

@ -107,65 +107,85 @@ export type DialogProps = {
onClose?: () => void;
footer?: FooterProps | React.ReactElement;
size?: DialogSize;
portal?: boolean;
// provides a way to add styles to the div wrapping the
contentContainer?: {
className?: string;
};
};
export const Dialog = ({
children,
hasBackdrop,
title,
titleTooltip,
description,
onClose,
footer,
size = 'md',
contentContainer,
}: DialogProps) => (
<RadixDialog.Root open>
{hasBackdrop && <Backdrop />}
<RadixDialog.Content
className={clsx(
size === 'max' ? '' : 'w-full',
`fixed transform -translate-x-2/4 left-2/4 mt-lg top-0 h-auto bg-gray-50 rounded overflow-hidden shadow-lg z-[101]`,
dialogSizing[size]
)}
>
{onClose && (
<RadixDialog.Close className="fixed right-3 top-3">
<FaTimes
className="ml-auto w-5 h-5 cursor-pointer text-gray-400 fill-current hover:text-gray-500"
onClick={onClose}
/>
</RadixDialog.Close>
)}
{!!title && (
<RadixDialog.Title className="flex items-top mb-1 pl-md pt-md pr-md text-xl font-semibold">
{title}
{!!titleTooltip && (
<IconTooltip className="-ml-1" message={titleTooltip} />
)}
</RadixDialog.Title>
)}
{!!description && (
<RadixDialog.Description className="text-muted pl-md pb-md pr-md ">
{description}
</RadixDialog.Description>
)}
<div
const DialogChildren = (props: DialogProps) => {
const {
children,
hasBackdrop,
title,
titleTooltip,
description,
onClose,
footer,
size = 'md',
contentContainer,
} = props;
return (
<>
{hasBackdrop && <Backdrop />}
<RadixDialog.Content
className={clsx(
'overflow-y-auto max-h-[calc(100vh-14rem)]',
contentContainer?.className
size === 'max' ? '' : 'w-full',
`fixed transform -translate-x-2/4 left-2/4 mt-lg top-0 h-auto bg-gray-50 rounded overflow-hidden shadow-lg z-[101]`,
dialogSizing[size]
)}
>
{children}
</div>
{React.isValidElement(footer) && footer}
{footer && !React.isValidElement(footer) && <Footer {...footer} />}
</RadixDialog.Content>
</RadixDialog.Root>
);
{onClose && (
<RadixDialog.Close className="fixed right-3 top-3">
<FaTimes
className="ml-auto w-5 h-5 cursor-pointer text-gray-400 fill-current hover:text-gray-500"
onClick={onClose}
/>
</RadixDialog.Close>
)}
{!!title && (
<RadixDialog.Title className="flex items-top mb-1 pl-md pt-md pr-md text-xl font-semibold">
{title}
{!!titleTooltip && (
<IconTooltip className="-ml-1" message={titleTooltip} />
)}
</RadixDialog.Title>
)}
{!!description && (
<RadixDialog.Description className="text-muted pl-md pb-md pr-md ">
{description}
</RadixDialog.Description>
)}
<div
className={clsx(
'overflow-y-auto max-h-[calc(100vh-14rem)]',
contentContainer?.className
)}
>
{children}
</div>
{React.isValidElement(footer) && footer}
{footer && !React.isValidElement(footer) && <Footer {...footer} />}
</RadixDialog.Content>
</>
);
};
export const Dialog = (props: DialogProps) => {
const { portal = false } = props;
return (
<RadixDialog.Root open>
{portal ? (
<RadixDialog.Portal>
<DialogChildren {...props} />
</RadixDialog.Portal>
) : (
<DialogChildren {...props} />
)}
</RadixDialog.Root>
);
};
Dialog.Footer = Footer;

View File

@ -32,7 +32,7 @@ const CustomCopy = ({ label, copy, onEdit }) => {
<React.Fragment>
<div className={styles.infoWrapper}>
<div className={styles.information}>
{label}:
<span>{label}:</span>
<span>
{onEdit && (
<EditIcon
@ -47,7 +47,7 @@ const CustomCopy = ({ label, copy, onEdit }) => {
</div>
</div>
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
<div className={styles.box}>
<div className={`p-xs overflow-auto ${styles.box}`}>
<code className={styles.queryCode}>
<pre style={{ whitespace: 'pre-wrap' }}>{copy}</pre>
</code>

View File

@ -1,6 +1,5 @@
import React, { useState } from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
// import BootstrapModalButton from 'react-bootstrap/lib/Button';
import { useState } from 'react';
import { Dialog } from '@hasura/console-legacy-ce';
// import DatePicker from 'react-datepicker';
// import 'react-datepicker/dist/react-datepicker.css';
import { DateRangePicker } from 'react-date-range';
@ -40,19 +39,24 @@ const DatePickerModal = props => {
};
}
*/
if (!show) return null;
return (
<BootstrapModal
<Dialog
hasBackdrop
size="xxl"
id="dateModal"
onHide={onHide}
show={show}
className={clsx(styles.datePickerModalWrapper, '!pointer-events-auto')}
onClose={onHide}
title="Custom Date"
portal
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Custom Date
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body>
<div
className={clsx(
styles.datePickerModalWrapper,
'!pointer-events-auto',
'p-sm'
)}
>
<div className={styles.datePickerContainer}>
<div className={styles.datePickerWrapper}>
{/*
@ -97,8 +101,8 @@ const DatePickerModal = props => {
Cancel
</Button>
</div>
</BootstrapModal.Body>
</BootstrapModal>
</div>
</Dialog>
);
};

View File

@ -1,7 +1,5 @@
import React from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
// import BootstrapModalButton from 'react-bootstrap/lib/Button';
import CustomCopy from './CustomCopy';
import { Dialog } from '@hasura/console-legacy-ce';
import { transformedVals } from '../Operations/utils';
import styles from '../Metrics.module.scss';
@ -214,146 +212,146 @@ const Modal = props => {
};
return (
<BootstrapModal
<Dialog
id="operationInspect"
onHide={onHide}
show
size="modal-lg"
className={styles.modalWrapper}
onClose={onHide}
hasBackdrop
size="xxxl"
title="Inspect"
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Inspect
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body
className={styles.modalContainer}
style={{ maxHeight: '986px' }}
>
<div className={styles.modalWrapper}>
<div
className={
styles.noPadd +
' col-md-6 ' +
styles.borderRight +
' ' +
styles.flexColumn
}
className={`mt-2 border border-top overflow-auto ${styles.modalContainer}`}
>
<div className={styles.infoWrapper}>
<div className={`${styles.infoField} ${styles.paddingBottom}`}>
<div className={styles.information}>
TIMESTAMP: <span>{new Date(time).toLocaleString()}</span>
</div>
{/*
<div
className={
styles.noPadd +
' col-md-6 ' +
styles.borderRight +
' ' +
styles.flexColumn
}
>
<div className={styles.infoWrapper}>
<div className={`${styles.infoField} ${styles.paddingBottom}`}>
<div className={styles.information}>
TIMESTAMP: <span>{new Date(time).toLocaleString()}</span>
</div>
{/*
<div className={styles.information}>
ID: <span>{id}</span>
</div>
*/}
<div className={styles.information}>
OPERATION NAME: <span>{operationName || 'N/A'}</span>
</div>
<div className={styles.information}>
OPERATION ID: <span>{operationId || 'N/A'}</span>
</div>
<div className={styles.information}>
REQUEST ID: <span>{requestId}</span>
</div>
<div
className={
styles.information +
' ' +
styles.borderBottom +
' ' +
styles.addPaddBottom
}
>
TRANSPORT: <span>{transport}</span>
</div>
{transport === 'ws' ? (
<div className={styles.borderBottom + ' ' + styles.paddingTop}>
<div className={styles.information}>
WEBSOCKET ID: <span>{websocketId}</span>
</div>
<div className={styles.information}>
WEBSOCKET OPERATION ID: <span>{websocketOperationId}</span>
</div>
{operationType === 'subscription' ? (
<div className={styles.information}>
SUBSCRIPTION STATUS <span>{status}</span>
</div>
) : null}
<div className={styles.information}>
OPERATION NAME: <span>{operationName || 'N/A'}</span>
</div>
) : null}
</div>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
{/*
<div className={styles.information}>
OPERATION ID: <span>{operationId || 'N/A'}</span>
</div>
<div className={styles.information}>
REQUEST ID: <span>{requestId}</span>
</div>
<div
className={
styles.information +
' ' +
styles.borderBottom +
' ' +
styles.addPaddBottom
}
>
TRANSPORT: <span>{transport}</span>
</div>
{transport === 'ws' ? (
<div
className={styles.borderBottom + ' ' + styles.paddingTop}
>
<div className={styles.information}>
WEBSOCKET ID: <span>{websocketId}</span>
</div>
<div className={styles.information}>
WEBSOCKET OPERATION ID:{' '}
<span>{websocketOperationId}</span>
</div>
{operationType === 'subscription' ? (
<div className={styles.information}>
SUBSCRIPTION STATUS <span>{status}</span>
</div>
) : null}
</div>
) : null}
</div>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
{/*
<div className={styles.information}>
CLIENT ID: <span>{clientId}</span>
</div>
*/}
<div className={styles.information}>
CLIENT NAME: <span>{client_name || 'N/A'}</span>
</div>
<div
className={`${styles.information} ${styles.noPaddingBottom}`}
>
ROLE: <span>{role || 'N/A'}</span>
</div>
</div>
</div>
{renderSessonVars()}
<div className={`${styles.infoWrapper} ${styles.noPaddingTop}`}>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
<div
className={`
${styles.information} ${styles.borderTop} ${styles.paddingTop}
`}
>
EXECUTION TIME:{' '}
<span>
{('execution_time' in transformedVals &&
transformedVals.execution_time(executionTime)) ||
executionTime}{' '}
ms
</span>
</div>
<div
className={`
${styles.information} ${styles.paddingTop}
`}
>
TIMING
<div className={styles.paddingTop}>
{trace && trace?.length && <TraceGraph trace={trace} />}
<div className={styles.information}>
CLIENT NAME: <span>{client_name || 'N/A'}</span>
</div>
<div
className={`${styles.information} ${styles.noPaddingBottom}`}
>
ROLE: <span>{role || 'N/A'}</span>
</div>
</div>
<div className={`${styles.information} ${styles.addPaddBottom}`}>
REQUEST SIZE:{' '}
<span>
{(transformedVals.hasOwnProperty('request_size') &&
transformedVals.request_size(requestSize)) ||
requestSize}{' '}
kB
</span>
<br />
RESPONSE SIZE:{' '}
<span>
{('response_size' in transformedVals &&
transformedVals.response_size(responseSize)) ||
responseSize}{' '}
kB
</span>
</div>
{renderSessonVars()}
<div className={`${styles.infoWrapper} ${styles.noPaddingTop}`}>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
<div
className={`
${styles.information} ${styles.borderTop} ${styles.paddingTop}
`}
>
EXECUTION TIME:{' '}
<span>
{('execution_time' in transformedVals &&
transformedVals.execution_time(executionTime)) ||
executionTime}{' '}
ms
</span>
</div>
<div
className={`
${styles.information} ${styles.paddingTop}
`}
>
TIMING
<div className={styles.paddingTop}>
{trace && trace?.length && <TraceGraph trace={trace} />}
</div>
</div>
<div
className={`${styles.information} ${styles.addPaddBottom}`}
>
REQUEST SIZE:{' '}
<span>
{(transformedVals.hasOwnProperty('request_size') &&
transformedVals.request_size(requestSize)) ||
requestSize}{' '}
kB
</span>
<br />
RESPONSE SIZE:{' '}
<span>
{('response_size' in transformedVals &&
transformedVals.response_size(responseSize)) ||
responseSize}{' '}
kB
</span>
</div>
</div>
</div>
{renderError()}
{renderResponseAnalysis()}
</div>
{renderError()}
{renderResponseAnalysis()}
</div>
<div className={styles.noPadd + ' col-md-6'}>
{renderOperationQuery()}
{renderGeneratedSql()}
{renderRequestHeaders()}
{/*
<div className={`overflow-auto ${styles.noPadd} col-md-6`}>
{renderOperationQuery()}
{renderGeneratedSql()}
{renderRequestHeaders()}
{/*
<div className={styles.infoWrapper}>
<div className={styles.information}>
GENERATED SQL:{' '}
@ -364,9 +362,10 @@ const Modal = props => {
<div className={styles.box} />
</div>
*/}
</div>
</div>
</BootstrapModal.Body>
</BootstrapModal>
</div>
</Dialog>
);
};

View File

@ -1,7 +1,7 @@
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import { Link } from 'react-router';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { Dialog } from '@hasura/console-legacy-ce';
import { Button } from '@hasura/console-legacy-ce';
import CustomCopy from './CustomCopy';
@ -174,59 +174,57 @@ const Modal = props => {
};
return (
<BootstrapModal
id="operationInspect"
onHide={onHide}
show
size="modal-lg"
className={styles.modalWrapper}
<Dialog
hasBackdrop
size="xxl"
id="dateModal"
onClose={onHide}
title="Inspect"
portal
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Inspect
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body className={styles.modalContainer}>
<div className={styles.noPadd + ' col-md-6 ' + styles.borderRight}>
<div className={styles.infoWrapper}>
<div className={styles.infoField}>
<div className={styles.information}>
ID: <span>{id || 'N/A'}</span>
<span className={styles.rightAlign}>{getRequestsLink()}</span>
</div>
<div className={styles.information}>
OPERATION NAME: <span>{operationName || 'N/A'}</span>
</div>
<div className={styles.information}>
EXECUTED BY ROLES: <span>{computeRoles()}</span>
</div>
<div className={styles.information}>
REQUESTS: <span>{requestCount} Requests</span>
</div>
<div className={styles.information}>
AVERAGE EXECUTION TIME:{' '}
<span>{computeAverageExecutionTime()} ms</span>
</div>
<div className={styles.information}>
AVERAGE RESPONSE SIZE:{' '}
<span>{computeAverageResponseSize()} kB</span>
</div>
<div className={styles.information}>
ERROR RATE: <span>{computeErrorRate()}</span>
<span className={styles.addPaddLeft}>{getErrorLink()}</span>
<div className={styles.modalWrapper}>
<div className={styles.modalContainer}>
<div className={styles.noPadd + ' col-md-6 ' + styles.borderRight}>
<div className={styles.infoWrapper}>
<div className={styles.infoField}>
<div className={styles.information}>
ID: <span>{id || 'N/A'}</span>
<span className={styles.rightAlign}>{getRequestsLink()}</span>
</div>
<div className={styles.information}>
OPERATION NAME: <span>{operationName || 'N/A'}</span>
</div>
<div className={styles.information}>
EXECUTED BY ROLES: <span>{computeRoles()}</span>
</div>
<div className={styles.information}>
REQUESTS: <span>{requestCount} Requests</span>
</div>
<div className={styles.information}>
AVERAGE EXECUTION TIME:{' '}
<span>{computeAverageExecutionTime()} ms</span>
</div>
<div className={styles.information}>
AVERAGE RESPONSE SIZE:{' '}
<span>{computeAverageResponseSize()} kB</span>
</div>
<div className={styles.information}>
ERROR RATE: <span>{computeErrorRate()}</span>
<span className={styles.addPaddLeft}>{getErrorLink()}</span>
</div>
</div>
</div>
</div>
</div>
{renderQueryIfExists()}
{/*
{renderQueryIfExists()}
{/*
<div className={styles.noPadd + ' col-md-6'}>
{renderOperationQuery()}
{renderGeneratedSql()}
</div>
*/}
</BootstrapModal.Body>
</BootstrapModal>
</div>
</div>
</Dialog>
);
};

View File

@ -785,8 +785,6 @@
/* common checkbox */
.commonCheckBox,
.defaultCheckBox {
min-width: 110px;
input[type='checkbox'] {
position: absolute; // take it out of document flow
opacity: 0; // hide it
@ -873,6 +871,7 @@
}
.modalWrapper {
padding: 0;
text-align: left;
.modalHeader {
background-color: #f8f8f8;
padding: 19px 32px;

View File

@ -1,6 +1,5 @@
import React, { useState, Fragment } from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { Tooltip } from '@hasura/console-legacy-ce';
import { useState, Fragment } from 'react';
import { Dialog, Tooltip } from '@hasura/console-legacy-ce';
import { useMutation } from '@apollo/react-hooks';
import CustomCopy from '../Common/CustomCopy';
@ -101,7 +100,7 @@ const EditRowModal = ({ onHide, show, name, testSuiteId }) => {
/>
</div>
<div
className={`col-md-6 ${styles.noPadd} ${styles.longCopy} ${styles.paddingBottom}`}
className={`col-md-6 ${styles.noPadd} ${styles.longCopy} ${styles.paddingBottom} w-full`}
>
{isEditing ? (
<EditData
@ -138,22 +137,19 @@ const EditRowModal = ({ onHide, show, name, testSuiteId }) => {
}
};
if (!show) return null;
return (
<BootstrapModal
<Dialog
id="operationInspect"
onHide={onHide}
show={show}
size="modal-lg"
className={styles.modalWrapper}
onClose={onHide}
hasBackdrop
size="xxl"
title="Inspect"
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Edit test
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body className={styles.modalContainer}>
{renderModalBody()}
</BootstrapModal.Body>
</BootstrapModal>
<div className={styles.modalWrapper}>
<div className={styles.modalContainer}>{renderModalBody()}</div>
</div>
</Dialog>
);
};

View File

@ -1,7 +1,6 @@
import React, { useState, Fragment } from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { useState, Fragment } from 'react';
// import { useMutation } from '@apollo/react-hooks';
import { Button } from '@hasura/console-legacy-ce';
import { Button, Dialog } from '@hasura/console-legacy-ce';
import { BrowseRunTests } from './BrowseRunTests';
import { BrowseRunTestsPreview } from './BrowseTestRunPreview';
@ -165,37 +164,34 @@ const RunTests = props => {
Run tests on CLI
</Button>
</div>
<BootstrapModal
id="operationInspect"
onHide={onHide}
show={showModal}
size="modal-lg"
className={styles.modalWrapper}
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Run tests from CLI
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body
className={`${styles.modalContainer} ${styles.padding20}`}
{showModal && (
<Dialog
id="operationInspect"
onClose={onHide}
hasBackdrop
size="xxl"
title="Run tests from CLI"
>
<div>
You can run tests from the CLI also. See{' '}
<a
href="https://docs.pro.hasura.io/cli/regression-tests/"
target="_blank"
rel="noopener noreferrer"
>
docs
</a>{' '}
for more info.
<div className={`p-sm ${styles.modalWrapper}`}>
<div className={styles.modalContainer}>
<div>
You can run tests from the CLI also. See <br />
<a
href="https://docs.pro.hasura.io/cli/regression-tests/"
target="_blank"
rel="noopener noreferrer"
>
docs
</a>{' '}
for more info.
</div>
<code>
{`hasura pro regression-tests run --testsuite-id ${testSuiteId} --project-id ${currentProjectId}`}
</code>
</div>
</div>
<code>
{`hasura pro regression-tests run --testsuite-id ${testSuiteId} --project-id ${currentProjectId}`}
</code>
</BootstrapModal.Body>
</BootstrapModal>
</Dialog>
)}
{testRunId ? (
<BrowseRunTests
testSuiteId={testSuiteId}

View File

@ -1,5 +1,5 @@
import React, { useState, Fragment } from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { useState, Fragment } from 'react';
import { Dialog } from '@hasura/console-legacy-ce';
import { useQuery } from '@apollo/react-hooks';
import CustomCopy from '../Common/CustomCopy';
@ -67,68 +67,67 @@ const TestRunDetailsModal = ({ onHide, show, operationName, testRunId }) => {
},
});
if (!show) return null;
return (
<BootstrapModal
<Dialog
id="operationInspect"
onHide={onHide}
show={show}
size="modal-lg"
className={styles.modalWrapper}
onClose={onHide}
hasBackdrop
size="xxl"
title="Test details"
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Test details
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body className={styles.modalContainer}>
{loading && <LoadingBody />}
{error && <ErrorBody error={error} />}
{data && data.test_run_details && data.test_run_details.length && (
<Fragment>
<div
className={`col-md-6 ${styles.noPadd} ${styles.borderRight} ${styles.halfWidth}`}
>
<CustomCopy
key="graphql-query"
label="Query"
copy={data.test_run_details[0].query}
/>
<CustomCopy
key="session_variables"
label="Session variables"
copy={JSON.stringify(
data.test_run_details[0].user_vars,
null,
2
)}
/>
<CustomCopy
key="variables"
label="Variables"
copy={JSON.stringify(
data.test_run_details[0].variables,
null,
2
)}
/>
</div>
<div
className={`col-md-6 ${styles.noPadd} ${styles.halfWidth} ${styles.longCopy}`}
>
<CustomCopy
key="response"
label="Response"
copy={JSON.stringify(
data.test_run_details[0].response,
null,
2
)}
/>
</div>
</Fragment>
)}
</BootstrapModal.Body>
</BootstrapModal>
<div className={`p-md ${styles.modalWrapper}`}>
<div className={styles.modalContainer}>
{loading && <LoadingBody />}
{error && <ErrorBody error={error} />}
{data && data.test_run_details && data.test_run_details.length && (
<Fragment>
<div
className={`col-md-6 ${styles.noPadd} ${styles.borderRight} ${styles.halfWidth}`}
>
<CustomCopy
key="graphql-query"
label="Query"
copy={data.test_run_details[0].query}
/>
<CustomCopy
key="session_variables"
label="Session variables"
copy={JSON.stringify(
data.test_run_details[0].user_vars,
null,
2
)}
/>
<CustomCopy
key="variables"
label="Variables"
copy={JSON.stringify(
data.test_run_details[0].variables,
null,
2
)}
/>
</div>
<div
className={`col-md-6 ${styles.noPadd} ${styles.halfWidth} ${styles.longCopy}`}
>
<CustomCopy
key="response"
label="Response"
copy={JSON.stringify(
data.test_run_details[0].response,
null,
2
)}
/>
</div>
</Fragment>
)}
</div>
</div>
</Dialog>
);
};

View File

@ -1,35 +1,39 @@
import React from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { Dialog } from '@hasura/console-legacy-ce';
import styles from '../Metrics.module.scss';
import { decodeError } from './utils';
export const ErrorModal = ({ show, onHide, err }) => {
const decodedError = { ...decodeError(err) };
if (!show) return null;
return (
<BootstrapModal onHide={onHide} show={show} className={styles.modalWrapper}>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Error
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body className={styles.modalContainer}>
<div className={`col-md-12 ${styles.addPaddingBottom}`}>
<p style={{ padding: '30px 26px 5px 26px' }}>
Failed loading config:
</p>
<div className={styles.boxwrapper}>
<div className={styles.box + ' ' + styles.errorBox}>
<code className={styles.queryCode}>
<pre style={{ whitespace: 'pre-wrap' }}>
{JSON.stringify(decodedError, null, 4)}
</pre>
</code>
<Dialog
hasBackdrop
size="xxl"
id="dateModal"
onClose={onHide}
title="Error"
portal
>
<div className={styles.modalWrapper}>
<div className={styles.modalContainer}>
<div className={`col-md-12 ${styles.addPaddingBottom}`}>
<p style={{ padding: '30px 26px 5px 26px' }}>
Failed loading config:
</p>
<div className={styles.boxwrapper}>
<div className={styles.box + ' ' + styles.errorBox}>
<code className={styles.queryCode}>
<pre style={{ whitespace: 'pre-wrap' }}>
{JSON.stringify(decodedError, null, 4)}
</pre>
</code>
</div>
</div>
</div>
</div>
</BootstrapModal.Body>
</BootstrapModal>
</div>
</Dialog>
);
};

View File

@ -1,7 +1,6 @@
import React from 'react';
import BootstrapModal from 'react-bootstrap/lib/Modal';
import { Dialog } from '@hasura/console-legacy-ce';
import { Tooltip } from '@hasura/console-legacy-ce';
// import BootstrapModalButton from 'react-bootstrap/lib/Button';
import CustomCopy from '../Common/CustomCopy';
import { REFETCH_DELAY, EXECUTION_TIME_DIVIDER_CONSTANT } from './constants';
import { hideVariableValues } from '../utils';
@ -116,92 +115,86 @@ const Modal = props => {
};
return (
<BootstrapModal
<Dialog
id="operationInspect"
onHide={onHide}
show
size="modal-lg"
className={styles.modalWrapper}
onClose={onHide}
hasBackdrop
size="xxl"
title="Inspect"
>
<BootstrapModal.Header className={styles.modalHeader} closeButton>
<BootstrapModal.Title className={styles.title}>
Inspect
</BootstrapModal.Title>
</BootstrapModal.Header>
<BootstrapModal.Body
className={styles.modalContainer}
style={{ maxHeight: '986px' }}
>
<div
className={
styles.noPadd +
' col-md-6 ' +
styles.borderRight +
' ' +
styles.flexColumn
}
>
<div className={styles.infoWrapper}>
<div className={`${styles.infoField} ${styles.paddingBottom}`}>
<div className={styles.information}>
TIMESTAMP: <span>{new Date(time).toLocaleString()}</span>
<div className={styles.modalWrapper}>
<div className={styles.modalContainer}>
<div
className={
styles.noPadd +
' col-md-6 ' +
styles.borderRight +
' ' +
styles.flexColumn
}
>
<div className={styles.infoWrapper}>
<div className={`${styles.infoField} ${styles.paddingBottom}`}>
<div className={styles.information}>
TIMESTAMP: <span>{new Date(time).toLocaleString()}</span>
</div>
<div
className={
styles.information +
' ' +
styles.borderBottom +
' ' +
styles.addPaddBottom
}
>
WORKER ID: <span>{pollerId}</span>
</div>
</div>
<div
className={
styles.information +
' ' +
styles.borderBottom +
' ' +
styles.addPaddBottom
}
>
WORKER ID: <span>{pollerId}</span>
</div>
</div>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
<div className={styles.information}>
LAST EXEC. TIME:
<span className={styles.paddingLeft}>
{`${formatRoundNumber(lastExecutionTime * 1000, 2)} ms`}
</span>
{renderWarningSymbol()}
</div>
<div className={styles.information}>
REFETCH DELAY: <span>{`${refetchDelay}s`}</span>
</div>
<div className={styles.information}>
NO. OF BATCHES: <span>{executionBatchSize}</span>
</div>
<div className={styles.information}>
EACH BATCH SIZE: <span>{batchSize}</span>
</div>
<div className={`${styles.information} ${styles.borderBottom}`}>
TOTAL SUBSCRIBERS: <span>{totalSubscribers}</span>
<div className={`${styles.infoField} ${styles.noPaddingBottom}`}>
<div className={styles.information}>
LAST EXEC. TIME:
<span className={styles.paddingLeft}>
{`${formatRoundNumber(lastExecutionTime * 1000, 2)} ms`}
</span>
{renderWarningSymbol()}
</div>
<div className={styles.information}>
REFETCH DELAY: <span>{`${refetchDelay}s`}</span>
</div>
<div className={styles.information}>
NO. OF BATCHES: <span>{executionBatchSize}</span>
</div>
<div className={styles.information}>
EACH BATCH SIZE: <span>{batchSize}</span>
</div>
<div className={`${styles.information} ${styles.borderBottom}`}>
TOTAL SUBSCRIBERS: <span>{totalSubscribers}</span>
</div>
</div>
</div>
<div>{renderGeneratedSql()}</div>
</div>
<div>{renderGeneratedSql()}</div>
</div>
<div className={styles.noPadd + ' col-md-6'}>
<div className={styles.infoWrapper}>
<div className={styles.infoField} style={{ paddingBottom: 0 }}>
<div className={styles.information}>
USER ROLE: <span>{userRole}</span>
</div>
<div className={styles.information}>
OPERATION ID: <span>{operationId}</span>
</div>
<div className={`${styles.information} ${styles.borderBottom}`}>
OPERATION NAME: <span>{operationName}</span>
<div className={`overflow-auto ${styles.noPadd} col-md-6`}>
<div className={styles.infoWrapper}>
<div className={styles.infoField} style={{ paddingBottom: 0 }}>
<div className={styles.information}>
USER ROLE: <span>{userRole}</span>
</div>
<div className={styles.information}>
OPERATION ID: <span>{operationId}</span>
</div>
<div className={`${styles.information} ${styles.borderBottom}`}>
OPERATION NAME: <span>{operationName}</span>
</div>
</div>
</div>
{renderOperationString()}
{renderQueryVariables()}
{renderSessionVariables()}
</div>
{renderOperationString()}
{renderQueryVariables()}
{renderSessionVariables()}
</div>
</BootstrapModal.Body>
</BootstrapModal>
</div>
</Dialog>
);
};