mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
Refactor import statements and update component types in Detail.tsx, CodeEditor.tsx, and JSONFunctions.ts
This commit is contained in:
@@ -8,6 +8,64 @@ import SerializableObjectDictionary from './SerializableObjectDictionary';
|
||||
import JSON5 from 'json5';
|
||||
|
||||
export default class JSONFunctions {
|
||||
public static nestJson(obj: JSONObject): JSONObject {
|
||||
// obj could be in this format:
|
||||
|
||||
/**
|
||||
* {
|
||||
"http.url.protocol": "http",
|
||||
"http.url.hostname": "localhost",
|
||||
"http.host": "localhost",
|
||||
*/
|
||||
|
||||
// we want to convert it to this format:
|
||||
|
||||
/**
|
||||
* {
|
||||
*
|
||||
* "http": {
|
||||
* "url": {
|
||||
* "protocol": "http",
|
||||
* "hostname": "localhost"
|
||||
* },
|
||||
* "host": "localhost",
|
||||
* "method": "POST",
|
||||
* "scheme": "http",
|
||||
* "client_ip": "
|
||||
* ...
|
||||
*
|
||||
* },
|
||||
*/
|
||||
|
||||
const result: JSONObject = {};
|
||||
|
||||
for (const key in obj) {
|
||||
const keys: Array<string> = key.split('.');
|
||||
|
||||
let currentObj: JSONObject = result;
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const k: string | undefined = keys[i];
|
||||
|
||||
if (!k) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i === keys.length - 1) {
|
||||
currentObj[k] = obj[key];
|
||||
} else {
|
||||
if (!currentObj[k]) {
|
||||
currentObj[k] = {};
|
||||
}
|
||||
|
||||
currentObj = currentObj[k] as JSONObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static isEmptyObject(
|
||||
obj: JSONObject | BaseModel | null | undefined
|
||||
): boolean {
|
||||
@@ -294,6 +352,10 @@ export default class JSONFunctions {
|
||||
return newVal;
|
||||
}
|
||||
|
||||
public static toFormattedString(val: JSONValue): string {
|
||||
return JSON.stringify(val, null, 4);
|
||||
}
|
||||
|
||||
public static anyObjectToJSONObject(val: any): JSONObject {
|
||||
return JSON.parse(JSON.stringify(val));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,13 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
|
||||
const [helpText, setHelpText] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
setValue(props.value || '');
|
||||
let value: string | undefined = props.value;
|
||||
|
||||
if (value && typeof value !== 'string') {
|
||||
value = JSON.stringify(value, null, 4);
|
||||
}
|
||||
|
||||
setValue(value || '');
|
||||
}, [props.value]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,7 +85,13 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
|
||||
const [value, setValue] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
setValue(props.initialValue || '');
|
||||
let initialValue: string | undefined = props.initialValue;
|
||||
|
||||
if (initialValue && typeof initialValue !== 'string') {
|
||||
initialValue = JSON.stringify(initialValue, null, 4);
|
||||
}
|
||||
|
||||
setValue(initialValue || '');
|
||||
}, [props.initialValue]);
|
||||
|
||||
return (
|
||||
@@ -110,7 +122,7 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
|
||||
props.onBlur && props.onBlur();
|
||||
props.onChange && props.onChange(code);
|
||||
}}
|
||||
defaultValue={props.initialValue || placeholder || ''}
|
||||
defaultValue={value || placeholder || ''}
|
||||
className={className}
|
||||
options={{
|
||||
acceptSuggestionOnCommitCharacter: true,
|
||||
|
||||
@@ -348,7 +348,9 @@ const Detail: DetailFunction = <T extends GenericObject>(
|
||||
<div className={`mt-1 text-sm text-gray-900 ${alignClassName}`}>
|
||||
{data && (
|
||||
<div
|
||||
className={`${field.contentClassName} w-full flex`}
|
||||
className={`${field.contentClassName} w-full ${
|
||||
field.opts?.isCopyable ? 'flex' : ''
|
||||
}`}
|
||||
>
|
||||
<div>{data}</div>
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ import FieldType from 'CommonUI/src/Components/Types/FieldType';
|
||||
import TelemetryService from 'Model/Models/TelemetryService';
|
||||
import TelemetryServiceElement from '../TelemetryService/TelemetryServiceElement';
|
||||
import SpanUtil, { DivisibilityFactor } from '../../Utils/SpanUtil';
|
||||
import SpanStatusElement from './SpanStatusElement';
|
||||
import CodeEditor from 'CommonUI/src/Components/CodeEditor/CodeEditor';
|
||||
import CodeType from 'Common/Types/Code/CodeType';
|
||||
import JSONFunctions from 'Common/Types/JSONFunctions';
|
||||
|
||||
export interface ComponentProps {
|
||||
id: string;
|
||||
@@ -63,6 +67,7 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
|
||||
endTimeUnixNano: true,
|
||||
attributes: true,
|
||||
durationUnixNano: true,
|
||||
name: true,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -143,22 +148,51 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
|
||||
|
||||
const getAttributesContentElement: GetReactElementFunction =
|
||||
(): ReactElement => {
|
||||
return <></>;
|
||||
if (!span) {
|
||||
return <ErrorMessage error="Span not found" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Detail<Span>
|
||||
item={span}
|
||||
fields={[
|
||||
{
|
||||
key: 'attributes',
|
||||
title: 'Span Attributes',
|
||||
description: 'The attributes of the span.',
|
||||
fieldType: FieldType.Element,
|
||||
getElement: (span: Span) => {
|
||||
return (
|
||||
<CodeEditor
|
||||
type={CodeType.JSON}
|
||||
initialValue={JSONFunctions.toFormattedString(
|
||||
JSONFunctions.nestJson(
|
||||
span.attributes || {}
|
||||
)
|
||||
)}
|
||||
readOnly={true}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getEventsContentElement: GetReactElementFunction =
|
||||
(): ReactElement => {
|
||||
return <></>;
|
||||
return <div>Coming Soon</div>;
|
||||
};
|
||||
|
||||
const getErrorsContentElement: GetReactElementFunction =
|
||||
(): ReactElement => {
|
||||
return <></>;
|
||||
return <div>Coming Soon</div>;
|
||||
};
|
||||
|
||||
const getBasicInfo: GetReactElementFunction = (): ReactElement => {
|
||||
if (!span) {
|
||||
return <></>;
|
||||
return <ErrorMessage error="Span not found" />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -174,6 +208,33 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
|
||||
isCopyable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'name',
|
||||
title: 'Span Name',
|
||||
description: 'The name of the span.',
|
||||
fieldType: FieldType.Text,
|
||||
},
|
||||
{
|
||||
key: 'statusCode',
|
||||
title: 'Span Status',
|
||||
description: 'The status of the span.',
|
||||
fieldType: FieldType.Element,
|
||||
getElement: (span: Span) => {
|
||||
return (
|
||||
<div>
|
||||
<SpanStatusElement
|
||||
span={span}
|
||||
title={
|
||||
'Status: ' +
|
||||
SpanUtil.getSpanStatusCodeFriendlyName(
|
||||
span.statusCode!
|
||||
)
|
||||
}
|
||||
/>{' '}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'traceId',
|
||||
title: 'Trace ID',
|
||||
@@ -273,7 +334,16 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
|
||||
key: 'kind',
|
||||
title: 'Span Kind',
|
||||
description: 'The kind of span.',
|
||||
fieldType: FieldType.Text,
|
||||
fieldType: FieldType.Element,
|
||||
getElement: (span: Span) => {
|
||||
return (
|
||||
<div>
|
||||
{SpanUtil.getSpanKindFriendlyName(
|
||||
span.kind!
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user