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

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/.github/workflows/ci.yml +3 -3
  4. package/.vscode/extensions.json +0 -1
  5. package/Dockerfile +2 -1
  6. package/dist/5fa71a03d45dc2e3d61447f3013a303d.png +0 -0
  7. package/dist/index.html +26 -0
  8. package/dist/main.js +23303 -0
  9. package/dist/vendor.js +281 -0
  10. package/package.json +16 -9
  11. package/public/index.html +5 -8
  12. package/src/app/__tests__/__snapshots__/index.test.tsx.snap +5 -7
  13. package/src/app/components/Tab.jsx +2 -3
  14. package/src/app/components/djgraph/DJNode.jsx +6 -6
  15. package/src/app/index.tsx +3 -11
  16. package/src/app/pages/ListNamespacesPage/Loadable.jsx +2 -11
  17. package/src/app/pages/ListNamespacesPage/index.jsx +2 -3
  18. package/src/app/pages/NamespacePage/Loadable.jsx +2 -11
  19. package/src/app/pages/NodePage/Loadable.jsx +2 -11
  20. package/src/app/pages/NodePage/NodeGraphTab.jsx +46 -40
  21. package/src/app/pages/NotFoundPage/Loadable.tsx +1 -1
  22. package/src/app/pages/NotFoundPage/index.tsx +5 -27
  23. package/src/app/pages/Root/Loadable.tsx +2 -11
  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 +13 -0
  28. package/src/utils/__tests__/loadable.test.tsx +1 -1
  29. package/tsconfig.json +7 -4
  30. package/webpack.config.js +91 -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
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.1",
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,17 @@
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",
39
41
  "chalk": "4.1.2",
40
42
  "cross-env": "7.0.3",
41
43
  "dagre": "^0.8.5",
42
- "datajunction": "0.0.1-rc.0",
43
44
  "eslint-config-prettier": "8.5.0",
44
45
  "eslint-plugin-prettier": "4.2.1",
45
46
  "eslint-plugin-react-hooks": "4.6.0",
47
+ "fbemitter": "3.0.0",
48
+ "flux": "4.0.4",
46
49
  "fontfaceobserver": "2.3.0",
47
50
  "husky": "8.0.1",
48
51
  "i18next": "21.9.2",
@@ -50,7 +53,6 @@
50
53
  "i18next-scanner": "4.0.0",
51
54
  "inquirer": "7.3.3",
52
55
  "inquirer-directory": "2.2.0",
53
- "jest-styled-components": "7.1.1",
54
56
  "lint-staged": "13.0.3",
55
57
  "node-plop": "0.26.3",
56
58
  "plop": "2.7.6",
@@ -74,16 +76,18 @@
74
76
  "serve": "14.0.1",
75
77
  "shelljs": "0.8.5",
76
78
  "sql-formatter": "^12.2.0",
77
- "styled-components": "5.3.5",
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"
85
87
  },
86
88
  "scripts": {
89
+ "webpack-start": "webpack-dev-server --open",
90
+ "webpack-build": "webpack",
87
91
  "start": "react-scripts start",
88
92
  "build": "react-scripts build",
89
93
  "test": "react-scripts test",
@@ -145,6 +149,9 @@
145
149
  }
146
150
  },
147
151
  "devDependencies": {
148
- "jest": "^29.5.0"
152
+ "@babel/plugin-proposal-class-properties": "7.18.6",
153
+ "html-webpack-plugin": "5.5.1",
154
+ "jest": "^29.5.0",
155
+ "mini-css-extract-plugin": "2.7.5"
149
156
  }
150
157
  }
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>
@@ -22,15 +22,15 @@ exports[`<App /> should render and match the snapshot 1`] = `
22
22
  <React.Fragment>
23
23
  <Route
24
24
  element={<Unknown />}
25
- path="/nodes/:name"
25
+ path="nodes/:name"
26
26
  />
27
27
  <Route
28
- element={<Unknown />}
29
- path="/namespaces/:namespace"
28
+ element={<ListNamespacesPage />}
29
+ path="namespaces"
30
30
  />
31
31
  <Route
32
- element={<ListNamespacesPage />}
33
- path="/namespaces/"
32
+ element={<Unknown />}
33
+ path="namespaces/:namespace"
34
34
  />
35
35
  </React.Fragment>
36
36
  </Route>
@@ -39,7 +39,5 @@ exports[`<App /> should render and match the snapshot 1`] = `
39
39
  path="*"
40
40
  />
41
41
  </Routes>
42
- <Memo(l) />
43
- <Memo(l) />
44
42
  </BrowserRouter>
45
43
  `;
@@ -7,17 +7,16 @@ 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
10
+ <button
11
11
  id={id}
12
12
  role="button"
13
13
  className="nav-link"
14
14
  tabIndex="0"
15
- href="#/"
16
15
  onClick={onClick}
17
16
  >
18
17
  {this.props.name}
19
18
  {/*<span className="rounded-pill badge bg-secondary-soft">823</span>*/}
20
- </a>
19
+ </button>
21
20
  </div>
22
21
  </div>
23
22
  </div>
@@ -61,12 +61,12 @@ export function DJNode({ id, data }) {
61
61
  <td style={{ textAlign: 'right' }}>{col.type}</td>
62
62
  </tr>
63
63
  ));
64
- // const dimensionsRenderer = data =>
65
- // data.dimensions.map(dim => (
66
- // <tr>
67
- // <td>{dim}</td>
68
- // </tr>
69
- // ));
64
+ const dimensionsRenderer = data =>
65
+ data.dimensions.map(dim => (
66
+ <tr>
67
+ <td>{dim}</td>
68
+ </tr>
69
+ ));
70
70
 
71
71
  return (
72
72
  <>
package/src/app/index.tsx CHANGED
@@ -7,9 +7,6 @@ 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';
@@ -35,19 +32,14 @@ export function App() {
35
32
  element={<Root />}
36
33
  children={
37
34
  <>
38
- <Route path="/nodes/:name" element={<NodePage />} />
39
- <Route
40
- path="/namespaces/:namespace"
41
- element={<NamespacePage />}
42
- />
43
- <Route path="/namespaces/" element={<ListNamespacesPage />} />
35
+ <Route path="nodes/:name" element={<NodePage />} />
36
+ <Route path="namespaces" element={<ListNamespacesPage />} />
37
+ <Route path="namespaces/:namespace" element={<NamespacePage />} />
44
38
  </>
45
39
  }
46
40
  />
47
41
  <Route path="*" element={<NotFoundPage />} />
48
42
  </Routes>
49
- <GlobalStyle />
50
- <DAGStyle />
51
43
  </BrowserRouter>
52
44
  );
53
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 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,8 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { useEffect, useState } from 'react';
3
+ import { DataJunctionAPI } from '../../services/DJService';
3
4
  import NamespaceHeader from '../../components/NamespaceHeader';
4
- const datajunction = require('datajunction');
5
- const dj = new datajunction.DJClient('http://localhost:8000');
6
5
 
7
6
  export function ListNamespacesPage() {
8
7
  const [state, setState] = useState({
@@ -11,7 +10,7 @@ export function ListNamespacesPage() {
11
10
 
12
11
  useEffect(() => {
13
12
  const fetchData = async () => {
14
- const namespaces = await dj.namespaces.get();
13
+ const namespaces = await DataJunctionAPI.namespaces();
15
14
  setState({
16
15
  namespaces: namespaces,
17
16
  });
@@ -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 NamespacePage = lazyLoad(
18
9
  () => import('./index'),
19
10
  module => module.NamespacePage,
20
11
  {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
12
+ fallback: <div></div>,
22
13
  },
23
14
  );
@@ -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 NodePage = lazyLoad(
18
9
  () => import('./index'),
19
10
  module => module.NodePage,
20
11
  {
21
- fallback: <LoadingWrapper></LoadingWrapper>,
12
+ fallback: <div></div>,
22
13
  },
23
14
  );
@@ -8,6 +8,8 @@ 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
15
  import { DataJunctionAPI } from '../../services/DJService';
@@ -23,49 +25,53 @@ const NodeLineage = djNode => {
23
25
  height: 100,
24
26
  width: 150,
25
27
  };
26
-
27
- const dagreGraph = useMemo(() => new dagre.graphlib.Graph(), []);
28
+ const dagreGraph = new dagre.graphlib.Graph();
28
29
  dagreGraph.setDefaultEdgeLabel(() => ({}));
29
30
 
30
- useEffect(() => {
31
- const setElementsLayout = (
32
- nodes,
33
- edges,
34
- direction = 'LR',
35
- nodeWidth = 800,
36
- nodeHeight = 150,
37
- ) => {
38
- const isHorizontal = direction === 'TB';
39
- dagreGraph.setGraph({ rankdir: direction });
40
-
41
- nodes.forEach(node => {
42
- dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
43
- });
44
-
45
- edges.forEach(edge => {
46
- dagreGraph.setEdge(edge.source, edge.target);
47
- });
48
-
49
- dagre.layout(dagreGraph);
50
-
51
- nodes.forEach(node => {
52
- const nodeWithPosition = dagreGraph.node(node.id);
53
- node.targetPosition = isHorizontal ? 'left' : 'top';
54
- node.sourcePosition = isHorizontal ? 'right' : 'bottom';
55
- node.position = {
56
- x: nodeWithPosition.x - nodeWidth / 2,
57
- y: nodeWithPosition.y - nodeHeight / 2,
58
- };
59
- return node;
60
- });
61
-
62
- return { nodes, edges };
63
- };
31
+ const setElementsLayout = (
32
+ nodes,
33
+ edges,
34
+ direction = 'LR',
35
+ nodeWidth = 800,
36
+ nodeHeight = 150,
37
+ ) => {
38
+ const isHorizontal = direction === 'TB';
39
+ dagreGraph.setGraph({ rankdir: direction });
40
+
41
+ nodes.forEach(node => {
42
+ dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
43
+ });
44
+
45
+ edges.forEach(edge => {
46
+ dagreGraph.setEdge(edge.source, edge.target);
47
+ });
48
+
49
+ dagre.layout(dagreGraph);
50
+
51
+ nodes.forEach(node => {
52
+ const nodeWithPosition = dagreGraph.node(node.id);
53
+ node.targetPosition = isHorizontal ? 'left' : 'top';
54
+ node.sourcePosition = isHorizontal ? 'right' : 'bottom';
55
+ node.position = {
56
+ x: nodeWithPosition.x - nodeWidth / 2,
57
+ y: nodeWithPosition.y - nodeHeight / 2,
58
+ };
59
+ return node;
60
+ });
61
+
62
+ return { nodes, edges };
63
+ };
64
64
 
65
+ useEffect(() => {
65
66
  const dagFetch = async () => {
66
67
  let upstreams = await DataJunctionAPI.upstreams(djNode.djNode.name);
67
68
  let downstreams = await DataJunctionAPI.downstreams(djNode.djNode.name);
68
- let djNodes = [...new Set([...upstreams, ...downstreams, djNode.djNode])];
69
+ var djNodes = [djNode.djNode];
70
+ for (const iterable of [upstreams, downstreams]) {
71
+ for (const item of iterable) {
72
+ djNodes.push(item);
73
+ }
74
+ }
69
75
  let edges = [];
70
76
  djNodes.forEach(obj => {
71
77
  obj.parents.forEach(parent => {
@@ -124,18 +130,18 @@ const NodeLineage = djNode => {
124
130
  // extent: 'parent',
125
131
  };
126
132
  });
127
-
133
+ console.log(djNodes);
128
134
  setNodes(nodes);
129
135
  setEdges(edges);
130
136
  setElementsLayout(nodes, edges);
131
137
  };
132
138
 
133
139
  dagFetch();
134
- }, [dagreGraph, djNode.djNode, setEdges, setNodes]);
140
+ }, []);
135
141
 
136
142
  const onConnect = useCallback(
137
143
  params => setEdges(eds => addEdge(params, eds)),
138
- [setEdges],
144
+ [],
139
145
  );
140
146
 
141
147
  return (
@@ -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
  );
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;