@urbanos/react-discovery-ui 2.1.46 → 2.1.48

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.
@@ -14,11 +14,11 @@ var _reactTabs = require("react-tabs");
14
14
  var _lodash = _interopRequireDefault(require("lodash"));
15
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
17
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
17
18
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
18
19
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
19
20
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
20
21
  function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
21
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
22
22
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
23
23
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
24
24
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -34,7 +34,8 @@ var DataTable = function DataTable(_ref) {
34
34
  var data = _ref.data,
35
35
  columns = _ref.columns,
36
36
  page = _ref.page,
37
- onNextPageClicked = _ref.onNextPageClicked;
37
+ onNextPageClicked = _ref.onNextPageClicked,
38
+ datasetName = _ref.datasetName;
38
39
  var _useState = (0, _react.useState)({
39
40
  pageIndex: page || 0,
40
41
  pageSize: 50
@@ -42,6 +43,14 @@ var DataTable = function DataTable(_ref) {
42
43
  _useState2 = _slicedToArray(_useState, 2),
43
44
  pagination = _useState2[0],
44
45
  setPagination = _useState2[1];
46
+ var _useState3 = (0, _react.useState)({
47
+ row: 0,
48
+ col: 0
49
+ }),
50
+ _useState4 = _slicedToArray(_useState3, 2),
51
+ focusedCell = _useState4[0],
52
+ setFocusedCell = _useState4[1];
53
+ var tableRef = (0, _react.useRef)(null);
45
54
  (0, _react.useEffect)(function () {
46
55
  setPagination(function (prev) {
47
56
  return _objectSpread(_objectSpread({}, prev), {}, {
@@ -65,33 +74,98 @@ var DataTable = function DataTable(_ref) {
65
74
  getCoreRowModel: (0, _reactTable.getCoreRowModel)(),
66
75
  getPaginationRowModel: (0, _reactTable.getPaginationRowModel)()
67
76
  });
77
+ var totalRows = table.getRowModel().rows.length + 1; // row 0 = header
78
+ var totalCols = columns.length;
79
+ var moveFocus = function moveFocus(newRow, newCol) {
80
+ var r = Math.max(0, Math.min(totalRows - 1, newRow));
81
+ var c = Math.max(0, Math.min(totalCols - 1, newCol));
82
+ setFocusedCell({
83
+ row: r,
84
+ col: c
85
+ });
86
+ var cell = tableRef.current && tableRef.current.querySelector("[data-row=\"".concat(r, "\"][data-col=\"").concat(c, "\"]"));
87
+ if (cell) cell.focus();
88
+ };
89
+ var handleKeyDown = function handleKeyDown(e) {
90
+ var row = focusedCell.row,
91
+ col = focusedCell.col;
92
+ var moves = {
93
+ ArrowUp: [row - 1, col],
94
+ ArrowDown: [row + 1, col],
95
+ ArrowLeft: [row, col - 1],
96
+ ArrowRight: [row, col + 1]
97
+ };
98
+ if (moves[e.key]) {
99
+ e.preventDefault();
100
+ moveFocus.apply(void 0, _toConsumableArray(moves[e.key]));
101
+ }
102
+ };
103
+ var tabIndex = function tabIndex(row, col) {
104
+ return focusedCell.row === row && focusedCell.col === col ? 0 : -1;
105
+ };
106
+ var onCellFocus = function onCellFocus(row, col) {
107
+ return setFocusedCell({
108
+ row: row,
109
+ col: col
110
+ });
111
+ };
68
112
  return /*#__PURE__*/_react.default.createElement("div", {
69
113
  style: {
70
114
  height: '400px',
71
- overflowY: 'auto'
115
+ overflow: 'auto'
72
116
  }
73
- }, /*#__PURE__*/_react.default.createElement("table", null, /*#__PURE__*/_react.default.createElement("thead", null, table.getHeaderGroups().map(function (headerGroup) {
117
+ }, /*#__PURE__*/_react.default.createElement("table", {
118
+ ref: tableRef,
119
+ style: {
120
+ minWidth: "".concat(columns.length * 120, "px")
121
+ },
122
+ onKeyDown: handleKeyDown
123
+ }, /*#__PURE__*/_react.default.createElement("caption", null, datasetName ? "".concat(datasetName, " Dataset Preview") : 'Dataset Preview'), /*#__PURE__*/_react.default.createElement("thead", null, table.getHeaderGroups().map(function (headerGroup) {
74
124
  return /*#__PURE__*/_react.default.createElement("tr", {
75
125
  key: headerGroup.id
76
- }, headerGroup.headers.map(function (header) {
126
+ }, headerGroup.headers.map(function (header, colIndex) {
77
127
  var _header$column$column;
78
128
  return /*#__PURE__*/_react.default.createElement("th", {
79
129
  key: header.id,
80
130
  scope: "col",
131
+ tabIndex: tabIndex(0, colIndex),
132
+ "data-row": 0,
133
+ "data-col": colIndex,
134
+ onFocus: function onFocus() {
135
+ return onCellFocus(0, colIndex);
136
+ },
81
137
  className: ((_header$column$column = header.column.columnDef.meta) === null || _header$column$column === void 0 ? void 0 : _header$column$column.headerClassName) || 'table-header'
82
138
  }, header.isPlaceholder ? null : (0, _reactTable.flexRender)(header.column.columnDef.header, header.getContext()));
83
139
  }));
84
140
  })), /*#__PURE__*/_react.default.createElement("tbody", null, table.getRowModel().rows.length === 0 ? /*#__PURE__*/_react.default.createElement("tr", null, /*#__PURE__*/_react.default.createElement("td", {
85
141
  colSpan: columns.length,
86
142
  className: "no-data-message"
87
- }, "No rows found")) : table.getRowModel().rows.map(function (row, i) {
143
+ }, "No rows found")) : table.getRowModel().rows.map(function (row, rowIndex) {
144
+ var tableRow = rowIndex + 1;
88
145
  return /*#__PURE__*/_react.default.createElement("tr", {
89
146
  key: row.id,
90
- className: i % 2 === 0 ? 'striped-row' : ''
91
- }, row.getVisibleCells().map(function (cell) {
92
- return /*#__PURE__*/_react.default.createElement("td", {
93
- key: cell.id
94
- }, (0, _reactTable.flexRender)(cell.column.columnDef.cell, cell.getContext()));
147
+ className: rowIndex % 2 === 0 ? 'striped-row' : ''
148
+ }, row.getVisibleCells().map(function (cell, colIndex) {
149
+ var content = (0, _reactTable.flexRender)(cell.column.columnDef.cell, cell.getContext());
150
+ return colIndex === 0 ? /*#__PURE__*/_react.default.createElement("th", {
151
+ key: cell.id,
152
+ scope: "row",
153
+ tabIndex: tabIndex(tableRow, colIndex),
154
+ "data-row": tableRow,
155
+ "data-col": colIndex,
156
+ onFocus: function onFocus() {
157
+ return onCellFocus(tableRow, colIndex);
158
+ },
159
+ className: "row-header"
160
+ }, content) : /*#__PURE__*/_react.default.createElement("td", {
161
+ key: cell.id,
162
+ tabIndex: tabIndex(tableRow, colIndex),
163
+ "data-row": tableRow,
164
+ "data-col": colIndex,
165
+ onFocus: function onFocus() {
166
+ return onCellFocus(tableRow, colIndex);
167
+ }
168
+ }, content);
95
169
  }));
96
170
  }))), /*#__PURE__*/_react.default.createElement("div", {
97
171
  className: "pagination"
@@ -186,10 +260,10 @@ var cleanseData = function cleanseData(data) {
186
260
  });
187
261
  };
188
262
  var _default = exports.default = function _default(props) {
189
- var _useState3 = (0, _react.useState)(0),
190
- _useState4 = _slicedToArray(_useState3, 2),
191
- index = _useState4[0],
192
- setIndex = _useState4[1];
263
+ var _useState5 = (0, _react.useState)(0),
264
+ _useState6 = _slicedToArray(_useState5, 2),
265
+ index = _useState6[0],
266
+ setIndex = _useState6[1];
193
267
  var isGeojson = props.format === 'geojson';
194
268
  var cleanData = isGeojson ? undefined : props.data ? cleanseData(props.data) : props.data;
195
269
  var columns = (0, _react.useMemo)(function () {
@@ -227,7 +301,8 @@ var _default = exports.default = function _default(props) {
227
301
  data: cleanData,
228
302
  columns: columns,
229
303
  page: props.page,
230
- onNextPageClicked: props.onNextPageClicked
304
+ onNextPageClicked: props.onNextPageClicked,
305
+ datasetName: props.datasetName
231
306
  }))), /*#__PURE__*/_react.default.createElement(_reactTabs.TabPanel, null, /*#__PURE__*/_react.default.createElement("div", {
232
307
  id: "data-view-raw"
233
308
  }, props.loading ? /*#__PURE__*/_react.default.createElement(_loadingElement.default, {
@@ -48,6 +48,11 @@
48
48
  text-align: left;
49
49
  font-weight: 800;
50
50
  }
51
+
52
+ tbody th.row-header {
53
+ font-weight: normal;
54
+ text-align: left;
55
+ }
51
56
  }
52
57
 
53
58
  #data-view-raw {
@@ -33,14 +33,16 @@ describe('data view', () => {
33
33
  })
34
34
 
35
35
  test('should render table rows including data for column names with dots', () => {
36
- const table_elements = subject.find('#data-view-table tbody td')
37
- const expected = [
38
- 'Joe', 'Smith', 'true', 'Joe Smith',
39
- 'Jane', 'Doe', 'false', 'Jane Doe'
40
- ]
41
- const actual = table_elements.map((x) => x.text())
36
+ const rowHeaders = subject.find('#data-view-table tbody .row-header').map(x => x.text())
37
+ const dataCells = subject.find('#data-view-table tbody td').map(x => x.text())
38
+ const actual = [...rowHeaders, ...dataCells]
42
39
 
43
- expect(actual).toContain(...expected)
40
+ expect(actual).toContain('Joe')
41
+ expect(actual).toContain('Smith')
42
+ expect(actual).toContain('true')
43
+ expect(actual).toContain('Jane')
44
+ expect(actual).toContain('Doe')
45
+ expect(actual).toContain('false')
44
46
  })
45
47
 
46
48
  test('should render two tabs', () => {
@@ -114,12 +116,10 @@ describe('data view', () => {
114
116
 
115
117
  const subject = mount(<DataView data={queryData} columns={columns} />)
116
118
 
117
- const cells = subject.find('#data-view-table tbody td')
118
- const actualValues = cells.map(c => c.text())
119
- expect(actualValues).toEqual([
120
- '{"value":1}', 'true', '[1]', '', '',
121
- '{"value":2}', 'false', '[2,3]', '', ''
122
- ])
119
+ const rowHeaders = subject.find('#data-view-table tbody .row-header').map(c => c.text())
120
+ const dataCells = subject.find('#data-view-table tbody td').map(c => c.text())
121
+ expect(rowHeaders).toEqual(['{"value":1}', '{"value":2}'])
122
+ expect(dataCells).toEqual(['true', '[1]', '', '', 'false', '[2,3]', '', ''])
123
123
  expect(subject.prop('data')).toEqual(queryData)
124
124
  })
125
125
 
@@ -139,11 +139,13 @@ describe('data view', () => {
139
139
  expect(headers).toContain('first.name')
140
140
  expect(headers).toContain('last.name')
141
141
 
142
- const cells = subject.find('#data-view-table tbody td').map(c => c.text())
143
- expect(cells).toContain('Mark')
144
- expect(cells).toContain('Johnson')
145
- expect(cells).toContain('George')
146
- expect(cells).toContain('Lakoff')
142
+ const rowHeaders = subject.find('#data-view-table tbody .row-header').map(c => c.text())
143
+ const dataCells = subject.find('#data-view-table tbody td').map(c => c.text())
144
+ const allCells = [...rowHeaders, ...dataCells]
145
+ expect(allCells).toContain('Mark')
146
+ expect(allCells).toContain('Johnson')
147
+ expect(allCells).toContain('George')
148
+ expect(allCells).toContain('Lakoff')
147
149
  })
148
150
  })
149
151
  })
@@ -11,9 +11,11 @@ var _selectors = require("../../store/selectors");
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
12
  var mapStateToProps = function mapStateToProps(state, _ref) {
13
13
  var format = _ref.format;
14
+ var dataset = (0, _selectors.getDataSet)(state);
14
15
  return {
15
16
  datasetPreview: (0, _selectors.getDataSetPreview)(state, format),
16
- previewLoading: state.presentation.previewLoading
17
+ previewLoading: state.presentation.previewLoading,
18
+ datasetName: dataset && dataset.title
17
19
  };
18
20
  };
19
21
  var mapDispatchToProps = function mapDispatchToProps(dispatch) {
@@ -50,7 +50,8 @@ var _default = exports.default = /*#__PURE__*/function (_Component) {
50
50
  data: data,
51
51
  columns: columns,
52
52
  loading: this.props.previewLoading,
53
- format: this.props.format
53
+ format: this.props.format,
54
+ datasetName: this.props.datasetName
54
55
  })));
55
56
  }
56
57
  }]);
@@ -12,8 +12,10 @@ var _visualizationSelectors = require("../../store/visualization-selectors");
12
12
  var _selectors = require("../../store/selectors");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  var mapStateToProps = function mapStateToProps(state) {
15
+ var dataset = (0, _selectors.getDataSet)(state);
15
16
  return {
16
17
  dataSources: (0, _querySelectors.getVisualizationDataSources)(state),
18
+ datasetName: dataset && dataset.title,
17
19
  recommendations: (0, _selectors.getDatasetRecommendations)(state),
18
20
  usedDatasets: (0, _visualizationSelectors.visualizationUsedDatasets)(state),
19
21
  datasetReferences: (0, _selectors.getDataSetReferences)(state),
@@ -21,6 +21,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
21
21
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
22
22
  var QueryView = function QueryView(props) {
23
23
  var dataSources = props.dataSources,
24
+ datasetName = props.datasetName,
24
25
  recommendations = props.recommendations,
25
26
  usedDatasets = props.usedDatasets,
26
27
  datasetReferences = props.datasetReferences,
@@ -74,7 +75,8 @@ var QueryView = function QueryView(props) {
74
75
  data: queryData,
75
76
  page: page,
76
77
  columns: Object.keys(dataSources),
77
- onNextPageClicked: onNextPageClicked
78
+ onNextPageClicked: onNextPageClicked,
79
+ datasetName: datasetName
78
80
  })));
79
81
  };
80
82
  var _default = exports.default = QueryView;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urbanos/react-discovery-ui",
3
- "version": "2.1.46",
3
+ "version": "2.1.48",
4
4
  "description": "React component for dataset discovery UI",
5
5
  "main": "./lib/ReactDiscoveryUI.js",
6
6
  "repository": {