datajunction-ui 0.0.1-a60 → 0.0.1-a61
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datajunction-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.1a61",
|
|
4
4
|
"description": "DataJunction Metrics Platform UI",
|
|
5
5
|
"module": "src/index.tsx",
|
|
6
6
|
"repository": {
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"coverageThreshold": {
|
|
166
166
|
"global": {
|
|
167
167
|
"statements": 87,
|
|
168
|
-
"branches":
|
|
168
|
+
"branches": 74,
|
|
169
169
|
"lines": 80,
|
|
170
170
|
"functions": 85
|
|
171
171
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default function AddNodeDropDown({ namespace }) {
|
|
2
|
+
return (
|
|
3
|
+
<span className="menu-link">
|
|
4
|
+
<span className="menu-title">
|
|
5
|
+
<div className="dropdown">
|
|
6
|
+
<span className="add_node">+ Add Node</span>
|
|
7
|
+
<div className="dropdown-content">
|
|
8
|
+
<a href={`/create/source`}>
|
|
9
|
+
<div className="node_type__source node_type_creation_heading">
|
|
10
|
+
Register Table
|
|
11
|
+
</div>
|
|
12
|
+
</a>
|
|
13
|
+
<a href={`/create/transform/${namespace}`}>
|
|
14
|
+
<div className="node_type__transform node_type_creation_heading">
|
|
15
|
+
Transform
|
|
16
|
+
</div>
|
|
17
|
+
</a>
|
|
18
|
+
<a href={`/create/metric/${namespace}`}>
|
|
19
|
+
<div className="node_type__metric node_type_creation_heading">
|
|
20
|
+
Metric
|
|
21
|
+
</div>
|
|
22
|
+
</a>
|
|
23
|
+
<a href={`/create/dimension/${namespace}`}>
|
|
24
|
+
<div className="node_type__dimension node_type_creation_heading">
|
|
25
|
+
Dimension
|
|
26
|
+
</div>
|
|
27
|
+
</a>
|
|
28
|
+
<a href={`/create/tag`}>
|
|
29
|
+
<div className="entity__tag node_type_creation_heading">
|
|
30
|
+
Tag
|
|
31
|
+
</div>
|
|
32
|
+
</a>
|
|
33
|
+
<a href={`/create/cube/${namespace}`}>
|
|
34
|
+
<div className="node_type__cube node_type_creation_heading">
|
|
35
|
+
Cube
|
|
36
|
+
</div>
|
|
37
|
+
</a>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</span>
|
|
41
|
+
</span>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -4,11 +4,18 @@ import { useContext, useEffect, useState } from 'react';
|
|
|
4
4
|
import NodeStatus from '../NodePage/NodeStatus';
|
|
5
5
|
import DJClientContext from '../../providers/djclient';
|
|
6
6
|
import Explorer from '../NamespacePage/Explorer';
|
|
7
|
+
import AddNodeDropdown from '../../components/AddNodeDropdown';
|
|
7
8
|
import NodeListActions from '../../components/NodeListActions';
|
|
8
9
|
import AddNamespacePopover from './AddNamespacePopover';
|
|
9
10
|
import 'styles/node-list.css';
|
|
11
|
+
import 'styles/sorted-table.css';
|
|
10
12
|
|
|
11
13
|
export function NamespacePage() {
|
|
14
|
+
const ASC = 'ascending';
|
|
15
|
+
const DESC = 'descending';
|
|
16
|
+
|
|
17
|
+
const fields = ['name', 'display_name', 'type', 'status', 'updated_at'];
|
|
18
|
+
|
|
12
19
|
const djClient = useContext(DJClientContext).DataJunctionAPI;
|
|
13
20
|
var { namespace } = useParams();
|
|
14
21
|
|
|
@@ -19,6 +26,38 @@ export function NamespacePage() {
|
|
|
19
26
|
|
|
20
27
|
const [namespaceHierarchy, setNamespaceHierarchy] = useState([]);
|
|
21
28
|
|
|
29
|
+
const [sortConfig, setSortConfig] = useState({ key: 'updated_at', direction: DESC });
|
|
30
|
+
const sortedNodes = React.useMemo(() => {
|
|
31
|
+
let sortableData = [...Object.values(state.nodes)];
|
|
32
|
+
if (sortConfig !== null) {
|
|
33
|
+
sortableData.sort((a, b) => {
|
|
34
|
+
if (a[sortConfig.key] < b[sortConfig.key]) {
|
|
35
|
+
return sortConfig.direction === ASC ? -1 : 1;
|
|
36
|
+
}
|
|
37
|
+
if (a[sortConfig.key] > b[sortConfig.key]) {
|
|
38
|
+
return sortConfig.direction === ASC ? 1 : -1;
|
|
39
|
+
}
|
|
40
|
+
return 0;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return sortableData;
|
|
44
|
+
}, [state.nodes, sortConfig]);
|
|
45
|
+
|
|
46
|
+
const requestSort = (key) => {
|
|
47
|
+
let direction = ASC;
|
|
48
|
+
if (sortConfig.key === key && sortConfig.direction === ASC) {
|
|
49
|
+
direction = DESC;
|
|
50
|
+
}
|
|
51
|
+
setSortConfig({ key, direction });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const getClassNamesFor = (name) => {
|
|
55
|
+
if (sortConfig.key === name) {
|
|
56
|
+
return sortConfig.direction;
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
};
|
|
60
|
+
|
|
22
61
|
const createNamespaceHierarchy = namespaceList => {
|
|
23
62
|
const hierarchy = [];
|
|
24
63
|
|
|
@@ -71,7 +110,7 @@ export function NamespacePage() {
|
|
|
71
110
|
fetchData().catch(console.error);
|
|
72
111
|
}, [djClient, namespace, namespaceHierarchy]);
|
|
73
112
|
|
|
74
|
-
const nodesList =
|
|
113
|
+
const nodesList = sortedNodes.map(node => (
|
|
75
114
|
<tr>
|
|
76
115
|
<td>
|
|
77
116
|
<a href={'/nodes/' + node.name} className="link-table">
|
|
@@ -97,9 +136,6 @@ export function NamespacePage() {
|
|
|
97
136
|
<td>
|
|
98
137
|
<NodeStatus node={node} revalidate={false} />
|
|
99
138
|
</td>
|
|
100
|
-
<td>
|
|
101
|
-
<span className="status">{node.mode}</span>
|
|
102
|
-
</td>
|
|
103
139
|
<td>
|
|
104
140
|
<span className="status">
|
|
105
141
|
{new Date(node.updated_at).toLocaleString('en-us')}
|
|
@@ -116,46 +152,7 @@ export function NamespacePage() {
|
|
|
116
152
|
<div className="card">
|
|
117
153
|
<div className="card-header">
|
|
118
154
|
<h2>Explore</h2>
|
|
119
|
-
|
|
120
|
-
<span className="menu-link">
|
|
121
|
-
<span className="menu-title">
|
|
122
|
-
<div className="dropdown">
|
|
123
|
-
<span className="add_node">+ Add Node</span>
|
|
124
|
-
<div className="dropdown-content">
|
|
125
|
-
<a href={`/create/source`}>
|
|
126
|
-
<div className="node_type__source node_type_creation_heading">
|
|
127
|
-
Register Table
|
|
128
|
-
</div>
|
|
129
|
-
</a>
|
|
130
|
-
<a href={`/create/transform/${namespace}`}>
|
|
131
|
-
<div className="node_type__transform node_type_creation_heading">
|
|
132
|
-
Transform
|
|
133
|
-
</div>
|
|
134
|
-
</a>
|
|
135
|
-
<a href={`/create/metric/${namespace}`}>
|
|
136
|
-
<div className="node_type__metric node_type_creation_heading">
|
|
137
|
-
Metric
|
|
138
|
-
</div>
|
|
139
|
-
</a>
|
|
140
|
-
<a href={`/create/dimension/${namespace}`}>
|
|
141
|
-
<div className="node_type__dimension node_type_creation_heading">
|
|
142
|
-
Dimension
|
|
143
|
-
</div>
|
|
144
|
-
</a>
|
|
145
|
-
<a href={`/create/tag`}>
|
|
146
|
-
<div className="entity__tag node_type_creation_heading">
|
|
147
|
-
Tag
|
|
148
|
-
</div>
|
|
149
|
-
</a>
|
|
150
|
-
<a href={`/create/cube/${namespace}`}>
|
|
151
|
-
<div className="node_type__cube node_type_creation_heading">
|
|
152
|
-
Cube
|
|
153
|
-
</div>
|
|
154
|
-
</a>
|
|
155
|
-
</div>
|
|
156
|
-
</div>
|
|
157
|
-
</span>
|
|
158
|
-
</span>
|
|
155
|
+
<AddNodeDropdown namespace={namespace} />
|
|
159
156
|
<div className="table-responsive">
|
|
160
157
|
<div className={`sidebar`}>
|
|
161
158
|
<span
|
|
@@ -182,12 +179,15 @@ export function NamespacePage() {
|
|
|
182
179
|
<table className="card-table table">
|
|
183
180
|
<thead>
|
|
184
181
|
<tr>
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
182
|
+
{fields.map(field => {
|
|
183
|
+
return (
|
|
184
|
+
<th>
|
|
185
|
+
<button type="button" onClick={() => requestSort(field)} className={'sortable ' + getClassNamesFor(field)}>
|
|
186
|
+
{field.replace('_', ' ')}
|
|
187
|
+
</button>
|
|
188
|
+
</th>
|
|
189
|
+
);
|
|
190
|
+
})}
|
|
191
191
|
<th>Actions</th>
|
|
192
192
|
</tr>
|
|
193
193
|
</thead>
|
package/src/styles/index.css
CHANGED
|
@@ -730,6 +730,11 @@ pre {
|
|
|
730
730
|
margin: 0;
|
|
731
731
|
list-style: none;
|
|
732
732
|
}
|
|
733
|
+
.menu-link {
|
|
734
|
+
display: inline-grid;
|
|
735
|
+
margin: 2em 1em 0 0;
|
|
736
|
+
float: right;
|
|
737
|
+
}
|
|
733
738
|
.menu-item .menu-link {
|
|
734
739
|
cursor: pointer;
|
|
735
740
|
align-items: center;
|
|
@@ -773,6 +778,7 @@ pre {
|
|
|
773
778
|
|
|
774
779
|
.card-header h2 {
|
|
775
780
|
font-family: 'Jost';
|
|
781
|
+
display: inline-block;
|
|
776
782
|
}
|
|
777
783
|
|
|
778
784
|
.text-gray-400 {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.sortable {
|
|
2
|
+
background: none;
|
|
3
|
+
border: none;
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
font-weight: bold;
|
|
6
|
+
font-family: inherit;
|
|
7
|
+
color: inherit;
|
|
8
|
+
text-transform: uppercase;
|
|
9
|
+
}
|
|
10
|
+
.sortable.ascending::after {
|
|
11
|
+
content: ' ▲';
|
|
12
|
+
}
|
|
13
|
+
.sortable.descending::after {
|
|
14
|
+
content: ' ▼';
|
|
15
|
+
}
|