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 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';
|
||||
|
||||
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 };
|
||||
|
||||
@ -85,6 +86,7 @@ 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 * from './lib/new-components/Toasts';
|
||||
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';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { hasuraToast } from '@hasura/console-legacy-ce';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
|
||||
import { EditIcon } from './EditIcon';
|
||||
@ -6,7 +7,14 @@ import { EditIcon } from './EditIcon';
|
||||
import styles from '../Metrics.module.scss';
|
||||
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 onCopy = () => {
|
||||
toggle(true);
|
||||
@ -14,17 +22,24 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
||||
};
|
||||
const renderCopyIcon = () => {
|
||||
if (isCopied) {
|
||||
// To suri modify it to have some kind of tooltip saying copied
|
||||
return (
|
||||
<div className={styles.copyIcon + ' ' + styles.copiedIcon}>
|
||||
<img
|
||||
className={styles.copyIcon + ' ' + styles.copiedIcon}
|
||||
src={copyImg}
|
||||
alt={'Copy icon'}
|
||||
/>
|
||||
<div className={styles.copiedWrapper}>Copied</div>
|
||||
</div>
|
||||
);
|
||||
if (displayAcknowledgement) {
|
||||
// To suri modify it to have some kind of tooltip saying copied
|
||||
return (
|
||||
<div className={styles.copyIcon + ' ' + styles.copiedIcon}>
|
||||
<img
|
||||
className={styles.copyIcon + ' ' + styles.copiedIcon}
|
||||
src={copyImg}
|
||||
alt={'Copy icon'}
|
||||
/>
|
||||
<div className={styles.copiedWrapper}>Copied</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
hasuraToast({
|
||||
type: 'success',
|
||||
title: 'Copied!',
|
||||
});
|
||||
}
|
||||
}
|
||||
return <img className={styles.copyIcon} src={copyImg} alt={'Copy icon'} />;
|
||||
};
|
||||
@ -32,7 +47,10 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
||||
<React.Fragment>
|
||||
<div className={styles.infoWrapper}>
|
||||
<div className={styles.information}>
|
||||
<span>{label}:</span>
|
||||
<span>
|
||||
{label}
|
||||
{displayColon ? ':' : ''}
|
||||
</span>
|
||||
<span>
|
||||
{onEdit && (
|
||||
<EditIcon
|
||||
@ -47,7 +65,12 @@ const CustomCopy = ({ label, copy, onEdit }) => {
|
||||
</div>
|
||||
</div>
|
||||
<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}>
|
||||
<pre style={{ whitespace: 'pre-wrap' }}>{copy}</pre>
|
||||
</code>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import clsx from 'clsx';
|
||||
import CustomCopy from './CustomCopy';
|
||||
import { Dialog } from '@hasura/console-legacy-ce';
|
||||
|
||||
@ -55,6 +56,22 @@ const TraceGraph = props => {
|
||||
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 { onHide, data, nullData, configData } = props;
|
||||
|
||||
@ -66,7 +83,7 @@ const Modal = props => {
|
||||
analyzeVariables = configData.analyze_query_variables;
|
||||
}
|
||||
|
||||
const renderSessonVars = () => {
|
||||
const renderSessionVars = () => {
|
||||
const { user_vars: userVars } = data;
|
||||
const userVarKeys = Object.keys(userVars);
|
||||
const sessionVariables = {};
|
||||
@ -76,12 +93,15 @@ const Modal = props => {
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={`${styles.resetInfoWrapperPadd} ${styles.alignedCustomCopy} ${styles.paddingTop}`}
|
||||
>
|
||||
<div className="rounded bg-white text-sm">
|
||||
<CustomCopy
|
||||
label="SESSION VARIABLES"
|
||||
label={
|
||||
<LabelValue className="inline-block" label="Session variables" />
|
||||
}
|
||||
copy={JSON.stringify(sessionVariables, null, 2)}
|
||||
displayColon={false}
|
||||
displayAcknowledgement={false}
|
||||
contentMaxHeight="200px"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -134,11 +154,19 @@ const Modal = props => {
|
||||
d = 'Enable response body analysis';
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={`${styles.resetInfoWrapperPadd} ${styles.alignedCustomCopy}
|
||||
}`}
|
||||
>
|
||||
<CustomCopy label="EMPTY ARRAYS & NULLS IN RESPONSE" copy={d} />
|
||||
<div className="rounded bg-white text-sm">
|
||||
<CustomCopy
|
||||
label={
|
||||
<LabelValue
|
||||
className="inline-block"
|
||||
label="Empty arrays & nulls in response"
|
||||
/>
|
||||
}
|
||||
copy={d}
|
||||
displayColon={false}
|
||||
displayAcknowledgement={false}
|
||||
contentMaxHeight="200px"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -150,7 +178,7 @@ const Modal = props => {
|
||||
const formattedError = JSON.stringify(requestError, null, 2);
|
||||
return (
|
||||
<div className={styles.boxwrapper + ' ' + styles.errorBox}>
|
||||
<div className={styles.errorMessage}>ERROR:</div>
|
||||
<LabelValue label="Error:" />
|
||||
<div className={styles.errorBox}>
|
||||
<code className={styles.queryCode}>
|
||||
<pre style={{ whitespace: 'pre-wrap' }}>{formattedError}</pre>
|
||||
@ -166,14 +194,37 @@ const Modal = props => {
|
||||
if (query) {
|
||||
const { query: graphQLQuery, variables } = query;
|
||||
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);
|
||||
if (variables && analyzeVariables) {
|
||||
try {
|
||||
const formattedVar = JSON.stringify(variables, null, 2);
|
||||
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);
|
||||
} catch (e) {
|
||||
@ -189,10 +240,17 @@ const Modal = props => {
|
||||
if (generatedSql) {
|
||||
try {
|
||||
return (
|
||||
<CustomCopy
|
||||
label={'GENERATED SQL'}
|
||||
copy={JSON.stringify(generatedSql, null, 2)}
|
||||
/>
|
||||
<div className="rounded bg-white text-sm">
|
||||
<CustomCopy
|
||||
label={
|
||||
<LabelValue className="inline-block" label="Generated SQL" />
|
||||
}
|
||||
copy={JSON.stringify(generatedSql, null, 2)}
|
||||
displayColon={false}
|
||||
displayAcknowledgement={false}
|
||||
contentMaxHeight="200px"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@ -205,7 +263,19 @@ const Modal = props => {
|
||||
if (!requestHeaders) return null;
|
||||
try {
|
||||
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) {
|
||||
console.log(e);
|
||||
}
|
||||
@ -217,154 +287,86 @@ const Modal = props => {
|
||||
onClose={onHide}
|
||||
hasBackdrop
|
||||
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
|
||||
className={`mt-2 border border-top overflow-auto ${styles.modalContainer}`}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
styles.noPadd +
|
||||
' col-md-6 ' +
|
||||
styles.borderRight +
|
||||
' ' +
|
||||
styles.flexColumn +
|
||||
' ' +
|
||||
'overflow-auto'
|
||||
<div
|
||||
className={`border border-top overflow-y-auto flex w-full text-left bg-slate-100`}
|
||||
>
|
||||
<div className="flex flex-col flex-shrink p-4 pr-2 gap-4 w-1/2">
|
||||
<LabelValue label="Request Id" value={requestId} />
|
||||
<LabelValue label="Transport" value={transport} />
|
||||
{transport === 'ws' ? (
|
||||
<>
|
||||
<LabelValue label="Websocket Id" value={websocketId} />
|
||||
<LabelValue
|
||||
label="Websocket operation Id"
|
||||
value={websocketOperationId}
|
||||
/>
|
||||
{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}>
|
||||
<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>
|
||||
) : 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>
|
||||
*/}
|
||||
/>
|
||||
<LabelValue
|
||||
label="Response size"
|
||||
value={
|
||||
(('response_size' in transformedVals &&
|
||||
transformedVals.response_size(responseSize)) ||
|
||||
responseSize) + ' kB'
|
||||
}
|
||||
/>
|
||||
{renderSessionVars()}
|
||||
<div>
|
||||
<LabelValue
|
||||
label="Execution time"
|
||||
value={
|
||||
(('execution_time' in transformedVals &&
|
||||
transformedVals.execution_time(executionTime)) ||
|
||||
executionTime) + ' ms'
|
||||
}
|
||||
/>
|
||||
<LabelValue
|
||||
label="Timing"
|
||||
value={trace && trace?.length && <TraceGraph trace={trace} />}
|
||||
/>
|
||||
</div>
|
||||
{renderError()}
|
||||
{renderResponseAnalysis()}
|
||||
</div>
|
||||
<div className="flex flex-col flex-shrink p-4 gap-4 w-1/2">
|
||||
{renderOperationQuery()}
|
||||
{renderGeneratedSql()}
|
||||
{renderRequestHeaders()}
|
||||
</div>
|
||||
</div>
|
||||
</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