diff --git a/Common/UI/Components/CodeBlock/CodeBlock.tsx b/Common/UI/Components/CodeBlock/CodeBlock.tsx index 44350994b6..e67b697113 100644 --- a/Common/UI/Components/CodeBlock/CodeBlock.tsx +++ b/Common/UI/Components/CodeBlock/CodeBlock.tsx @@ -1,19 +1,62 @@ import "highlight.js/styles/a11y-dark.css"; -import React, { FunctionComponent, ReactElement } from "react"; +import React, { FunctionComponent, ReactElement, useState } from "react"; import Highlight from "react-highlight"; +import Icon from "../Icon/Icon"; +import IconProp from "../../../Types/Icon/IconProp"; export interface ComponentProps { code: string | ReactElement; language: string; + maxHeight?: string | undefined; + showCopyButton?: boolean | undefined; } const CodeBlock: FunctionComponent = ( props: ComponentProps, ): ReactElement => { + const [copied, setCopied] = useState(false); + + const handleCopy: () => void = (): void => { + if (typeof props.code === "string") { + navigator.clipboard.writeText(props.code).catch(() => { + /* ignore clipboard errors */ + }); + setCopied(true); + setTimeout(() => { + setCopied(false); + }, 2000); + } + }; + + const maxHeight: string = props.maxHeight || "500px"; + const showCopyButton: boolean = props.showCopyButton !== false; + return ( - - {props.code} - +
+ {showCopyButton && typeof props.code === "string" && ( + + )} +
+ + {props.code} + +
+
); }; diff --git a/Common/UI/Components/Detail/Detail.tsx b/Common/UI/Components/Detail/Detail.tsx index 87c3f44927..840caf76dc 100644 --- a/Common/UI/Components/Detail/Detail.tsx +++ b/Common/UI/Components/Detail/Detail.tsx @@ -1,6 +1,6 @@ import AlignItem from "../../Types/AlignItem"; import { Logger } from "../../Utils/Logger"; -import CodeEditor from "../CodeEditor/CodeEditor"; +import CodeBlock from "../CodeBlock/CodeBlock"; import ColorViewer from "../ColorViewer/ColorViewer"; import CopyableButton from "../CopyableButton/CopyableButton"; import DictionaryOfStringsViewer from "../Dictionary/DictionaryOfStingsViewer"; @@ -12,7 +12,6 @@ import Field from "./Field"; import FieldLabelElement from "./FieldLabel"; import PlaceholderText from "./PlaceholderText"; import FileModel from "../../../Models/DatabaseModels/DatabaseBaseModel/FileModel"; -import CodeType from "../../../Types/Code/CodeType"; import Color from "../../../Types/Color"; import DatabaseProperty from "../../../Types/Database/DatabaseProperty"; import OneUptimeDate from "../../../Types/Date"; @@ -101,8 +100,18 @@ const Detail: DetailFunction = ( return ( - - + + {selectedOption.label as string} @@ -141,10 +150,22 @@ const Detail: DetailFunction = ( return (
- - + + - ${formattedAmount} + + ${formattedAmount} + USD @@ -163,8 +184,18 @@ const Detail: DetailFunction = ( return (
- - + + {minutes} @@ -211,14 +242,25 @@ const Detail: DetailFunction = ( if (field.fieldType === FieldType.Date) { if (data) { - const formattedDate: string = OneUptimeDate.getDateAsUserFriendlyLocalFormattedString( - data as string, - true, - ); + const formattedDate: string = + OneUptimeDate.getDateAsUserFriendlyLocalFormattedString( + data as string, + true, + ); data = ( - - + + {formattedDate} @@ -248,14 +290,25 @@ const Detail: DetailFunction = ( if (field.fieldType === FieldType.DateTime) { if (data) { - const formattedDateTime: string = OneUptimeDate.getDateAsUserFriendlyLocalFormattedString( - data as string, - false, - ); + const formattedDateTime: string = + OneUptimeDate.getDateAsUserFriendlyLocalFormattedString( + data as string, + false, + ); data = ( - - + + {formattedDateTime} @@ -382,14 +435,14 @@ const Detail: DetailFunction = ( field.fieldType === FieldType.JavaScript || field.fieldType === FieldType.Code) ) { - let codeType: CodeType = CodeType.HTML; + let language: string = "html"; if (field.fieldType === FieldType.CSS) { - codeType = CodeType.CSS; + language = "css"; } if (field.fieldType === FieldType.JSON) { - codeType = CodeType.JSON; + language = "json"; //make sure json is well formatted. @@ -411,18 +464,18 @@ const Detail: DetailFunction = ( } if (field.fieldType === FieldType.JavaScript) { - codeType = CodeType.JavaScript; + language = "javascript"; } if (field.fieldType === FieldType.Code) { - codeType = CodeType.Text; + language = "plaintext"; } data = ( - ); } @@ -461,7 +514,8 @@ const Detail: DetailFunction = ( "group transition-all duration-200 ease-in-out"; if (isCardStyle) { - containerClasses += " bg-gradient-to-br from-white to-gray-50/50 rounded-xl border border-gray-100 p-4 shadow-sm hover:shadow-md hover:border-gray-200"; + containerClasses += + " bg-gradient-to-br from-white to-gray-50/50 rounded-xl border border-gray-100 p-4 shadow-sm hover:shadow-md hover:border-gray-200"; } else if (isMinimalStyle) { containerClasses += " py-3 first:pt-0 last:pb-0 border-b border-gray-50 last:border-b-0 hover:bg-gray-50/50 px-2 -mx-2 rounded-lg";