datajunction-ui 0.0.1-rc.0 → 0.0.1-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.babel-plugin-macrosrc.js +5 -0
  2. package/.babelrc +4 -0
  3. package/.prettierignore +3 -1
  4. package/.vscode/extensions.json +0 -1
  5. package/Dockerfile +2 -1
  6. package/package.json +24 -12
  7. package/public/index.html +5 -8
  8. package/src/app/__tests__/__snapshots__/index.test.tsx.snap +65 -27
  9. package/src/app/components/DashboardItem.jsx +29 -0
  10. package/src/app/components/Tab.jsx +2 -10
  11. package/src/app/index.tsx +26 -22
  12. package/src/app/pages/ListNamespacesPage/Loadable.jsx +2 -11
  13. package/src/app/pages/ListNamespacesPage/index.jsx +13 -6
  14. package/src/app/pages/NamespacePage/Loadable.jsx +10 -17
  15. package/src/app/pages/NamespacePage/__tests__/__snapshots__/index.test.tsx.snap +18 -15
  16. package/src/app/pages/NamespacePage/index.jsx +14 -20
  17. package/src/app/pages/NodePage/Loadable.jsx +10 -17
  18. package/src/app/pages/NodePage/NodeGraphTab.jsx +15 -8
  19. package/src/app/pages/NodePage/index.jsx +6 -5
  20. package/src/app/pages/NotFoundPage/Loadable.tsx +1 -1
  21. package/src/app/pages/NotFoundPage/index.tsx +5 -27
  22. package/src/app/pages/Root/Loadable.tsx +2 -11
  23. package/src/app/providers/djclient.jsx +5 -0
  24. package/src/index.tsx +3 -2
  25. package/src/setupTests.ts +0 -2
  26. package/src/styles/dag.css +118 -0
  27. package/src/styles/index.css +19 -4
  28. package/src/utils/__tests__/loadable.test.tsx +1 -1
  29. package/tsconfig.json +8 -5
  30. package/webpack.config.js +108 -0
  31. package/src/app/pages/NotFoundPage/P.ts +0 -8
  32. package/src/app/pages/NotFoundPage/__tests__/__snapshots__/index.test.tsx.snap +0 -61
  33. package/src/app/pages/NotFoundPage/__tests__/index.test.tsx +0 -21
  34. package/src/styles/dag-styles.ts +0 -117
  35. package/src/styles/global-styles.ts +0 -588
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ styledComponents: {
3
+ displayName: process.env.NODE_ENV !== 'production',
4
+ },
5
+ };
package/.babelrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "presets": ["@babel/preset-env", "@babel/preset-react"],
3
+ "plugins": ["@babel/plugin-proposal-class-properties"]
4
+ }
package/.prettierignore CHANGED
@@ -1,4 +1,6 @@
1
1
  build/
2
2
  node_modules/
3
3
  package-lock.json
4
- yarn.lock
4
+ yarn.lock
5
+ dist/
6
+ coverage/
@@ -2,7 +2,6 @@
2
2
  "recommendations": [
3
3
  "dbaeumer.vscode-eslint",
4
4
  "esbenp.prettier-vscode",
5
- "styled-components.vscode-styled-components",
6
5
  "orta.vscode-jest"
7
6
  ]
8
7
  }
package/Dockerfile CHANGED
@@ -2,5 +2,6 @@ FROM node:19 AS ui-build
2
2
  WORKDIR /usr/src/app
3
3
  COPY . .
4
4
  EXPOSE 3000
5
+ RUN yarn webpack build
5
6
 
6
- CMD ["yarn", "start"]
7
+ CMD ["yarn", "webpack-start", "--host", "0.0.0.0", "--port", "3000"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datajunction-ui",
3
- "version": "0.0.1-rc.0",
3
+ "version": "0.0.1-rc.10",
4
4
  "description": "DataJunction Metrics Platform UI",
5
5
  "module": "src/index.tsx",
6
6
  "repository": {
@@ -20,6 +20,9 @@
20
20
  },
21
21
  "homepage": "https://github.com/DataJunction/dj#readme",
22
22
  "dependencies": {
23
+ "@babel/core": "^7.18.2",
24
+ "@babel/preset-env": "^7.18.2",
25
+ "@babel/preset-react": "7.18.6",
23
26
  "@reduxjs/toolkit": "1.8.5",
24
27
  "@testing-library/jest-dom": "5.16.5",
25
28
  "@testing-library/react": "13.4.0",
@@ -32,17 +35,16 @@
32
35
  "@types/react-test-renderer": "^18.0.0",
33
36
  "@types/rimraf": "^3.0.2",
34
37
  "@types/shelljs": "^0.8.11",
35
- "@types/styled-components": "^5.1.26",
36
38
  "@types/testing-library__jest-dom": "^5.14.5",
37
39
  "@types/webpack": "^5.28.0",
38
40
  "@types/webpack-env": "^1.18.0",
41
+ "babel-loader": "9.1.2",
39
42
  "chalk": "4.1.2",
40
43
  "cross-env": "7.0.3",
44
+ "css-loader": "6.7.3",
41
45
  "dagre": "^0.8.5",
42
46
  "datajunction": "0.0.1-rc.0",
43
- "eslint-config-prettier": "8.5.0",
44
- "eslint-plugin-prettier": "4.2.1",
45
- "eslint-plugin-react-hooks": "4.6.0",
47
+ "file-loader": "6.2.0",
46
48
  "fontfaceobserver": "2.3.0",
47
49
  "husky": "8.0.1",
48
50
  "i18next": "21.9.2",
@@ -50,7 +52,6 @@
50
52
  "i18next-scanner": "4.0.0",
51
53
  "inquirer": "7.3.3",
52
54
  "inquirer-directory": "2.2.0",
53
- "jest-styled-components": "7.1.1",
54
55
  "lint-staged": "13.0.3",
55
56
  "node-plop": "0.26.3",
56
57
  "plop": "2.7.6",
@@ -74,16 +75,20 @@
74
75
  "serve": "14.0.1",
75
76
  "shelljs": "0.8.5",
76
77
  "sql-formatter": "^12.2.0",
77
- "styled-components": "5.3.5",
78
+ "style-loader": "3.3.2",
78
79
  "stylelint": "14.12.0",
79
80
  "stylelint-config-recommended": "9.0.0",
80
- "stylelint-config-styled-components": "0.1.1",
81
- "stylelint-processor-styled-components": "1.10.0",
81
+ "ts-loader": "9.4.2",
82
82
  "ts-node": "10.9.1",
83
83
  "typescript": "4.6.4",
84
- "web-vitals": "2.1.4"
84
+ "web-vitals": "2.1.4",
85
+ "webpack": "5.81.0",
86
+ "webpack-cli": "5.0.2",
87
+ "webpack-dev-server": "4.13.3"
85
88
  },
86
89
  "scripts": {
90
+ "webpack-start": "webpack-dev-server --open",
91
+ "webpack-build": "webpack",
87
92
  "start": "react-scripts start",
88
93
  "build": "react-scripts build",
89
94
  "test": "react-scripts test",
@@ -98,7 +103,8 @@
98
103
  "generate": "plop --plopfile internals/generators/plopfile.ts",
99
104
  "cleanAndSetup": "ts-node ./internals/scripts/clean.ts",
100
105
  "prettify": "prettier --write",
101
- "extract-messages": "i18next-scanner --config=internals/extractMessages/i18next-scanner.config.js"
106
+ "extract-messages": "i18next-scanner --config=internals/extractMessages/i18next-scanner.config.js",
107
+ "prepublishOnly": "webpack --mode=production"
102
108
  },
103
109
  "eslintConfig": {
104
110
  "extends": "react-app"
@@ -145,6 +151,12 @@
145
151
  }
146
152
  },
147
153
  "devDependencies": {
148
- "jest": "^29.5.0"
154
+ "@babel/plugin-proposal-class-properties": "7.18.6",
155
+ "eslint-config-prettier": "8.8.0",
156
+ "eslint-plugin-prettier": "4.2.1",
157
+ "eslint-plugin-react-hooks": "4.6.0",
158
+ "html-webpack-plugin": "5.5.1",
159
+ "jest": "^29.5.0",
160
+ "mini-css-extract-plugin": "2.7.5"
149
161
  }
150
162
  }
package/public/index.html CHANGED
@@ -1,18 +1,15 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
+ <base href="/" />
4
5
  <meta charset="utf-8" />
5
- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6
+ <link rel="icon" href="public/favicon.ico" />
6
7
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
8
  <meta name="theme-color" content="#000000" />
8
- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
9
- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
10
- <meta property="og:title" content="React Boilerplate Example App" />
9
+ <link rel="manifest" href="public/manifest.json" />
10
+ <link rel="manifest" href="src/styles/index.css" />
11
+ <meta property="og:title" content="DataJunction UI" />
11
12
  <meta property="og:description" content="" />
12
- <meta
13
- property="og:image"
14
- content="https://repository-images.githubusercontent.com/250347048/15514f00-8713-11ea-9f9d-796a89b5de4d"
15
- />
16
13
  <title>DataJunction App</title>
17
14
  <meta name="description" content="" />
18
15
  </head>
@@ -14,32 +14,70 @@ exports[`<App /> should render and match the snapshot 1`] = `
14
14
  name="description"
15
15
  />
16
16
  </Helmet>
17
- <Routes>
18
- <Route
19
- element={<Unknown />}
20
- path="/"
21
- >
22
- <React.Fragment>
23
- <Route
24
- element={<Unknown />}
25
- path="/nodes/:name"
26
- />
27
- <Route
28
- element={<Unknown />}
29
- path="/namespaces/:namespace"
30
- />
31
- <Route
32
- element={<ListNamespacesPage />}
33
- path="/namespaces/"
34
- />
35
- </React.Fragment>
36
- </Route>
37
- <Route
38
- element={<Unknown />}
39
- path="*"
40
- />
41
- </Routes>
42
- <Memo(l) />
43
- <Memo(l) />
17
+ <Context.Provider
18
+ value={
19
+ Object {
20
+ "DataJunctionAPI": Object {
21
+ "dag": [Function],
22
+ "downstreams": [Function],
23
+ "lineage": [Function],
24
+ "metric": [Function],
25
+ "namespace": [Function],
26
+ "namespaces": [Function],
27
+ "node": [Function],
28
+ "upstreams": [Function],
29
+ },
30
+ }
31
+ }
32
+ >
33
+ <Routes>
34
+ <Route
35
+ element={<Unknown />}
36
+ path="/"
37
+ >
38
+ <React.Fragment>
39
+ <Route
40
+ path="nodes"
41
+ >
42
+ <Route
43
+ element={<NodePage />}
44
+ path=":name"
45
+ />
46
+ </Route>
47
+ <Route
48
+ element={
49
+ <ListNamespacesPage
50
+ djClient={
51
+ Object {
52
+ "dag": [Function],
53
+ "downstreams": [Function],
54
+ "lineage": [Function],
55
+ "metric": [Function],
56
+ "namespace": [Function],
57
+ "namespaces": [Function],
58
+ "node": [Function],
59
+ "upstreams": [Function],
60
+ }
61
+ }
62
+ />
63
+ }
64
+ path="/"
65
+ />
66
+ <Route
67
+ path="namespaces"
68
+ >
69
+ <Route
70
+ element={<NamespacePage />}
71
+ path=":namespace"
72
+ />
73
+ </Route>
74
+ </React.Fragment>
75
+ </Route>
76
+ <Route
77
+ element={<Unknown />}
78
+ path="*"
79
+ />
80
+ </Routes>
81
+ </Context.Provider>
44
82
  </BrowserRouter>
45
83
  `;
@@ -0,0 +1,29 @@
1
+ import { Component } from 'react';
2
+
3
+ export default class DashboardItem extends Component {
4
+ render() {
5
+ const { label, value } = this.props;
6
+ return (
7
+ // <div className="col-xl col-md-6 col-12">
8
+ // <div className="card">
9
+ // <div className="card-body">
10
+ // <div className="align-items-center row">
11
+ // <div className="col"><h6 className="text-uppercase text-muted mb-2">{ label }</h6><span
12
+ // className="h2 mb-0">{ value }</span><span className="mt-n1 ms-2 badge bg-success-soft">+3.5%</span></div>
13
+ // <div className="col-auto">
14
+ // <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
15
+ // stroke-linecap="round" stroke-linejoin="round" className="feather feather-dollar-sign text-muted">
16
+ // <g>
17
+ // <line x1="12" y1="1" x2="12" y2="23"></line>
18
+ // <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path>
19
+ // </g>
20
+ // </svg>
21
+ // </div>
22
+ // </div>
23
+ // </div>
24
+ // </div>
25
+ // </div>
26
+ <div></div>
27
+ );
28
+ }
29
+ }
@@ -7,17 +7,9 @@ export default class Tab extends Component {
7
7
  <div className={selectedTab === id ? 'col active' : 'col'}>
8
8
  <div className="header-tabs nav-overflow nav nav-tabs">
9
9
  <div className="nav-item">
10
- <a
11
- id={id}
12
- role="button"
13
- className="nav-link"
14
- tabIndex="0"
15
- href="#/"
16
- onClick={onClick}
17
- >
10
+ <button id={id} className="nav-link" tabIndex="0" onClick={onClick}>
18
11
  {this.props.name}
19
- {/*<span className="rounded-pill badge bg-secondary-soft">823</span>*/}
20
- </a>
12
+ </button>
21
13
  </div>
22
14
  </div>
23
15
  </div>
package/src/app/index.tsx CHANGED
@@ -7,14 +7,13 @@ import * as React from 'react';
7
7
  import { Helmet } from 'react-helmet-async';
8
8
  import { BrowserRouter, Routes, Route } from 'react-router-dom';
9
9
 
10
- import { GlobalStyle } from 'styles/global-styles';
11
- import { DAGStyle } from '../styles/dag-styles';
12
-
13
10
  import { NamespacePage } from './pages/NamespacePage/Loadable';
14
11
  import { NodePage } from './pages/NodePage/Loadable';
15
12
  import { NotFoundPage } from './pages/NotFoundPage/Loadable';
16
13
  import { Root } from './pages/Root/Loadable';
17
14
  import { ListNamespacesPage } from './pages/ListNamespacesPage';
15
+ import DJClientContext from './providers/djclient';
16
+ import { DataJunctionAPI } from './services/DJService';
18
17
 
19
18
  export function App() {
20
19
  return (
@@ -28,26 +27,31 @@ export function App() {
28
27
  content="DataJunction serves as a semantic layer to help manage metrics"
29
28
  />
30
29
  </Helmet>
30
+ <DJClientContext.Provider value={{ DataJunctionAPI }}>
31
+ <Routes>
32
+ <Route
33
+ path="/"
34
+ element={<Root />}
35
+ children={
36
+ <>
37
+ <Route path="nodes" key="nodes">
38
+ <Route path=":name" element={<NodePage />} />
39
+ </Route>
31
40
 
32
- <Routes>
33
- <Route
34
- path="/"
35
- element={<Root />}
36
- children={
37
- <>
38
- <Route path="/nodes/:name" element={<NodePage />} />
39
- <Route
40
- path="/namespaces/:namespace"
41
- element={<NamespacePage />}
42
- />
43
- <Route path="/namespaces/" element={<ListNamespacesPage />} />
44
- </>
45
- }
46
- />
47
- <Route path="*" element={<NotFoundPage />} />
48
- </Routes>
49
- <GlobalStyle />
50
- <DAGStyle />
41
+ <Route path="/" element={<ListNamespacesPage />} key="index" />
42
+ <Route path="namespaces">
43
+ <Route
44
+ path=":namespace"
45
+ element={<NamespacePage />}
46
+ key="namespaces"
47
+ />
48
+ </Route>
49
+ </>
50
+ }
51
+ />
52
+ <Route path="*" element={<NotFoundPage />} />
53
+ </Routes>
54
+ </DJClientContext.Provider>
51
55
  </BrowserRouter>
52
56
  );
53
57
  }
@@ -3,21 +3,12 @@
3
3
  */
4
4
 
5
5
  import * as React from 'react';
6
- import { lazyLoad } from 'utils/loadable';
7
- import styled from 'styled-components/macro';
8
-
9
- const LoadingWrapper = styled.div`
10
- width: 100%;
11
- height: 100vh;
12
- display: flex;
13
- align-items: center;
14
- justify-content: center;
15
- `;
6
+ import { lazyLoad } from '../../../utils/loadable';
16
7
 
17
8
  export const ListNamespacesPage = lazyLoad(
18
9
  () => import('./index'),
19
10
  module => module.ListNamespacesPage,
20
11
  {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
12
+ fallback: <div></div>,
22
13
  },
23
14
  );
@@ -1,30 +1,33 @@
1
1
  import * as React from 'react';
2
- import { useEffect, useState } from 'react';
2
+ import { useContext, useEffect, useState } from 'react';
3
3
  import NamespaceHeader from '../../components/NamespaceHeader';
4
- const datajunction = require('datajunction');
5
- const dj = new datajunction.DJClient('http://localhost:8000');
4
+ import { DataJunctionAPI } from '../../services/DJService';
5
+ import DJClientContext from '../../providers/djclient';
6
+ // const datajunction = require('datajunction');
7
+ // const dj = new datajunction.DJClient('http://localhost:8000');
6
8
 
7
9
  export function ListNamespacesPage() {
10
+ const djClient = useContext(DJClientContext).DataJunctionAPI;
8
11
  const [state, setState] = useState({
9
12
  namespaces: [],
10
13
  });
11
14
 
12
15
  useEffect(() => {
13
16
  const fetchData = async () => {
14
- const namespaces = await dj.namespaces.get();
17
+ const namespaces = await djClient.namespaces();
15
18
  setState({
16
19
  namespaces: namespaces,
17
20
  });
18
21
  };
19
22
  fetchData().catch(console.error);
20
- }, []);
23
+ }, [djClient, djClient.namespaces]);
21
24
 
22
25
  const namespacesList = state.namespaces.map(node => (
23
26
  <tr>
24
27
  <td>
25
28
  <a href={'/namespaces/' + node.namespace}>{node.namespace}</a>
26
29
  </td>
27
- <td>5</td>
30
+ <td></td>
28
31
  </tr>
29
32
  ));
30
33
 
@@ -51,3 +54,7 @@ export function ListNamespacesPage() {
51
54
  </>
52
55
  );
53
56
  }
57
+
58
+ ListNamespacesPage.defaultProps = {
59
+ djClient: DataJunctionAPI,
60
+ };
@@ -3,21 +3,14 @@
3
3
  */
4
4
 
5
5
  import * as React from 'react';
6
- import { lazyLoad } from 'utils/loadable';
7
- import styled from 'styled-components/macro';
6
+ import { lazyLoad } from '../../../utils/loadable';
8
7
 
9
- const LoadingWrapper = styled.div`
10
- width: 100%;
11
- height: 100vh;
12
- display: flex;
13
- align-items: center;
14
- justify-content: center;
15
- `;
16
-
17
- export const NamespacePage = lazyLoad(
18
- () => import('./index'),
19
- module => module.NamespacePage,
20
- {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
22
- },
23
- );
8
+ export const NamespacePage = props => {
9
+ return lazyLoad(
10
+ () => import('./index'),
11
+ module => module.NamespacePage,
12
+ {
13
+ fallback: <div></div>,
14
+ },
15
+ )(props);
16
+ };
@@ -21,22 +21,25 @@ exports[`<NamespacePage /> should render and match the snapshot 1`] = `
21
21
  className="card-table table"
22
22
  >
23
23
  <thead>
24
- <th>
25
- Namespace
26
- </th>
27
- <th>
28
- Name
29
- </th>
30
- <th>
31
- Type
32
- </th>
33
- <th>
34
- Status
35
- </th>
36
- <th>
37
- Mode
38
- </th>
24
+ <tr>
25
+ <th>
26
+ Namespace
27
+ </th>
28
+ <th>
29
+ Name
30
+ </th>
31
+ <th>
32
+ Type
33
+ </th>
34
+ <th>
35
+ Status
36
+ </th>
37
+ <th>
38
+ Mode
39
+ </th>
40
+ </tr>
39
41
  </thead>
42
+ <tbody />
40
43
  </table>
41
44
  </div>
42
45
  </div>
@@ -1,20 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { useParams } from 'react-router-dom';
3
- import { useEffect, useState } from 'react';
4
- import { DataJunctionAPI } from '../../services/DJService';
3
+ import { useContext, useEffect, useState } from 'react';
5
4
  import NamespaceHeader from '../../components/NamespaceHeader';
6
5
  import NodeStatus from '../NodePage/NodeStatus';
7
-
8
- export async function loader({ params }) {
9
- const djNode = await DataJunctionAPI.node(params.name);
10
- if (djNode.type === 'metric') {
11
- const metricNode = await DataJunctionAPI.metric(params.name);
12
- djNode.dimensions = metricNode.dimensions;
13
- }
14
- return djNode;
15
- }
6
+ import DJClientContext from '../../providers/djclient';
16
7
 
17
8
  export function NamespacePage() {
9
+ const djClient = useContext(DJClientContext).DataJunctionAPI;
18
10
  const { namespace } = useParams();
19
11
 
20
12
  const [state, setState] = useState({
@@ -24,9 +16,9 @@ export function NamespacePage() {
24
16
 
25
17
  useEffect(() => {
26
18
  const fetchData = async () => {
27
- const djNodes = await DataJunctionAPI.namespace(namespace);
19
+ const djNodes = await djClient.namespace(namespace);
28
20
  const nodes = djNodes.map(node => {
29
- return DataJunctionAPI.node(node);
21
+ return djClient.node(node);
30
22
  });
31
23
  const foundNodes = await Promise.all(nodes);
32
24
  setState({
@@ -35,7 +27,7 @@ export function NamespacePage() {
35
27
  });
36
28
  };
37
29
  fetchData().catch(console.error);
38
- }, [namespace]);
30
+ }, [djClient, namespace]);
39
31
 
40
32
  const nodesList = state.nodes.map(node => (
41
33
  <tr>
@@ -77,13 +69,15 @@ export function NamespacePage() {
77
69
  <div className="table-responsive">
78
70
  <table className="card-table table">
79
71
  <thead>
80
- <th>Namespace</th>
81
- <th>Name</th>
82
- <th>Type</th>
83
- <th>Status</th>
84
- <th>Mode</th>
72
+ <tr>
73
+ <th>Namespace</th>
74
+ <th>Name</th>
75
+ <th>Type</th>
76
+ <th>Status</th>
77
+ <th>Mode</th>
78
+ </tr>
85
79
  </thead>
86
- {nodesList}
80
+ <tbody>{nodesList}</tbody>
87
81
  </table>
88
82
  </div>
89
83
  </div>
@@ -3,21 +3,14 @@
3
3
  */
4
4
 
5
5
  import * as React from 'react';
6
- import { lazyLoad } from 'utils/loadable';
7
- import styled from 'styled-components/macro';
6
+ import { lazyLoad } from '../../../utils/loadable';
8
7
 
9
- const LoadingWrapper = styled.div`
10
- width: 100%;
11
- height: 100vh;
12
- display: flex;
13
- align-items: center;
14
- justify-content: center;
15
- `;
16
-
17
- export const NodePage = lazyLoad(
18
- () => import('./index'),
19
- module => module.NodePage,
20
- {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
22
- },
23
- );
8
+ export const NodePage = props => {
9
+ return lazyLoad(
10
+ () => import('./index'),
11
+ module => module.NodePage,
12
+ {
13
+ fallback: <div></div>,
14
+ },
15
+ )(props);
16
+ };