mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
console: fix operation details modal layout
[DSF-424]: https://hasurahq.atlassian.net/browse/DSF-424?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9495 GitOrigin-RevId: 561bb3060c7b31bafa7f9a5be8e3fe08f7462f16
This commit is contained in:
parent
3124c93673
commit
92f244f9cc
@ -1,3 +1,7 @@
|
|||||||
|
import CommonScss from './lib/components/Common/Common.module.scss';
|
||||||
|
import filterQueryScss from './lib/components/Common/FilterQuery/FilterQuery.module.scss';
|
||||||
|
import tableScss from './lib/components/Common/TableCommon/Table.module.scss';
|
||||||
|
|
||||||
import DragFoldTable from './lib/components/Common/TableCommon/DragFoldTable';
|
import DragFoldTable from './lib/components/Common/TableCommon/DragFoldTable';
|
||||||
|
|
||||||
import Editor from './lib/components/Common/Layout/ExpandableEditor/Editor';
|
import Editor from './lib/components/Common/Layout/ExpandableEditor/Editor';
|
||||||
@ -13,9 +17,6 @@ import * as EndpointNamedExps from './lib/Endpoints';
|
|||||||
import * as ControlPlane from './lib/features/ControlPlane';
|
import * as ControlPlane from './lib/features/ControlPlane';
|
||||||
|
|
||||||
export * from './lib/utils/console-dev-tools';
|
export * from './lib/utils/console-dev-tools';
|
||||||
const CommonScss = require('./lib/components/Common/Common.module.scss');
|
|
||||||
const filterQueryScss = require('./lib/components/Common/FilterQuery/FilterQuery.module.scss');
|
|
||||||
const tableScss = require('./lib/components/Common/TableCommon/Table.module.scss');
|
|
||||||
|
|
||||||
export { ControlPlane };
|
export { ControlPlane };
|
||||||
|
|
||||||
@ -85,6 +86,7 @@ export * from './lib/new-components/Button/';
|
|||||||
export * from './lib/new-components/Tooltip/';
|
export * from './lib/new-components/Tooltip/';
|
||||||
export * from './lib/new-components/Badge/';
|
export * from './lib/new-components/Badge/';
|
||||||
export * from './lib/new-components/Dialog';
|
export * from './lib/new-components/Dialog';
|
||||||
|
export * from './lib/new-components/Toasts';
|
||||||
export { default as dataHeaders } from './lib/components/Services/Data/Common/Headers';
|
export { default as dataHeaders } from './lib/components/Services/Data/Common/Headers';
|
||||||
export { handleMigrationErrors } from './lib/components/Services/Data/TableModify/ModifyActions';
|
export { handleMigrationErrors } from './lib/components/Services/Data/TableModify/ModifyActions';
|
||||||
export { loadMigrationStatus } from './lib/components/Main/Actions';
|
export { loadMigrationStatus } from './lib/components/Main/Actions';
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { hasuraToast } from '@hasura/console-legacy-ce';
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
|
|
||||||
import { EditIcon } from './EditIcon';
|
import { EditIcon } from './EditIcon';
|
||||||
@ -6,7 +7,14 @@ import { EditIcon } from './EditIcon';
|
|||||||
import styles from '../Metrics.module.scss';
|
import styles from '../Metrics.module.scss';
|
||||||
import copyImg from '../images/copy.svg';
|
import copyImg from '../images/copy.svg';
|
||||||
|
|
||||||
const CustomCopy = ({ label, copy, onEdit }) => {
|
const CustomCopy = ({
|
||||||
|
label,
|
||||||
|
copy,
|
||||||
|
onEdit,
|
||||||
|
displayColon = true,
|
||||||
|
displayAcknowledgement = true,
|
||||||
|
contentMaxHeight,
|
||||||
|
}) => {
|
||||||
const [isCopied, toggle] = useState(false);
|
const [isCopied, toggle] = useState(false);
|
||||||
const onCopy = () => {
|
const onCopy = () => {
|
||||||
toggle(true);
|
toggle(true);
|
||||||
@ -14,17 +22,24 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
|||||||
};
|
};
|
||||||
const renderCopyIcon = () => {
|
const renderCopyIcon = () => {
|
||||||
if (isCopied) {
|
if (isCopied) {
|
||||||
// To suri modify it to have some kind of tooltip saying copied
|
if (displayAcknowledgement) {
|
||||||
return (
|
// To suri modify it to have some kind of tooltip saying copied
|
||||||
<div className={styles.copyIcon + ' ' + styles.copiedIcon}>
|
return (
|
||||||
<img
|
<div className={styles.copyIcon + ' ' + styles.copiedIcon}>
|
||||||
className={styles.copyIcon + ' ' + styles.copiedIcon}
|
<img
|
||||||
src={copyImg}
|
className={styles.copyIcon + ' ' + styles.copiedIcon}
|
||||||
alt={'Copy icon'}
|
src={copyImg}
|
||||||
/>
|
alt={'Copy icon'}
|
||||||
<div className={styles.copiedWrapper}>Copied</div>
|
/>
|
||||||
</div>
|
<div className={styles.copiedWrapper}>Copied</div>
|
||||||
);
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
hasuraToast({
|
||||||
|
type: 'success',
|
||||||
|
title: 'Copied!',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return <img className={styles.copyIcon} src={copyImg} alt={'Copy icon'} />;
|
return <img className={styles.copyIcon} src={copyImg} alt={'Copy icon'} />;
|
||||||
};
|
};
|
||||||
@ -32,7 +47,10 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
|||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className={styles.infoWrapper}>
|
<div className={styles.infoWrapper}>
|
||||||
<div className={styles.information}>
|
<div className={styles.information}>
|
||||||
<span>{label}:</span>
|
<span>
|
||||||
|
{label}
|
||||||
|
{displayColon ? ':' : ''}
|
||||||
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{onEdit && (
|
{onEdit && (
|
||||||
<EditIcon
|
<EditIcon
|
||||||
@ -47,7 +65,12 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
||||||
<div className={`p-xs overflow-auto ${styles.box}`}>
|
<div
|
||||||
|
className={`p-xs overflow-auto ${styles.box}`}
|
||||||
|
style={{
|
||||||
|
...(contentMaxHeight ? { maxHeight: contentMaxHeight } : {}),
|
||||||
|
}}
|
||||||
|
>
|
||||||
<code className={styles.queryCode}>
|
<code className={styles.queryCode}>
|
||||||
<pre style={{ whitespace: 'pre-wrap' }}>{copy}</pre>
|
<pre style={{ whitespace: 'pre-wrap' }}>{copy}</pre>
|
||||||
</code>
|
</code>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import clsx from 'clsx';
|
||||||
import CustomCopy from './CustomCopy';
|
import CustomCopy from './CustomCopy';
|
||||||
import { Dialog } from '@hasura/console-legacy-ce';
|
import { Dialog } from '@hasura/console-legacy-ce';
|
||||||
|
|
||||||
@ -55,6 +56,22 @@ const TraceGraph = props => {
|
|||||||
return root ? <FlameGraph data={root} height={200} width={375} /> : null;
|
return root ? <FlameGraph data={root} height={200} width={375} /> : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LabelValue = props => {
|
||||||
|
const { label, value, className } = props;
|
||||||
|
return (
|
||||||
|
<div className={className}>
|
||||||
|
<div className={clsx('bg-white rounded p-2', className)}>
|
||||||
|
<div className="text-slate-500 text-base mr-1 whitespace-nowrap">
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>{value}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Modal = props => {
|
const Modal = props => {
|
||||||
const { onHide, data, nullData, configData } = props;
|
const { onHide, data, nullData, configData } = props;
|
||||||
|
|
||||||
@ -66,7 +83,7 @@ const Modal = props => {
|
|||||||
analyzeVariables = configData.analyze_query_variables;
|
analyzeVariables = configData.analyze_query_variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderSessonVars = () => {
|
const renderSessionVars = () => {
|
||||||
const { user_vars: userVars } = data;
|
const { user_vars: userVars } = data;
|
||||||
const userVarKeys = Object.keys(userVars);
|
const userVarKeys = Object.keys(userVars);
|
||||||
const sessionVariables = {};
|
const sessionVariables = {};
|
||||||
@ -76,12 +93,15 @@ const Modal = props => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="rounded bg-white text-sm">
|
||||||
className={`${styles.resetInfoWrapperPadd} ${styles.alignedCustomCopy} ${styles.paddingTop}`}
|
|
||||||
>
|
|
||||||
<CustomCopy
|
<CustomCopy
|
||||||
label="SESSION VARIABLES"
|
label={
|
||||||
|
<LabelValue className="inline-block" label="Session variables" />
|
||||||
|
}
|
||||||
copy={JSON.stringify(sessionVariables, null, 2)}
|
copy={JSON.stringify(sessionVariables, null, 2)}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -134,11 +154,19 @@ const Modal = props => {
|
|||||||
d = 'Enable response body analysis';
|
d = 'Enable response body analysis';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="rounded bg-white text-sm">
|
||||||
className={`${styles.resetInfoWrapperPadd} ${styles.alignedCustomCopy}
|
<CustomCopy
|
||||||
}`}
|
label={
|
||||||
>
|
<LabelValue
|
||||||
<CustomCopy label="EMPTY ARRAYS & NULLS IN RESPONSE" copy={d} />
|
className="inline-block"
|
||||||
|
label="Empty arrays & nulls in response"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
copy={d}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -150,7 +178,7 @@ const Modal = props => {
|
|||||||
const formattedError = JSON.stringify(requestError, null, 2);
|
const formattedError = JSON.stringify(requestError, null, 2);
|
||||||
return (
|
return (
|
||||||
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
||||||
<div className={styles.errorMessage}>ERROR:</div>
|
<LabelValue label="Error:" />
|
||||||
<div className={styles.errorBox}>
|
<div className={styles.errorBox}>
|
||||||
<code className={styles.queryCode}>
|
<code className={styles.queryCode}>
|
||||||
<pre style={{ whitespace: 'pre-wrap' }}>{formattedError}</pre>
|
<pre style={{ whitespace: 'pre-wrap' }}>{formattedError}</pre>
|
||||||
@ -166,14 +194,37 @@ const Modal = props => {
|
|||||||
if (query) {
|
if (query) {
|
||||||
const { query: graphQLQuery, variables } = query;
|
const { query: graphQLQuery, variables } = query;
|
||||||
const queryElement = (
|
const queryElement = (
|
||||||
<CustomCopy label={'OPERATION STRING'} copy={graphQLQuery} />
|
<div className="rounded bg-white text-sm">
|
||||||
|
<CustomCopy
|
||||||
|
label={
|
||||||
|
<LabelValue className="inline-block" label="Operation string" />
|
||||||
|
}
|
||||||
|
copy={graphQLQuery}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
renderItem.push(queryElement);
|
renderItem.push(queryElement);
|
||||||
if (variables && analyzeVariables) {
|
if (variables && analyzeVariables) {
|
||||||
try {
|
try {
|
||||||
const formattedVar = JSON.stringify(variables, null, 2);
|
const formattedVar = JSON.stringify(variables, null, 2);
|
||||||
const variablesElement = [
|
const variablesElement = [
|
||||||
<CustomCopy label={'QUERY VARIABLES'} copy={formattedVar} />,
|
<div className="rounded bg-white text-sm">
|
||||||
|
<CustomCopy
|
||||||
|
label={
|
||||||
|
<LabelValue
|
||||||
|
className="inline-block"
|
||||||
|
label="Query variables"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
copy={formattedVar}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>,
|
||||||
];
|
];
|
||||||
renderItem.push(variablesElement);
|
renderItem.push(variablesElement);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -189,10 +240,17 @@ const Modal = props => {
|
|||||||
if (generatedSql) {
|
if (generatedSql) {
|
||||||
try {
|
try {
|
||||||
return (
|
return (
|
||||||
<CustomCopy
|
<div className="rounded bg-white text-sm">
|
||||||
label={'GENERATED SQL'}
|
<CustomCopy
|
||||||
copy={JSON.stringify(generatedSql, null, 2)}
|
label={
|
||||||
/>
|
<LabelValue className="inline-block" label="Generated SQL" />
|
||||||
|
}
|
||||||
|
copy={JSON.stringify(generatedSql, null, 2)}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@ -205,7 +263,19 @@ const Modal = props => {
|
|||||||
if (!requestHeaders) return null;
|
if (!requestHeaders) return null;
|
||||||
try {
|
try {
|
||||||
const stringified = JSON.stringify(requestHeaders, null, 2);
|
const stringified = JSON.stringify(requestHeaders, null, 2);
|
||||||
return <CustomCopy label="REQUEST HEADERS" copy={stringified} />;
|
return (
|
||||||
|
<div className="rounded bg-white text-sm">
|
||||||
|
<CustomCopy
|
||||||
|
label={
|
||||||
|
<LabelValue className="inline-block" label="Request headers:" />
|
||||||
|
}
|
||||||
|
copy={stringified}
|
||||||
|
displayColon={false}
|
||||||
|
displayAcknowledgement={false}
|
||||||
|
contentMaxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
@ -217,154 +287,86 @@ const Modal = props => {
|
|||||||
onClose={onHide}
|
onClose={onHide}
|
||||||
hasBackdrop
|
hasBackdrop
|
||||||
size="xxxl"
|
size="xxxl"
|
||||||
title="Inspect"
|
title={
|
||||||
|
<div className="font-normal text-slate-900 flex gap-2 text-left w-full">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span className="text-slate-500">Operation </span>
|
||||||
|
<strong>{operationName || 'N/A'}</strong>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm">
|
||||||
|
<span className="text-slate-500">Id </span>
|
||||||
|
{operationId || 'N/A'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-base flex-grow text-right pr-6 pt-2">
|
||||||
|
<LabelValue
|
||||||
|
label="Timestamp:"
|
||||||
|
value={new Date(time).toLocaleString()}
|
||||||
|
className="bg-transparent flex justify-end"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className={styles.modalWrapper}>
|
<div
|
||||||
<div
|
className={`border border-top overflow-y-auto flex w-full text-left bg-slate-100`}
|
||||||
className={`mt-2 border border-top overflow-auto ${styles.modalContainer}`}
|
>
|
||||||
>
|
<div className="flex flex-col flex-shrink p-4 pr-2 gap-4 w-1/2">
|
||||||
<div
|
<LabelValue label="Request Id" value={requestId} />
|
||||||
className={
|
<LabelValue label="Transport" value={transport} />
|
||||||
styles.noPadd +
|
{transport === 'ws' ? (
|
||||||
' col-md-6 ' +
|
<>
|
||||||
styles.borderRight +
|
<LabelValue label="Websocket Id" value={websocketId} />
|
||||||
' ' +
|
<LabelValue
|
||||||
styles.flexColumn +
|
label="Websocket operation Id"
|
||||||
' ' +
|
value={websocketOperationId}
|
||||||
'overflow-auto'
|
/>
|
||||||
|
{operationType === 'subscription' ? (
|
||||||
|
<LabelValue label="Subscription status" value={status} />
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
<LabelValue label="Client name" value={role || 'N/A'} />
|
||||||
|
<LabelValue label="Role" value={client_name || 'N/A'} />
|
||||||
|
<LabelValue
|
||||||
|
label="Request size"
|
||||||
|
value={
|
||||||
|
((transformedVals.hasOwnProperty('request_size') &&
|
||||||
|
transformedVals.request_size(requestSize)) ||
|
||||||
|
requestSize) + ' kB'
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<div className={styles.infoWrapper}>
|
<LabelValue
|
||||||
<div className={`${styles.infoField} ${styles.paddingBottom}`}>
|
label="Response size"
|
||||||
<div className={styles.information}>
|
value={
|
||||||
TIMESTAMP: <span>{new Date(time).toLocaleString()}</span>
|
(('response_size' in transformedVals &&
|
||||||
</div>
|
transformedVals.response_size(responseSize)) ||
|
||||||
{/*
|
responseSize) + ' kB'
|
||||||
<div className={styles.information}>
|
}
|
||||||
ID: <span>{id}</span>
|
/>
|
||||||
</div>
|
{renderSessionVars()}
|
||||||
*/}
|
<div>
|
||||||
<div className={styles.information}>
|
<LabelValue
|
||||||
OPERATION NAME: <span>{operationName || 'N/A'}</span>
|
label="Execution time"
|
||||||
</div>
|
value={
|
||||||
<div className={styles.information}>
|
(('execution_time' in transformedVals &&
|
||||||
OPERATION ID: <span>{operationId || 'N/A'}</span>
|
transformedVals.execution_time(executionTime)) ||
|
||||||
</div>
|
executionTime) + ' ms'
|
||||||
<div className={styles.information}>
|
}
|
||||||
REQUEST ID: <span>{requestId}</span>
|
/>
|
||||||
</div>
|
<LabelValue
|
||||||
<div
|
label="Timing"
|
||||||
className={
|
value={trace && trace?.length && <TraceGraph trace={trace} />}
|
||||||
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>
|
|
||||||
</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>
|
|
||||||
<div className={`overflow-auto ${styles.noPadd} col-md-6`}>
|
|
||||||
{renderOperationQuery()}
|
|
||||||
{renderGeneratedSql()}
|
|
||||||
{renderRequestHeaders()}
|
|
||||||
{/*
|
|
||||||
<div className={styles.infoWrapper}>
|
|
||||||
<div className={styles.information}>
|
|
||||||
GENERATED SQL:{' '}
|
|
||||||
<button className={styles.analyzeBtn}>ANALYZE</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
|
||||||
<div className={styles.box} />
|
|
||||||
</div>
|
|
||||||
*/}
|
|
||||||
</div>
|
</div>
|
||||||
|
{renderError()}
|
||||||
|
{renderResponseAnalysis()}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col flex-shrink p-4 gap-4 w-1/2">
|
||||||
|
{renderOperationQuery()}
|
||||||
|
{renderGeneratedSql()}
|
||||||
|
{renderRequestHeaders()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { StoryObj, Meta } from '@storybook/react';
|
||||||
|
import { action } from '@storybook/addon-actions';
|
||||||
|
|
||||||
|
import Modal from './Modal';
|
||||||
|
|
||||||
|
const DATA = {
|
||||||
|
operation: {
|
||||||
|
time: '2023-06-07T12:11:01.134+00:00',
|
||||||
|
request_id: 'f09cde5e9616177f77d61c78479ed633',
|
||||||
|
operation_id: '7116865cef017c3b09e5c9271b0e182a6dcf4c01',
|
||||||
|
operation_name: 'IntrospectionQuery',
|
||||||
|
client_name: null,
|
||||||
|
user_role: 'admin',
|
||||||
|
execution_time: 0.004819542,
|
||||||
|
request_size: 1728,
|
||||||
|
response_size: 1152,
|
||||||
|
error: null,
|
||||||
|
query: {
|
||||||
|
query:
|
||||||
|
'\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n ',
|
||||||
|
variables: {
|
||||||
|
review: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user_vars: {
|
||||||
|
'x-hasura-role': 'admin',
|
||||||
|
},
|
||||||
|
transport: 'ws',
|
||||||
|
|
||||||
|
request_headers: {
|
||||||
|
Accept: '*/*',
|
||||||
|
'Accept-Encoding': 'gzip, deflate',
|
||||||
|
'Accept-Language': 'en',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
Connection: 'close',
|
||||||
|
'Content-Length': '1728',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Host: 'tenant1.nginx.hasura.me',
|
||||||
|
Origin: 'http://cloud.lux-dev.hasura.me',
|
||||||
|
Pragma: 'no-cache',
|
||||||
|
Referer: 'http://cloud.lux-dev.hasura.me/',
|
||||||
|
'User-Agent':
|
||||||
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
|
||||||
|
'X-Forwarded-Host': 'tenant1.nginx.hasura.me',
|
||||||
|
'X-Forwarded-Port': '80',
|
||||||
|
'X-Forwarded-Proto': 'http',
|
||||||
|
'X-Forwarded-Server': 'ccced495ab5e',
|
||||||
|
'X-NginX-Proxy': 'true',
|
||||||
|
'X-Request-Id': 'f09cde5e9616177f77d61c78479ed633',
|
||||||
|
},
|
||||||
|
websocket_id: 'c0cjsdf09cde5e9616177f77d61c78479ed3',
|
||||||
|
ws_operation_id: 'c1984fgb9cde5616177f77d61c78479ed3',
|
||||||
|
kind: null,
|
||||||
|
request_mode: 'single',
|
||||||
|
generated_sql: 'SELECT * FROM public.author',
|
||||||
|
trace: [
|
||||||
|
{
|
||||||
|
id: '429793da-9c7d-450e-9a9d-d50283b446ca',
|
||||||
|
name: '/v1/graphql',
|
||||||
|
parent_id: null,
|
||||||
|
span_id: '7903618144220886803',
|
||||||
|
time: '2023-06-07T15:14:02.774+00:00',
|
||||||
|
duration: 3398250,
|
||||||
|
start: '2023-06-07T15:14:02.878461+00:00',
|
||||||
|
meta: {
|
||||||
|
request_id: '05e83aff90e604b68cd6daa311105f78',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'a1c38f1d-bd74-4660-a849-0a1e4924ebe9',
|
||||||
|
name: 'Query',
|
||||||
|
parent_id: '7903618144220886803',
|
||||||
|
span_id: '2425353977187282560',
|
||||||
|
time: '2023-06-07T15:14:02.774+00:00',
|
||||||
|
duration: 49791,
|
||||||
|
start: '2023-06-07T15:14:02.881081+00:00',
|
||||||
|
meta: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: Modal,
|
||||||
|
} as Meta<typeof Modal>;
|
||||||
|
|
||||||
|
export const Basic: StoryObj<typeof Modal> = {
|
||||||
|
args: {
|
||||||
|
data: DATA.operation,
|
||||||
|
configData: {},
|
||||||
|
onHide: action('onHide'),
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user