Skip to content

Commit bb8eabd

Browse files
committed
fix: improve views table usability
1 parent 6ed37ba commit bb8eabd

File tree

2 files changed

+101
-42
lines changed

2 files changed

+101
-42
lines changed

src/dashboard/Data/Views/Views.react.js

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import CategoryList from 'components/CategoryList/CategoryList.react';
22
import SidebarAction from 'components/Sidebar/SidebarAction';
3-
import TableHeader from 'components/Table/TableHeader.react';
43
import TableView from 'dashboard/TableView.react';
54
import Toolbar from 'components/Toolbar/Toolbar.react';
65
import Parse from 'parse';
76
import React from 'react';
87
import Notification from 'dashboard/Data/Browser/Notification.react';
9-
import Pill from 'components/Pill/Pill.react';
8+
import Icon from 'components/Icon/Icon.react';
9+
import DragHandle from 'components/DragHandle/DragHandle.react';
1010
import CreateViewDialog from './CreateViewDialog.react';
1111
import * as ViewPreferences from 'lib/ViewPreferences';
1212
import generatePath from 'lib/generatePath';
1313
import { withRouter } from 'lib/withRouter';
1414
import subscribeTo from 'lib/subscribeTo';
1515
import { ActionTypes as SchemaActionTypes } from 'lib/stores/SchemaStore';
16+
import styles from './Views.scss';
1617

17-
const BROWSER_LAST_LOCATION = 'brower_last_location';
1818

1919
export default
2020
@subscribeTo('Schema', 'schema')
@@ -95,11 +95,10 @@ class Views extends TableView {
9595
.aggregate(view.query, { useMasterKey: true })
9696
.then(results => {
9797
const columns = {};
98+
const computeWidth = str =>
99+
Math.min(100, Math.max((String(str).length + 2) * 8, 40));
98100
results.forEach(item => {
99101
Object.keys(item).forEach(key => {
100-
if (columns[key]) {
101-
return;
102-
}
103102
const val = item[key];
104103
let type = 'String';
105104
if (typeof val === 'number') {
@@ -119,13 +118,23 @@ class Views extends TableView {
119118
type = 'Object';
120119
}
121120
}
122-
columns[key] = { type };
121+
const content =
122+
type === 'Pointer'
123+
? val.objectId
124+
: type === 'Object'
125+
? JSON.stringify(val)
126+
: val;
127+
const width = computeWidth(content || key);
128+
if (!columns[key]) {
129+
columns[key] = { type, width };
130+
} else if (width > columns[key].width) {
131+
columns[key].width = width;
132+
}
133+
});
123134
});
124-
});
125-
const colNames = Object.keys(columns);
126-
const width = colNames.length > 0 ? 100 / colNames.length : 0;
127-
const order = colNames.map(name => ({ name, width }));
128-
this.setState({ data: results, order, columns });
135+
const colNames = Object.keys(columns);
136+
const order = colNames.map(name => ({ name, width: columns[name].width }));
137+
this.setState({ data: results, order, columns });
129138
})
130139
.catch(error => {
131140
this.showNote(
@@ -142,7 +151,7 @@ class Views extends TableView {
142151

143152
renderRow(row) {
144153
return (
145-
<tr key={JSON.stringify(row)}>
154+
<tr key={JSON.stringify(row)} className={styles.tableRow}>
146155
{this.state.order.map(({ name, width }) => {
147156
const value = row[name];
148157
const type = this.state.columns[name]?.type;
@@ -151,21 +160,21 @@ class Views extends TableView {
151160
const id = value.objectId;
152161
const className = value.className;
153162
content = (
154-
<Pill
155-
value={id}
156-
followClick={true}
157-
onClick={() =>
158-
this.handlePointerClick({ className, id })
159-
}
160-
/>
163+
<span
164+
className={styles.pointerLink}
165+
onClick={() => this.handlePointerClick({ className, id })}
166+
>
167+
{id}
168+
<Icon name="right-outline" width={12} height={12} fill="#1669a1" />
169+
</span>
161170
);
162171
} else if (type === 'Object') {
163172
content = JSON.stringify(value);
164173
} else {
165174
content = String(value);
166175
}
167176
return (
168-
<td key={name} style={{ width: width + '%' }}>
177+
<td key={name} className={styles.cell} style={{ width }}>
169178
{content}
170179
</td>
171180
);
@@ -174,11 +183,21 @@ class Views extends TableView {
174183
);
175184
}
176185

186+
handleResize(index, delta) {
187+
this.setState(({ order }) => {
188+
const newOrder = [...order];
189+
const next = Math.max(40, newOrder[index].width + delta);
190+
newOrder[index] = { ...newOrder[index], width: next };
191+
return { order: newOrder };
192+
});
193+
}
194+
177195
renderHeaders() {
178-
return this.state.order.map(({ name, width }) => (
179-
<TableHeader key={name} width={width}>
196+
return this.state.order.map(({ name, width }, i) => (
197+
<div key={name} className={styles.headerWrap} style={{ width }}>
180198
{name}
181-
</TableHeader>
199+
<DragHandle className={styles.handle} onDrag={delta => this.handleResize(i, delta)} />
200+
</div>
182201
));
183202
}
184203

@@ -258,24 +277,6 @@ class Views extends TableView {
258277
this.context,
259278
`browser/${className}?filters=${encodeURIComponent(filters)}`
260279
);
261-
try {
262-
const existing = JSON.parse(
263-
window.localStorage.getItem(BROWSER_LAST_LOCATION)
264-
) || [];
265-
const updated = existing.filter(
266-
e => e.appId !== this.context.applicationId
267-
);
268-
updated.push({
269-
appId: this.context.applicationId,
270-
location: path,
271-
});
272-
window.localStorage.setItem(
273-
BROWSER_LAST_LOCATION,
274-
JSON.stringify(updated)
275-
);
276-
} catch {
277-
// ignore write errors
278-
}
279280
this.props.navigate(path);
280281
}
281282

src/dashboard/Data/Views/Views.scss

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
@import 'stylesheets/globals.scss';
2+
3+
.headerWrap {
4+
display: inline-block;
5+
vertical-align: top;
6+
background: #66637A;
7+
color: white;
8+
line-height: 30px;
9+
padding: 0 16px;
10+
border-right: 1px solid #e3e3ea;
11+
position: relative;
12+
white-space: nowrap;
13+
max-width: 100px;
14+
overflow: hidden;
15+
text-overflow: ellipsis;
16+
}
17+
18+
.handle {
19+
position: absolute;
20+
top: 0;
21+
right: -4px;
22+
width: 8px;
23+
height: 30px;
24+
cursor: ew-resize;
25+
}
26+
27+
.tableRow {
28+
@include MonospaceFont;
29+
font-size: 12px;
30+
white-space: nowrap;
31+
height: 30px;
32+
border-bottom: 1px solid #e3e3ea;
33+
}
34+
35+
.tableRow:nth-child(odd) {
36+
background: #f4f5f7;
37+
}
38+
39+
.cell {
40+
line-height: 30px;
41+
padding: 10px 16px;
42+
border-right: 1px solid #e3e3ea;
43+
max-width: 100px;
44+
overflow: hidden;
45+
text-overflow: ellipsis;
46+
white-space: nowrap;
47+
}
48+
49+
.pointerLink {
50+
display: inline-flex;
51+
align-items: center;
52+
cursor: pointer;
53+
54+
svg {
55+
margin-left: 4px;
56+
transform: rotate(316deg);
57+
}
58+
}

0 commit comments

Comments
 (0)