diff --git a/airflow/www/static/js/api/useGridData.test.ts b/airflow/www/static/js/api/useGridData.test.ts
index 929303efe1f5d..3e83e29ee56a2 100644
--- a/airflow/www/static/js/api/useGridData.test.ts
+++ b/airflow/www/static/js/api/useGridData.test.ts
@@ -34,7 +34,6 @@ const commonDagRunParams = {
lastSchedulingDecision: null,
externalTrigger: false,
conf: null,
- confIsJson: false,
note: "",
};
diff --git a/airflow/www/static/js/components/RenderedJsonField.tsx b/airflow/www/static/js/components/RenderedJsonField.tsx
new file mode 100644
index 0000000000000..518f6b9fd82df
--- /dev/null
+++ b/airflow/www/static/js/components/RenderedJsonField.tsx
@@ -0,0 +1,70 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from "react";
+
+import ReactJson from "react-json-view";
+
+import { Flex, Button, Code, Spacer, useClipboard } from "@chakra-ui/react";
+
+interface Props {
+ content: string;
+}
+
+const JsonParse = (content: string) => {
+ let contentJson = null;
+ let contentFormatted = "";
+ let isJson = false;
+ try {
+ contentJson = JSON.parse(content);
+ contentFormatted = JSON.stringify(contentJson, null, 4);
+ isJson = true;
+ } catch (e) {
+ // skip
+ }
+ return [isJson, contentJson, contentFormatted];
+};
+
+const RenderedJsonField = ({ content }: Props) => {
+ const [isJson, contentJson, contentFormatted] = JsonParse(content);
+ const { onCopy, hasCopied } = useClipboard(contentFormatted);
+
+ return isJson ? (
+ {content}
+ );
+};
+
+export default RenderedJsonField;
diff --git a/airflow/www/static/js/dag/details/dagRun/Details.tsx b/airflow/www/static/js/dag/details/dagRun/Details.tsx
index c769da72d5c4f..317cbd99f2a32 100644
--- a/airflow/www/static/js/dag/details/dagRun/Details.tsx
+++ b/airflow/www/static/js/dag/details/dagRun/Details.tsx
@@ -16,21 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { useEffect } from "react";
-import {
- Flex,
- Box,
- Button,
- Spacer,
- Table,
- Tbody,
- Tr,
- Td,
- useClipboard,
- Text,
-} from "@chakra-ui/react";
-
-import ReactJson from "react-json-view";
+import React from "react";
+import { Flex, Box, Table, Tbody, Tr, Td, Text } from "@chakra-ui/react";
import type { DagRun as DagRunType } from "src/types";
import { SimpleStatus } from "src/dag/StatusBox";
@@ -38,25 +25,13 @@ import { ClipboardText } from "src/components/Clipboard";
import { formatDuration, getDuration } from "src/datetime_utils";
import Time from "src/components/Time";
import RunTypeIcon from "src/components/RunTypeIcon";
+import RenderedJsonField from "src/components/RenderedJsonField";
interface Props {
run: DagRunType;
}
-const formatConf = (conf: string | null | undefined): string => {
- if (!conf) {
- return "";
- }
- return JSON.stringify(JSON.parse(conf), null, 4);
-};
-
const DagRunDetails = ({ run }: Props) => {
- const { onCopy, setValue, hasCopied } = useClipboard(formatConf(run?.conf));
-
- useEffect(() => {
- setValue(formatConf(run?.conf));
- }, [run, setValue]);
-
if (!run) return null;
const {
state,
@@ -69,7 +44,6 @@ const DagRunDetails = ({ run }: Props) => {
queuedAt,
externalTrigger,
conf,
- confIsJson,
} = run;
return (
@@ -161,28 +135,9 @@ const DagRunDetails = ({ run }: Props) => {
| {key} |
- {field as string}
+ |