mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
refactor: Update import statements for ProbeMonitor and ServerMonitor to use ProbeMonitorResponse and ServerMonitorResponse
This commit is contained in:
@@ -11,9 +11,9 @@ const reviews: Review[] = [
|
||||
title: "OneUptime is fantastic!",
|
||||
},
|
||||
{
|
||||
name: "Bob",
|
||||
text: "The incident management feature is top-notch. It has streamlined our response process significantly.",
|
||||
title: "Top-notch incident management",
|
||||
name: "Reg, Skillable",
|
||||
text: "We use OneUptime to reliably monitor endpoint availability globally, and it delivers.",
|
||||
title: "OneUptime delivers!",
|
||||
},
|
||||
{
|
||||
name: "Charlie",
|
||||
|
||||
@@ -186,8 +186,10 @@ const monitorLogs: MonitorLogsFunction = async (data: {
|
||||
query.body = new Search(logQuery.body);
|
||||
}
|
||||
|
||||
if (logQuery.severityText) {
|
||||
query.severityText = logQuery.severityText;
|
||||
if (logQuery.severityTexts && logQuery.severityTexts.length > 0) {
|
||||
query.severityText = QueryHelper.any(
|
||||
logQuery.severityTexts as Array<string>,
|
||||
);
|
||||
}
|
||||
|
||||
if (logQuery.telemetryServiceIds && logQuery.telemetryServiceIds.length > 0) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import ObjectID from "../ObjectID";
|
||||
export default interface MonitorStepLogMonitor {
|
||||
attributes: Dictionary<string | number | boolean>;
|
||||
body: string;
|
||||
severityText: Array<LogSeverity>;
|
||||
severityTexts: Array<LogSeverity>;
|
||||
telemetryServiceIds: Array<ObjectID>;
|
||||
lastXSecondsOfLogs: number;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export class MonitorStepLogMonitorUtil {
|
||||
return {
|
||||
attributes: {},
|
||||
body: "",
|
||||
severityText: [],
|
||||
severityTexts: [],
|
||||
telemetryServiceIds: [],
|
||||
lastXSecondsOfLogs: 60,
|
||||
};
|
||||
@@ -27,7 +27,7 @@ export class MonitorStepLogMonitorUtil {
|
||||
attributes:
|
||||
(json["attributes"] as Dictionary<string | number | boolean>) || {},
|
||||
body: json["body"] as string,
|
||||
severityText: json["severityText"] as Array<LogSeverity>,
|
||||
severityTexts: json["severityTexts"] as Array<LogSeverity>,
|
||||
telemetryServiceIds: ObjectID.fromJSONArray(
|
||||
json["telemetryServiceIds"] as Array<JSONObject>,
|
||||
),
|
||||
@@ -39,7 +39,7 @@ export class MonitorStepLogMonitorUtil {
|
||||
return {
|
||||
attributes: monitor.attributes,
|
||||
body: monitor.body,
|
||||
severityText: monitor.severityText,
|
||||
severityTexts: monitor.severityTexts,
|
||||
telemetryServiceId: ObjectID.toJSONArray(monitor.telemetryServiceIds),
|
||||
lastXSecondsOfLogs: monitor.lastXSecondsOfLogs,
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ export const DefaultValidateFunction: DefaultValidateFunctionType = (
|
||||
return {};
|
||||
};
|
||||
|
||||
export interface BaseComponentProps<T extends GenericObject> {
|
||||
export interface BaseComponentProps<T> {
|
||||
submitButtonStyleType?: ButtonStyleType | undefined;
|
||||
initialValues?: FormValues<T> | undefined;
|
||||
onValidate?: undefined | ((values: FormValues<T>) => JSONObject);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import LogSeverity from "Common/Types/Log/LogSeverity";
|
||||
import MonitorStepLogMonitor from "Common/Types/Monitor/MonitorStepLogMonitor";
|
||||
import FiltersForm from "CommonUI/src/Components/Filters/FiltersForm";
|
||||
import FieldType from "CommonUI/src/Components/Types/FieldType";
|
||||
import Query from "CommonUI/src/Utils/BaseDatabase/Query";
|
||||
import DropdownUtil from "CommonUI/src/Utils/Dropdown";
|
||||
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import BasicForm from "CommonUI/src/Components/Forms/BasicForm";
|
||||
import LogSeverity from "Common/Types/Log/LogSeverity";
|
||||
import DropdownUtil from "CommonUI/src/Utils/Dropdown";
|
||||
import FormFieldSchemaType from "CommonUI/src/Components/Forms/Types/FormFieldSchemaType";
|
||||
|
||||
export interface ComponentProps {
|
||||
monitorStepLogMonitor: MonitorStepLogMonitor;
|
||||
@@ -20,24 +19,24 @@ const LogMonitorStepForm: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
return (
|
||||
<FiltersForm<MonitorStepLogMonitor>
|
||||
<BasicForm
|
||||
id="logs-filter"
|
||||
showFilter={true}
|
||||
filterData={props.monitorStepLogMonitor}
|
||||
onFilterChanged={(filterData: Query<MonitorStepLogMonitor>) => {
|
||||
props.onMonitorStepLogMonitorChanged(
|
||||
filterData as MonitorStepLogMonitor,
|
||||
);
|
||||
}}
|
||||
filters={[
|
||||
hideSubmitButton={true}
|
||||
initialValue={props.monitorStepLogMonitor}
|
||||
onChange={props.onMonitorStepLogMonitorChanged}
|
||||
fields={[
|
||||
{
|
||||
key: "body",
|
||||
type: FieldType.Text,
|
||||
field: {
|
||||
body: true,
|
||||
},
|
||||
type: FormFieldSchemaType.Text,
|
||||
title: "Search Log Body",
|
||||
},
|
||||
{
|
||||
key: "lastXSecondsOfLogs",
|
||||
type: FieldType.Dropdown,
|
||||
field: {
|
||||
lastXSecondsOfLogs: true,
|
||||
},
|
||||
type: FormFieldSchemaType.Dropdown,
|
||||
filterDropdownOptions: [
|
||||
{
|
||||
label: "Last 5 seconds",
|
||||
@@ -88,16 +87,20 @@ const LogMonitorStepForm: FunctionComponent<ComponentProps> = (
|
||||
isAdvancedFilter: true,
|
||||
},
|
||||
{
|
||||
key: "severityText",
|
||||
field: {
|
||||
severityTexts: true,
|
||||
},
|
||||
filterDropdownOptions:
|
||||
DropdownUtil.getDropdownOptionsFromEnum(LogSeverity),
|
||||
type: FieldType.MultiSelectDropdown,
|
||||
type: FormFieldSchemaType.MultiSelectDropdown,
|
||||
title: "Log Severity",
|
||||
isAdvancedFilter: true,
|
||||
},
|
||||
{
|
||||
key: "telemetryServiceIds",
|
||||
type: FieldType.MultiSelectDropdown,
|
||||
field: {
|
||||
telemetryServiceIds: true,
|
||||
},
|
||||
type: FormFieldSchemaType.MultiSelectDropdown,
|
||||
filterDropdownOptions: props.telemetryServices.map(
|
||||
(telemetryService: TelemetryService) => {
|
||||
return {
|
||||
@@ -110,8 +113,10 @@ const LogMonitorStepForm: FunctionComponent<ComponentProps> = (
|
||||
isAdvancedFilter: true,
|
||||
},
|
||||
{
|
||||
key: "attributes",
|
||||
type: FieldType.JSON,
|
||||
field: {
|
||||
attributes: true,
|
||||
},
|
||||
type: FormFieldSchemaType.JSON,
|
||||
title: "Filter by Attributes",
|
||||
jsonKeys: props.attributeKeys,
|
||||
isAdvancedFilter: true,
|
||||
|
||||
@@ -16,6 +16,19 @@ import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import ComponentLoader from "CommonUI/src/Components/ComponentLoader/ComponentLoader";
|
||||
import ErrorMessage from "CommonUI/src/Components/ErrorMessage/ErrorMessage";
|
||||
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
|
||||
import ListResult from "CommonUI/src/Utils/BaseDatabase/ListResult";
|
||||
import ModelAPI from "CommonUI/src/Utils/ModelAPI/ModelAPI";
|
||||
import DashboardNavigation from "../../../Utils/Navigation";
|
||||
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
|
||||
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
|
||||
import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
|
||||
import API from "CommonUI/src/Utils/API/API";
|
||||
import Includes from "Common/Types/BaseDatabase/Includes";
|
||||
|
||||
export interface ComponentProps {
|
||||
monitorStatusOptions: Array<MonitorStatus>;
|
||||
@@ -25,138 +38,268 @@ export interface ComponentProps {
|
||||
onCallPolicyOptions: Array<OnCallDutyPolicy>;
|
||||
}
|
||||
|
||||
export interface LogMonitorStepView {
|
||||
body: string | undefined;
|
||||
severityTexts: Array<string> | undefined;
|
||||
attributes: JSONObject | undefined;
|
||||
telemetryServices: Array<TelemetryService> | undefined;
|
||||
}
|
||||
|
||||
const MonitorStepElement: FunctionComponent<ComponentProps> = (
|
||||
props: ComponentProps,
|
||||
): ReactElement => {
|
||||
const [requestDetailsFields, setRequestDetailsFields] = useState<
|
||||
Array<Field<MonitorStepType>>
|
||||
>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
const [telemetryServices, setTelemetryServices] = useState<
|
||||
Array<TelemetryService> | undefined
|
||||
>(undefined);
|
||||
|
||||
// this field is used for most monitor types
|
||||
let fields: Array<Field<MonitorStepType>> = [];
|
||||
let logFields: Array<Field<LogMonitorStepView>> = [];
|
||||
|
||||
const logMonitorDetailView: LogMonitorStepView = {
|
||||
body: undefined,
|
||||
severityTexts: undefined,
|
||||
attributes: undefined,
|
||||
telemetryServices: undefined,
|
||||
};
|
||||
|
||||
const fetchTelemetryServices: PromiseVoidFunction =
|
||||
async (): Promise<void> => {
|
||||
const telemetryServicesResult: ListResult<TelemetryService> =
|
||||
await ModelAPI.getList<TelemetryService>({
|
||||
modelType: TelemetryService,
|
||||
query: {
|
||||
projectId: DashboardNavigation.getProjectId(),
|
||||
_id: new Includes(
|
||||
props.monitorStep.data?.logMonitor?.telemetryServiceIds || [],
|
||||
),
|
||||
},
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
select: {
|
||||
_id: true,
|
||||
name: true,
|
||||
serviceColor: true,
|
||||
},
|
||||
sort: {
|
||||
name: SortOrder.Ascending,
|
||||
},
|
||||
});
|
||||
|
||||
if (telemetryServicesResult instanceof HTTPErrorResponse) {
|
||||
throw telemetryServicesResult;
|
||||
}
|
||||
|
||||
setTelemetryServices(telemetryServicesResult.data);
|
||||
};
|
||||
|
||||
const loadComponent: PromiseVoidFunction = async (): Promise<void> => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (props.monitorType === MonitorType.Logs) {
|
||||
await fetchTelemetryServices();
|
||||
}
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyErrorMessage(err as Error));
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let fields: Array<Field<MonitorStepType>> = [];
|
||||
|
||||
if (props.monitorType === MonitorType.API) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "API URL",
|
||||
description: "URL of the API you want to monitor.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestType",
|
||||
title: "Request Type",
|
||||
description: "Whats the type of the API request?",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestBody",
|
||||
title: "Request Body",
|
||||
description: "Request Body to send, if any.",
|
||||
fieldType: FieldType.JSON,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestHeaders",
|
||||
title: "Request Headers",
|
||||
description: "Request Headers to send, if any.",
|
||||
fieldType: FieldType.DictionaryOfStrings,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Website) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Website URL",
|
||||
description: "URL of the website you want to monitor.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Ping) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Ping Hostname or IP Address",
|
||||
description:
|
||||
"Hostname or IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Port) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Ping Hostname or IP Address",
|
||||
description:
|
||||
"Hostname or IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "monitorDestinationPort",
|
||||
title: "Port",
|
||||
description: "Port of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Port,
|
||||
placeholder: "No port entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.IP) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "IP Address",
|
||||
description: "IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.CustomJavaScriptCode) {
|
||||
fields = [
|
||||
{
|
||||
key: "customCode",
|
||||
title: "JavaScript Code",
|
||||
description: "JavaScript code to run.",
|
||||
fieldType: FieldType.JavaScript,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.SyntheticMonitor) {
|
||||
fields = [
|
||||
{
|
||||
key: "customCode",
|
||||
title: "JavaScript Code",
|
||||
description: "JavaScript code to run.",
|
||||
fieldType: FieldType.JavaScript,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "browserTypes",
|
||||
title: "Browser Types",
|
||||
description: "Browser types to run the synthetic monitor on.",
|
||||
fieldType: FieldType.ArrayOfText,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "screenSizeTypes",
|
||||
title: "Screen Size Types",
|
||||
description: "Screen size types to run the synthetic monitor on.",
|
||||
fieldType: FieldType.ArrayOfText,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
}
|
||||
setRequestDetailsFields(fields);
|
||||
loadComponent();
|
||||
}, [props.monitorType]);
|
||||
|
||||
if (isLoading) {
|
||||
return <ComponentLoader />;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <ErrorMessage error={error} />;
|
||||
}
|
||||
|
||||
if (props.monitorType === MonitorType.API) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "API URL",
|
||||
description: "URL of the API you want to monitor.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestType",
|
||||
title: "Request Type",
|
||||
description: "Whats the type of the API request?",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestBody",
|
||||
title: "Request Body",
|
||||
description: "Request Body to send, if any.",
|
||||
fieldType: FieldType.JSON,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "requestHeaders",
|
||||
title: "Request Headers",
|
||||
description: "Request Headers to send, if any.",
|
||||
fieldType: FieldType.DictionaryOfStrings,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Website) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Website URL",
|
||||
description: "URL of the website you want to monitor.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Ping) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Ping Hostname or IP Address",
|
||||
description:
|
||||
"Hostname or IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Port) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "Ping Hostname or IP Address",
|
||||
description:
|
||||
"Hostname or IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "monitorDestinationPort",
|
||||
title: "Port",
|
||||
description: "Port of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Port,
|
||||
placeholder: "No port entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.IP) {
|
||||
fields = [
|
||||
{
|
||||
key: "monitorDestination",
|
||||
title: "IP Address",
|
||||
description: "IP Address of the resource you would like us to ping.",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.CustomJavaScriptCode) {
|
||||
fields = [
|
||||
{
|
||||
key: "customCode",
|
||||
title: "JavaScript Code",
|
||||
description: "JavaScript code to run.",
|
||||
fieldType: FieldType.JavaScript,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.SyntheticMonitor) {
|
||||
fields = [
|
||||
{
|
||||
key: "customCode",
|
||||
title: "JavaScript Code",
|
||||
description: "JavaScript code to run.",
|
||||
fieldType: FieldType.JavaScript,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "browserTypes",
|
||||
title: "Browser Types",
|
||||
description: "Browser types to run the synthetic monitor on.",
|
||||
fieldType: FieldType.ArrayOfText,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
{
|
||||
key: "screenSizeTypes",
|
||||
title: "Screen Size Types",
|
||||
description: "Screen size types to run the synthetic monitor on.",
|
||||
fieldType: FieldType.ArrayOfText,
|
||||
placeholder: "No data entered",
|
||||
},
|
||||
];
|
||||
} else if (props.monitorType === MonitorType.Logs) {
|
||||
logFields = [];
|
||||
|
||||
if (props.monitorStep.data?.logMonitor?.body) {
|
||||
logMonitorDetailView.body = props.monitorStep.data?.logMonitor?.body;
|
||||
|
||||
logFields.push({
|
||||
key: "body",
|
||||
title: "Filter Log Message",
|
||||
description: "Filter by log message with this text:",
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "No log message entered",
|
||||
});
|
||||
}
|
||||
|
||||
if (props.monitorStep.data?.logMonitor?.severityTexts) {
|
||||
logMonitorDetailView.severityTexts =
|
||||
props.monitorStep.data?.logMonitor?.severityTexts;
|
||||
|
||||
logFields.push({
|
||||
key: "severityTexts",
|
||||
title: "Log Severity",
|
||||
description: "Severity of the logs to monitor.",
|
||||
fieldType: FieldType.ArrayOfText,
|
||||
placeholder: "No severity entered",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
props.monitorStep.data?.logMonitor?.attributes &&
|
||||
Object.keys(props.monitorStep.data?.logMonitor?.attributes).length > 0
|
||||
) {
|
||||
logMonitorDetailView.attributes =
|
||||
props.monitorStep.data?.logMonitor?.attributes;
|
||||
|
||||
logFields.push({
|
||||
key: "attributes",
|
||||
title: "Log Attributes",
|
||||
description: "Attributes of the logs to monitor.",
|
||||
fieldType: FieldType.JSON,
|
||||
placeholder: "No attributes entered",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
props.monitorStep.data?.logMonitor?.telemetryServiceIds &&
|
||||
props.monitorStep.data?.logMonitor?.telemetryServiceIds.length > 0 &&
|
||||
telemetryServices &&
|
||||
telemetryServices.length > 0
|
||||
) {
|
||||
logMonitorDetailView.telemetryServices = telemetryServices; // set the telemetry services
|
||||
|
||||
logFields.push({
|
||||
key: "telemetryServices",
|
||||
title: "Telemetry Services",
|
||||
description: "Telemetry services to monitor.",
|
||||
fieldType: FieldType.Element,
|
||||
placeholder: "No telemetry services entered",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-5">
|
||||
<FieldLabelElement
|
||||
title={"Request Details"}
|
||||
title={"Monitor Details"}
|
||||
description={
|
||||
"Here are the details of the request we will send to monitor your resource status."
|
||||
}
|
||||
@@ -164,11 +307,20 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
|
||||
isHeading={true}
|
||||
/>
|
||||
<div className="mt-5">
|
||||
<Detail
|
||||
id={"monitor-step"}
|
||||
item={props.monitorStep.data as any}
|
||||
fields={requestDetailsFields}
|
||||
/>
|
||||
{fields && fields.length && (
|
||||
<Detail<MonitorStepType>
|
||||
id={"monitor-step"}
|
||||
item={props.monitorStep.data!}
|
||||
fields={fields}
|
||||
/>
|
||||
)}
|
||||
{logFields && logFields.length && (
|
||||
<Detail<LogMonitorStepView>
|
||||
id={"monitor-logs"}
|
||||
item={logMonitorDetailView}
|
||||
fields={logFields}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<HorizontalRule />
|
||||
|
||||
Reference in New Issue
Block a user