From f71d30ca8304cbf29eec17ee203af72410685d8e Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Wed, 12 Apr 2023 14:50:33 +0100 Subject: [PATCH] Re-implement frame and event download option. --- ui/package.json | 1 + ui/src/components/LogTable.tsx | 37 +++++++++++++++++++++++++--------- ui/src/index.css | 8 ++++++++ ui/yarn.lock | 7 ++++++- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/ui/package.json b/ui/package.json index da47054f..507fe950 100644 --- a/ui/package.json +++ b/ui/package.json @@ -28,6 +28,7 @@ "codemirror": "^5.65.3", "google-protobuf": "^3.21.2", "grpc-web": "^1.4.2", + "js-file-download": "^0.4.12", "leaflet": "^1.7.1", "leaflet.awesome-markers": "^2.0.5", "react": "^17.0.2", diff --git a/ui/src/components/LogTable.tsx b/ui/src/components/LogTable.tsx index e5fcaf54..3a663e9e 100644 --- a/ui/src/components/LogTable.tsx +++ b/ui/src/components/LogTable.tsx @@ -1,8 +1,9 @@ import React, { Component } from "react"; import moment from "moment"; import JSONTreeOriginal from "react-json-tree"; +import fileDownload from "js-file-download"; -import { Tag, Drawer, Button, Table, Spin } from "antd"; +import { Tag, Drawer, Button, Table, Spin, Space } from "antd"; import { ZoomInOutlined } from "@ant-design/icons"; import { LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb"; @@ -14,6 +15,7 @@ interface IProps { interface IState { drawerOpen: boolean; body: any; + drawerTitle: any; } class LogTable extends Component { @@ -23,6 +25,7 @@ class LogTable extends Component { this.state = { drawerOpen: false, body: null, + drawerTitle: null, }; } @@ -32,15 +35,29 @@ class LogTable extends Component { }); }; - onDrawerOpen = (body: any) => { + onDrawerOpen = (time: any, body: any) => { + let ts = new Date(0); + ts.setUTCSeconds(time.seconds); + let drawerTitle = moment(ts).format("YYYY-MM-DD HH:mm:ss"); + return () => { this.setState({ body: body, + drawerTitle: drawerTitle, drawerOpen: true, }); }; }; + downloadSingleFrame = () => { + fileDownload(JSON.stringify(JSON.parse(this.state.body), null, 4), "single-log.json", "application/json"); + }; + + downloadFrames = () => { + let items = this.props.logs.map((l, i) => JSON.parse(l.getBody())); + fileDownload(JSON.stringify(items, null, 4), "log.json"); + }; + render() { let items = this.props.logs.map((l, i) => l.toObject()); let body = JSON.parse(this.state.body); @@ -67,13 +84,14 @@ class LogTable extends Component { }; return ( -
+ Download} > { /> {items.length !== 0 && ( -
- -
+ + + + )} { type="primary" shape="round" size="small" - onClick={this.onDrawerOpen(obj.body)} + onClick={this.onDrawerOpen(obj.time, obj.body)} > {text} @@ -144,7 +163,7 @@ class LogTable extends Component { }, ]} /> - + ); } } diff --git a/ui/src/index.css b/ui/src/index.css index d9eb1315..026e1317 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -111,3 +111,11 @@ pre { .CodeMirror { height: 600px; } + +.ant-drawer { + padding-top: 64px; +} + +.ant-drawer-body { + padding-bottom: 88px; /* 64 + 24 */ +} diff --git a/ui/yarn.lock b/ui/yarn.lock index 6b893941..40fe0e82 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1881,7 +1881,7 @@ integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@chirpstack/chirpstack-api-grpc-web@file:../api/grpc-web": - version "4.3.0" + version "4.3.1" dependencies: "@types/google-protobuf" "^3.15.6" google-protobuf "^3.21.2" @@ -7025,6 +7025,11 @@ jest@^27.4.3: import-local "^3.0.2" jest-cli "^27.5.1" +js-file-download@^0.4.12: + version "0.4.12" + resolved "https://registry.yarnpkg.com/js-file-download/-/js-file-download-0.4.12.tgz#10c70ef362559a5b23cdbdc3bd6f399c3d91d821" + integrity sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"