diff --git a/web/package-lock.json b/web/package-lock.json index fc7a06f7f..65e32d894 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -5322,6 +5322,14 @@ } } }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -7147,6 +7155,15 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-linkify": { + "version": "1.0.0-alpha", + "resolved": "https://registry.npmjs.org/react-linkify/-/react-linkify-1.0.0-alpha.tgz", + "integrity": "sha512-7gcIUvJkAXXttt1fmBK9cwn+1jTa4hbKLGCZ9J1U6EOkyb2/+LKL1Z28d9rtDLMnpvImlNlLPdTPooorl5cpmg==", + "requires": { + "linkify-it": "^2.0.3", + "tlds": "^1.199.0" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -8726,6 +8743,11 @@ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" }, + "tlds": { + "version": "1.212.0", + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.212.0.tgz", + "integrity": "sha512-03rYYO1rGhOYpdYB+wlLY2d0xza6hdN/S67ol2ZpaH+CtFedMVAVhj8ft0rwxEkr90zatou8opBv7Xp6X4cK6g==" + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -8878,6 +8900,11 @@ "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/web/package.json b/web/package.json index 55bfd1ee6..9135e3df3 100644 --- a/web/package.json +++ b/web/package.json @@ -18,6 +18,7 @@ "prop-types": "^15.7.2", "react": "16.13.1", "react-dom": "16.13.1", + "react-linkify": "^1.0.0-alpha", "recharts": "^1.8.5", "sass": "^1.26.11" }, diff --git a/web/pages/components/chart.tsx b/web/pages/components/chart.tsx index e1680bf78..6f4c1ce39 100644 --- a/web/pages/components/chart.tsx +++ b/web/pages/components/chart.tsx @@ -9,13 +9,14 @@ interface ToolTipProps { const defaultProps = { active: false, payload: {}, + unit: "" }; interface ChartProps { - data: number, + data: [{}], color: string, unit: string, - dataCollections?: [], + dataCollections?: {}, } function CustomizedTooltip(props: ToolTipProps) { @@ -40,7 +41,7 @@ export default function Chart({ data, color, unit, dataCollections }: ChartProps }; if (dataCollections) { - var ticks = dataCollections[0]?.data.map(function (collection) { + var ticks = dataCollections?[0].data.map(function (collection) { return collection?.time; }) } else { diff --git a/web/pages/components/log-table.tsx b/web/pages/components/log-table.tsx new file mode 100644 index 000000000..5844a8a59 --- /dev/null +++ b/web/pages/components/log-table.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import { timeFormat } from "d3-time-format"; +import { Table, } from "antd"; +import Linkify from "react-linkify"; + +export default function LogTable({ logs, pageSize }) { + const columns = [ + { + title: "Level", + dataIndex: "level", + key: "level", + filters: [ + { + text: "Info", + value: "info", + }, + { + text: "Warning", + value: "warning", + }, + { + text: "Error", + value: "Error", + }, + ], + onFilter: (level, row) => row.level.indexOf(level) === 0, + render: renderColumnLevel, + }, + { + title: "Timestamp", + dataIndex: "time", + key: "time", + render: (timestamp) => + timeFormat("%H:%M:%S %m/%d/%Y")(new Date(timestamp)), + sorter: (a, b) => new Date(a.time).getTime() - new Date(b.time).getTime(), + sortDirections: ["descend", "ascend"], + defaultSortOrder: "descend", + }, + { + title: "Message", + dataIndex: "message", + key: "message", + render: renderMessage, + }, + ]; + + return ( +