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
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo } from 'react';
1
+ import React, { useCallback, useContext, useEffect, useMemo } from 'react';
2
2
  import ReactFlow, {
3
3
  addEdge,
4
4
  MiniMap,
@@ -8,12 +8,15 @@ import ReactFlow, {
8
8
  useEdgesState,
9
9
  MarkerType,
10
10
  } from 'reactflow';
11
+
12
+ import '../../../styles/dag.css';
11
13
  import 'reactflow/dist/style.css';
12
14
  import DJNode from '../../components/djgraph/DJNode';
13
- import { DataJunctionAPI } from '../../services/DJService';
14
15
  import dagre from 'dagre';
16
+ import DJClientContext from '../../providers/djclient';
15
17
 
16
18
  const NodeLineage = djNode => {
19
+ const djClient = useContext(DJClientContext).DataJunctionAPI;
17
20
  const nodeTypes = useMemo(() => ({ DJNode: DJNode }), []);
18
21
 
19
22
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
@@ -63,9 +66,14 @@ const NodeLineage = djNode => {
63
66
  };
64
67
 
65
68
  const dagFetch = async () => {
66
- let upstreams = await DataJunctionAPI.upstreams(djNode.djNode.name);
67
- let downstreams = await DataJunctionAPI.downstreams(djNode.djNode.name);
68
- let djNodes = [...new Set([...upstreams, ...downstreams, djNode.djNode])];
69
+ let upstreams = await djClient.upstreams(djNode.djNode.name);
70
+ let downstreams = await djClient.downstreams(djNode.djNode.name);
71
+ var djNodes = [djNode.djNode];
72
+ for (const iterable of [upstreams, downstreams]) {
73
+ for (const item of iterable) {
74
+ djNodes.push(item);
75
+ }
76
+ }
69
77
  let edges = [];
70
78
  djNodes.forEach(obj => {
71
79
  obj.parents.forEach(parent => {
@@ -111,7 +119,7 @@ const NodeLineage = djNode => {
111
119
  label:
112
120
  node.table !== null
113
121
  ? String(node.schema_ + '.' + node.table)
114
- : String(node.name),
122
+ : 'default.' + node.name,
115
123
  table: node.table,
116
124
  name: String(node.name),
117
125
  display_name: String(node.display_name),
@@ -124,14 +132,13 @@ const NodeLineage = djNode => {
124
132
  // extent: 'parent',
125
133
  };
126
134
  });
127
-
128
135
  setNodes(nodes);
129
136
  setEdges(edges);
130
137
  setElementsLayout(nodes, edges);
131
138
  };
132
139
 
133
140
  dagFetch();
134
- }, [dagreGraph, djNode.djNode, setEdges, setNodes]);
141
+ }, [dagreGraph, djClient, djNode.djNode, setEdges, setNodes]);
135
142
 
136
143
  const onConnect = useCallback(
137
144
  params => setEdges(eds => addEdge(params, eds)),
@@ -1,14 +1,15 @@
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 Tab from '../../components/Tab';
6
5
  import NamespaceHeader from '../../components/NamespaceHeader';
7
6
  import NodeInfoTab from './NodeInfoTab';
8
7
  import NodeColumnTab from './NodeColumnTab';
9
8
  import NodeLineage from './NodeGraphTab';
9
+ import DJClientContext from '../../providers/djclient';
10
10
 
11
11
  export function NodePage() {
12
+ const djClient = useContext(DJClientContext).DataJunctionAPI;
12
13
  const [state, setState] = useState({
13
14
  selectedTab: 0,
14
15
  });
@@ -35,11 +36,11 @@ export function NodePage() {
35
36
 
36
37
  useEffect(() => {
37
38
  const fetchData = async () => {
38
- const data = await DataJunctionAPI.node(name);
39
+ const data = await djClient.node(name);
39
40
  setNode(data);
40
41
  };
41
42
  fetchData().catch(console.error);
42
- }, [name]);
43
+ }, [djClient, name]);
43
44
 
44
45
  const TabsJson = [
45
46
  {
@@ -66,7 +67,7 @@ export function NodePage() {
66
67
  tabToDisplay = <NodeColumnTab node={node} />;
67
68
  break;
68
69
  case 2:
69
- tabToDisplay = <NodeLineage djNode={node} />;
70
+ tabToDisplay = <NodeLineage djNode={node} djClient={djClient} />;
70
71
  break;
71
72
  default:
72
73
  tabToDisplay = <NodeInfoTab node={node} />;
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import * as React from 'react';
6
- import { lazyLoad } from 'utils/loadable';
6
+ import { lazyLoad } from '../../../utils/loadable';
7
7
 
8
8
  export const NotFoundPage = lazyLoad(
9
9
  () => import('./index'),
@@ -1,6 +1,4 @@
1
1
  import * as React from 'react';
2
- import styled from 'styled-components/macro';
3
- import { P } from './P';
4
2
  import { Helmet } from 'react-helmet-async';
5
3
 
6
4
  export function NotFoundPage() {
@@ -10,36 +8,16 @@ export function NotFoundPage() {
10
8
  <title>404 Page Not Found</title>
11
9
  <meta name="description" content="Page not found" />
12
10
  </Helmet>
13
- <Wrapper>
14
- <Title>
11
+ <div>
12
+ <label>
15
13
  4
16
14
  <span role="img" aria-label="Crying Face">
17
15
  😢
18
16
  </span>
19
17
  4
20
- </Title>
21
- <P>Page not found.</P>
22
- </Wrapper>
18
+ </label>
19
+ <p>Page not found.</p>
20
+ </div>
23
21
  </>
24
22
  );
25
23
  }
26
-
27
- const Wrapper = styled.div`
28
- height: 100%;
29
- display: flex;
30
- align-items: center;
31
- justify-content: center;
32
- flex-direction: column;
33
- min-height: 320px;
34
- `;
35
-
36
- const Title = styled.div`
37
- margin-top: -8vh;
38
- font-weight: bold;
39
- color: ${p => p.theme.text};
40
- font-size: 3.375rem;
41
-
42
- span {
43
- font-size: 3.125rem;
44
- }
45
- `;
@@ -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 Root = lazyLoad(
18
9
  () => import('./index'),
19
10
  module => module.Root,
20
11
  {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
12
+ fallback: <></>,
22
13
  },
23
14
  );
@@ -0,0 +1,5 @@
1
+ import { DataJunctionAPI } from '../services/DJService';
2
+ import * as React from 'react';
3
+
4
+ const DJClientContext = React.createContext({ DataJunctionAPI });
5
+ export default DJClientContext;
package/src/index.tsx CHANGED
@@ -14,11 +14,12 @@ import FontFaceObserver from 'fontfaceobserver';
14
14
 
15
15
  // Use consistent styling
16
16
  import 'sanitize.css/sanitize.css';
17
+ import './styles/index.css';
17
18
 
18
- import { App } from 'app';
19
+ import { App } from './app';
19
20
 
20
21
  import { HelmetProvider } from 'react-helmet-async';
21
- import reportWebVitals from 'reportWebVitals';
22
+ import reportWebVitals from './reportWebVitals';
22
23
 
23
24
  // Observe loading of Inter (to remove 'Inter', remove the <link> tag in
24
25
  // the index.html file and this observer)
package/src/setupTests.ts CHANGED
@@ -4,5 +4,3 @@ import '@testing-library/jest-dom/extend-expect';
4
4
 
5
5
  import 'react-app-polyfill/ie11';
6
6
  import 'react-app-polyfill/stable';
7
-
8
- import 'jest-styled-components';
@@ -0,0 +1,118 @@
1
+ .react-flow__node-custom {
2
+ font-size: 1.2em;
3
+ width: 180px;
4
+ background: #f5f5f6;
5
+ color: #222;
6
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 15%), 0 2px 4px -1px rgb(0 0 0 / 8%);
7
+ border-radius: 2px;
8
+ }
9
+ .react-flow {
10
+ width: 100%;
11
+ height: 800px;
12
+ overflow: hidden;
13
+ position: relative;
14
+ z-index: 0;
15
+ }
16
+ .react-flow__node-custom .react-flow__handle {
17
+ top: 24px;
18
+ right: -15px;
19
+ width: 6px;
20
+ height: 10px;
21
+ border-radius: 2px;
22
+ background-color: #778899;
23
+ }
24
+
25
+ .react-flow__node.circle {
26
+ border-radius: 50%;
27
+ width: 60px;
28
+ height: 60px;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ font-weight: 700;
33
+ }
34
+
35
+ .react-flow__node.annotation {
36
+ border-radius: 0;
37
+ text-align: left;
38
+ background: white;
39
+ border: none;
40
+ line-height: 1.4;
41
+ width: 225px;
42
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 15%), 0 2px 4px -1px rgb(0 0 0 / 8%);
43
+ }
44
+
45
+ .react-flow__node.annotation .react-flow__handle {
46
+ display: none;
47
+ }
48
+
49
+ .dj-node__header {
50
+ font-weight: 400;
51
+ text-transform: uppercase;
52
+ font-family: 'jetbrains-mono', monospace;
53
+ font-size: 1.5em;
54
+ padding-inline-start: 0.5rem;
55
+ padding-inline-end: 0.5rem;
56
+ padding-left: 0.75em;
57
+ padding-top: 0.35rem;
58
+ padding-bottom: 0.35rem;
59
+ border-bottom-width: 1px;
60
+ border-bottom-style: solid;
61
+ border-color: #c4cbd1;
62
+ }
63
+
64
+ .dj-node__body {
65
+ background-color: rgb(254, 254, 254);
66
+ padding: 0.5em 0.7em 0.9em 0.7em;
67
+ font-family: 'nt-dapper', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
68
+ Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
69
+ font-size: 1.7em;
70
+ }
71
+
72
+ .dj-node__full {
73
+ display: flex;
74
+ flex-direction: column;
75
+ height: 100%;
76
+ border-width: 1px;
77
+ border-style: solid;
78
+ border-image: initial;
79
+ border-color: #b0b9c2;
80
+ border-radius: 8px;
81
+ overflow: hidden;
82
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px,
83
+ rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
84
+ }
85
+
86
+ .dj-node__metadata {
87
+ padding: 1em;
88
+ font-family: 'nt-dapper', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
89
+ Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
90
+ font-size: 1em;
91
+ }
92
+
93
+ .collapse-button {
94
+ display: block;
95
+ width: 100%;
96
+ font: 0.8em 'Montserrat', 'Helvetica Neue', Helvetica, Arial, sans-serif;
97
+ text-transform: uppercase;
98
+ border: none;
99
+ margin-top: 0.2em;
100
+ padding: 0.35em;
101
+ }
102
+ .collapse {
103
+ padding-top: 10px;
104
+ }
105
+ .collapse-content.collapsed {
106
+ display: none;
107
+ }
108
+ .collapsed-content.expanded {
109
+ display: block;
110
+ }
111
+ .collapse tr td {
112
+ padding-left: 5px;
113
+ padding-bottom: 5px;
114
+ }
115
+ .serif {
116
+ font-family: 'jetbrains-mono', monospace;
117
+ text-transform: lowercase;
118
+ }
@@ -25,8 +25,21 @@ p {
25
25
  a,
26
26
  a:hover {
27
27
  text-decoration: none;
28
+ color: #005c72;
28
29
  font-family: 'Cerebri Sans', sans-serif;
29
30
  }
31
+ a:hover {
32
+ text-decoration: underline;
33
+ }
34
+ button.nav-link {
35
+ background: none;
36
+ color: #007acc;
37
+ border: inherit;
38
+ padding: inherit;
39
+ font: inherit;
40
+ cursor: pointer;
41
+ outline: inherit;
42
+ }
30
43
  code {
31
44
  font-family: Consolas, source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
32
45
  monospace;
@@ -339,6 +352,8 @@ tbody th {
339
352
  padding: 0.44rem;
340
353
  border-radius: 0.375rem;
341
354
  cursor: crosshair;
355
+ word-wrap: break-word;
356
+ white-space: break-spaces;
342
357
  }
343
358
 
344
359
  /* Nodes */
@@ -366,8 +381,8 @@ tbody th {
366
381
  }
367
382
 
368
383
  .node_type__cube {
369
- background-color: #c2180750 !important;
370
- color: #c21807;
384
+ background-color: #dbafff !important;
385
+ color: #580076;
371
386
  }
372
387
 
373
388
  .status__valid {
@@ -485,8 +500,8 @@ pre {
485
500
  flex-grow: 0 !important;
486
501
  }
487
502
  .logo img {
488
- padding: 10px;
489
- margin-bottom: -1.2rem;
503
+ padding: 15px;
504
+ margin-bottom: 0.2rem;
490
505
  }
491
506
 
492
507
  .menu-lg-row > .menu-item {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { render } from '@testing-library/react';
3
- import { lazyLoad } from 'utils/loadable';
3
+ import { lazyLoad } from '../loadable';
4
4
 
5
5
  const LoadingIndicator = () => <div>Loading</div>;
6
6
 
package/tsconfig.json CHANGED
@@ -2,29 +2,32 @@
2
2
  "compilerOptions": {
3
3
  "noImplicitAny": false,
4
4
  "target": "es5",
5
- "lib": ["dom", "dom.iterable", "esnext"],
5
+ "lib": ["dom", "dom.iterable", "esnext", "es2015"],
6
6
  "allowJs": true,
7
7
  "skipLibCheck": true,
8
8
  "esModuleInterop": true,
9
9
  "allowSyntheticDefaultImports": true,
10
10
  "strict": true,
11
11
  "forceConsistentCasingInFileNames": true,
12
- "module": "esnext",
12
+ "module": "commonjs",
13
13
  "moduleResolution": "node",
14
14
  "resolveJsonModule": true,
15
15
  "isolatedModules": true,
16
16
  "noEmit": true,
17
17
  "noFallthroughCasesInSwitch": true,
18
18
  "jsx": "react-jsx",
19
- "baseUrl": "./src"
19
+ "baseUrl": "./src",
20
+ "preserveConstEnums": true,
21
+ "removeComments": true,
22
+ "sourceMap": true
20
23
  },
21
- "include": ["src", "internals/startingTemplate/**/*"],
24
+ "include": ["src/**/*.ts", "src/**/*.tsx", "internals/startingTemplate/**/*"],
22
25
  "ts-node": {
23
26
  "compilerOptions": {
24
27
  "esModuleInterop": true,
25
28
  "module": "commonjs",
26
29
  "moduleResolution": "node",
27
- "noEmit": true,
30
+ "noEmit": false,
28
31
  "allowSyntheticDefaultImports": true
29
32
  }
30
33
  }
@@ -0,0 +1,108 @@
1
+ const webpack = require('webpack');
2
+ const path = require('path');
3
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
4
+ // const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5
+
6
+ var babelOptions = {
7
+ presets: ['@babel/preset-react'],
8
+ };
9
+
10
+ module.exports = {
11
+ cache: true,
12
+ entry: {
13
+ main: './src/index.tsx',
14
+ vendor: ['events', 'react', 'react-dom'],
15
+ },
16
+ target: 'web',
17
+ mode: 'development',
18
+ output: {
19
+ path: path.resolve(__dirname, './dist'),
20
+ filename: 'static/[name].[fullhash].js',
21
+ library: 'datajunction-ui',
22
+ libraryTarget: 'umd',
23
+ globalObject: 'this',
24
+ umdNamedDefine: true,
25
+ publicPath: '/',
26
+ },
27
+ devServer: {
28
+ historyApiFallback: {
29
+ disableDotRule: true,
30
+ },
31
+ },
32
+ resolve: {
33
+ extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
34
+ fallback: {
35
+ path: false,
36
+ buffer: false,
37
+ assert: false,
38
+ fs: false,
39
+ os: false,
40
+ module: false,
41
+ http: false,
42
+ tls: false,
43
+ https: false,
44
+ url: false,
45
+ browser: false,
46
+ net: false,
47
+ process: false,
48
+ },
49
+ },
50
+ module: {
51
+ rules: [
52
+ {
53
+ test: /\.(ts|tsx|jsx)$/,
54
+ use: [
55
+ {
56
+ loader: 'babel-loader',
57
+ options: babelOptions,
58
+ },
59
+ {
60
+ loader: 'ts-loader',
61
+ options: {
62
+ compilerOptions: {
63
+ noEmit: false,
64
+ },
65
+ },
66
+ },
67
+ ],
68
+ },
69
+ {
70
+ test: /\.css$/,
71
+ use: ['style-loader', 'css-loader'],
72
+ },
73
+ {
74
+ test: /\.js$/,
75
+ exclude: /node_modules/,
76
+ use: [
77
+ {
78
+ loader: 'babel-loader',
79
+ options: babelOptions,
80
+ },
81
+ ],
82
+ },
83
+ {
84
+ test: /\.(png|jpe?g|gif)$/i,
85
+ use: [
86
+ {
87
+ loader: 'file-loader',
88
+ },
89
+ ],
90
+ },
91
+ {
92
+ test: /node_modules[\\|/](name-of-the-umd-package)/,
93
+ use: { loader: 'umd-compat-loader' },
94
+ },
95
+ ],
96
+ },
97
+ plugins: [
98
+ new HtmlWebpackPlugin({
99
+ template: path.resolve(__dirname, 'public', 'index.html'),
100
+ }),
101
+ new webpack.DefinePlugin({
102
+ REACT_APP_DJ_URL: 'http://localhost:8000',
103
+ }),
104
+ // new MiniCssExtractPlugin({
105
+ // filename: './styles/index.css',
106
+ // }),
107
+ ],
108
+ };
@@ -1,8 +0,0 @@
1
- import styled from 'styled-components/macro';
2
-
3
- export const P = styled.p`
4
- font-size: 1rem;
5
- line-height: 1.5;
6
- color: ${p => p.theme.textSecondary};
7
- margin: 0.625rem 0 1.5rem 0;
8
- `;
@@ -1,61 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<NotFoundPage /> should match snapshot 1`] = `
4
- .c2 {
5
- font-size: 1rem;
6
- line-height: 1.5;
7
- margin: 0.625rem 0 1.5rem 0;
8
- }
9
-
10
- .c0 {
11
- height: 100%;
12
- display: -webkit-box;
13
- display: -webkit-flex;
14
- display: -ms-flexbox;
15
- display: flex;
16
- -webkit-align-items: center;
17
- -webkit-box-align: center;
18
- -ms-flex-align: center;
19
- align-items: center;
20
- -webkit-box-pack: center;
21
- -webkit-justify-content: center;
22
- -ms-flex-pack: center;
23
- justify-content: center;
24
- -webkit-flex-direction: column;
25
- -ms-flex-direction: column;
26
- flex-direction: column;
27
- min-height: 320px;
28
- }
29
-
30
- .c1 {
31
- margin-top: -8vh;
32
- font-weight: bold;
33
- font-size: 3.375rem;
34
- }
35
-
36
- .c1 span {
37
- font-size: 3.125rem;
38
- }
39
-
40
- <div
41
- className="c0"
42
- >
43
- <div
44
- className="c1"
45
- >
46
- 4
47
- <span
48
- aria-label="Crying Face"
49
- role="img"
50
- >
51
- 😢
52
- </span>
53
- 4
54
- </div>
55
- <p
56
- className="c2"
57
- >
58
- Page not found.
59
- </p>
60
- </div>
61
- `;
@@ -1,21 +0,0 @@
1
- import * as React from 'react';
2
- import { NotFoundPage } from '..';
3
- import { MemoryRouter } from 'react-router-dom';
4
- import { HelmetProvider } from 'react-helmet-async';
5
- import renderer from 'react-test-renderer';
6
-
7
- const renderPage = () =>
8
- renderer.create(
9
- <MemoryRouter>
10
- <HelmetProvider>
11
- <NotFoundPage />
12
- </HelmetProvider>
13
- </MemoryRouter>,
14
- );
15
-
16
- describe('<NotFoundPage />', () => {
17
- it('should match snapshot', () => {
18
- const notFoundPage = renderPage();
19
- expect(notFoundPage.toJSON()).toMatchSnapshot();
20
- });
21
- });