Skip to content

Commit e3bb523

Browse files
committed
add react UI
1 parent 97edfe5 commit e3bb523

33 files changed

+12157
-6
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
**/*.rs.bk
33
*.db
44
.DS_Store
5+
ui/build
6+
ui/node_modules
7+
ui/src/client/.openapi-generator*

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ keywords = ["data", "logger", "iot"]
99
readme = "README.md"
1010
license = "MIT"
1111
edition = "2018"
12-
include = ["src/**/*", "Cargo.toml", "docs/*"]
12+
include = ["src/**/*", "Cargo.toml", "docs/**/*", "ui/build/**"]
1313

1414
[dependencies]
1515
actix-rt = "1.0.0"

src/main.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,7 @@ async fn insert_data(
4848
}
4949

5050
async fn p404() -> Result<fs::NamedFile, WebError> {
51-
Ok(
52-
fs::NamedFile::open("src/ui/build/index.html")?
53-
.set_status_code(actix_web::http::StatusCode::OK),
54-
)
51+
Ok(fs::NamedFile::open("ui/build/index.html")?.set_status_code(actix_web::http::StatusCode::OK))
5552
}
5653

5754
#[actix_rt::main]
@@ -80,7 +77,7 @@ async fn main() -> io::Result<()> {
8077
.route(web::get().to(list_data))
8178
.route(web::post().to(insert_data)),
8279
)
83-
.service(fs::Files::new("/", "src/ui/build").index_file("index.html"))
80+
.service(fs::Files::new("/", "ui/build").index_file("index.html"))
8481
.default_service(web::resource("").route(web::get().to(p404)))
8582
})
8683
.bind("0.0.0.0:8080")?

ui/.eslintrc.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
root: true,
3+
parser: '@typescript-eslint/parser',
4+
plugins: [
5+
'@typescript-eslint',
6+
],
7+
extends: [
8+
'eslint:recommended',
9+
'plugin:@typescript-eslint/eslint-recommended',
10+
'plugin:@typescript-eslint/recommended',
11+
],
12+
};

ui/.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*

ui/package.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"name": "dlphn-ui",
3+
"version": "0.1.0",
4+
"private": true,
5+
"dependencies": {
6+
"@typescript-eslint/eslint-plugin": "^2.15.0",
7+
"@typescript-eslint/parser": "^2.15.0",
8+
"eslint": "^6.8.0",
9+
"@testing-library/jest-dom": "^4.2.4",
10+
"@testing-library/react": "^9.4.0",
11+
"@testing-library/user-event": "^7.2.1",
12+
"@types/jest": "^24.0.25",
13+
"@types/node": "^12.12.24",
14+
"@types/react": "^16.9.17",
15+
"@types/react-dom": "^16.9.4",
16+
"@types/react-redux": "^7.1.5",
17+
"@types/redux": "^3.6.0",
18+
"connected-react-router": "^6.6.1",
19+
"history": "^4.10.1",
20+
"react": "^16.12.0",
21+
"react-dom": "^16.12.0",
22+
"react-redux": "^7.1.3",
23+
"react-router": "^5.1.2",
24+
"react-scripts": "3.3.0",
25+
"redux": "^4.0.5",
26+
"redux-saga": "^1.1.3",
27+
"semantic-ui-react": "^0.88.2",
28+
"typescript": "^3.7.4"
29+
},
30+
"scripts": {
31+
"generate-client": "docker run --rm -v ${PWD}/src:/out -v ${PWD}/../../docs:/in openapitools/openapi-generator-cli generate -i /in/openapi.json -g typescript-fetch -o /out/client",
32+
"start": "react-scripts start",
33+
"build": "react-scripts build",
34+
"test": "react-scripts test",
35+
"eject": "react-scripts eject"
36+
},
37+
"eslintConfig": {
38+
"extends": "react-app"
39+
},
40+
"browserslist": {
41+
"production": [
42+
">0.2%",
43+
"not dead",
44+
"not op_mini all"
45+
],
46+
"development": [
47+
"last 1 chrome version",
48+
"last 1 firefox version",
49+
"last 1 safari version"
50+
]
51+
}
52+
}

ui/public/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="theme-color" content="#000000" />
7+
<title>dlphn</title>
8+
</head>
9+
10+
<body>
11+
<noscript>You need to enable JavaScript to run this app.</noscript>
12+
<div id="root"></div>
13+
</body>
14+
</html>

ui/src/Dolphin.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from 'react';
2+
import { Provider } from 'react-redux';
3+
import { ConnectedRouter } from 'connected-react-router';
4+
import { Route, Switch, Redirect } from 'react-router';
5+
import { Store } from 'redux';
6+
import { History } from 'history';
7+
import { Container } from 'semantic-ui-react';
8+
9+
import { ApplicationState } from './store';
10+
import { StreamsPage } from './pages/Streams';
11+
import { DataPage } from './pages/Data';
12+
13+
interface MainProps {
14+
store: Store<ApplicationState>;
15+
history: History;
16+
}
17+
18+
const Dolphin: React.FC<MainProps> = ({ store, history }) => {
19+
return (
20+
<Provider store={store}>
21+
<Container fluid style={{ padding: '20px' }}>
22+
<ConnectedRouter history={history}>
23+
<Switch>
24+
<Route exact path="/">
25+
<Redirect to="/streams" />
26+
</Route>
27+
<Route exact path="/streams" component={StreamsPage} />
28+
<Route path="/streams/:key/data" component={DataPage} />
29+
<Route component={() => <div>Not Found</div>} />
30+
</Switch>
31+
</ConnectedRouter>
32+
</Container>
33+
</Provider>
34+
);
35+
};
36+
37+
export default Dolphin;

ui/src/client/apis/DataApi.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
/**
4+
* dlphn-rs
5+
* A simple data logging server written in Rust.
6+
*
7+
* The version of the OpenAPI document: 0.1.0
8+
*
9+
*
10+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
11+
* https://openapi-generator.tech
12+
* Do not edit the class manually.
13+
*/
14+
15+
16+
import * as runtime from '../runtime';
17+
import {
18+
Data,
19+
DataFromJSON,
20+
DataToJSON,
21+
} from '../models';
22+
23+
export interface AddDataRequest {
24+
key: string;
25+
body: object;
26+
}
27+
28+
export interface ListDataRequest {
29+
key: string;
30+
}
31+
32+
/**
33+
* no description
34+
*/
35+
export class DataApi extends runtime.BaseAPI {
36+
37+
/**
38+
* Add data to a stream
39+
*/
40+
async addDataRaw(requestParameters: AddDataRequest): Promise<runtime.ApiResponse<void>> {
41+
if (requestParameters.key === null || requestParameters.key === undefined) {
42+
throw new runtime.RequiredError('key','Required parameter requestParameters.key was null or undefined when calling addData.');
43+
}
44+
45+
if (requestParameters.body === null || requestParameters.body === undefined) {
46+
throw new runtime.RequiredError('body','Required parameter requestParameters.body was null or undefined when calling addData.');
47+
}
48+
49+
const queryParameters: runtime.HTTPQuery = {};
50+
51+
const headerParameters: runtime.HTTPHeaders = {};
52+
53+
headerParameters['Content-Type'] = 'application/json';
54+
55+
const response = await this.request({
56+
path: `/streams/{key}/data`.replace(`{${"key"}}`, encodeURIComponent(String(requestParameters.key))),
57+
method: 'POST',
58+
headers: headerParameters,
59+
query: queryParameters,
60+
body: requestParameters.body as any,
61+
});
62+
63+
return new runtime.VoidApiResponse(response);
64+
}
65+
66+
/**
67+
* Add data to a stream
68+
*/
69+
async addData(requestParameters: AddDataRequest): Promise<void> {
70+
await this.addDataRaw(requestParameters);
71+
}
72+
73+
/**
74+
* List logged data for stream
75+
*/
76+
async listDataRaw(requestParameters: ListDataRequest): Promise<runtime.ApiResponse<Array<Data>>> {
77+
if (requestParameters.key === null || requestParameters.key === undefined) {
78+
throw new runtime.RequiredError('key','Required parameter requestParameters.key was null or undefined when calling listData.');
79+
}
80+
81+
const queryParameters: runtime.HTTPQuery = {};
82+
83+
const headerParameters: runtime.HTTPHeaders = {};
84+
85+
const response = await this.request({
86+
path: `/streams/{key}/data`.replace(`{${"key"}}`, encodeURIComponent(String(requestParameters.key))),
87+
method: 'GET',
88+
headers: headerParameters,
89+
query: queryParameters,
90+
});
91+
92+
return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(DataFromJSON));
93+
}
94+
95+
/**
96+
* List logged data for stream
97+
*/
98+
async listData(requestParameters: ListDataRequest): Promise<Array<Data>> {
99+
const response = await this.listDataRaw(requestParameters);
100+
return await response.value();
101+
}
102+
103+
}

ui/src/client/apis/StreamsApi.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
/**
4+
* dlphn-rs
5+
* A simple data logging server written in Rust.
6+
*
7+
* The version of the OpenAPI document: 0.1.0
8+
*
9+
*
10+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
11+
* https://openapi-generator.tech
12+
* Do not edit the class manually.
13+
*/
14+
15+
16+
import * as runtime from '../runtime';
17+
import {
18+
Stream,
19+
StreamFromJSON,
20+
StreamToJSON,
21+
} from '../models';
22+
23+
/**
24+
* no description
25+
*/
26+
export class StreamsApi extends runtime.BaseAPI {
27+
28+
/**
29+
* List streams
30+
*/
31+
async listStreamsRaw(): Promise<runtime.ApiResponse<Array<Stream>>> {
32+
const queryParameters: runtime.HTTPQuery = {};
33+
34+
const headerParameters: runtime.HTTPHeaders = {};
35+
36+
const response = await this.request({
37+
path: `/streams`,
38+
method: 'GET',
39+
headers: headerParameters,
40+
query: queryParameters,
41+
});
42+
43+
return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(StreamFromJSON));
44+
}
45+
46+
/**
47+
* List streams
48+
*/
49+
async listStreams(): Promise<Array<Stream>> {
50+
const response = await this.listStreamsRaw();
51+
return await response.value();
52+
}
53+
54+
}

0 commit comments

Comments
 (0)