Skip to content

Commit c0aa407

Browse files
authored
feat: Add row number column to data browser (#2878)
1 parent 2064e68 commit c0aa407

File tree

7 files changed

+172
-75
lines changed

7 files changed

+172
-75
lines changed

src/components/BrowserRow/BrowserRow.react.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export default class BrowserRow extends Component {
3333
row,
3434
rowValue,
3535
rowWidth,
36+
showRowNumber,
37+
rowNumberWidth,
38+
skip,
3639
selection,
3740
selectRow,
3841
setCopyableValue,
@@ -79,17 +82,13 @@ export default class BrowserRow extends Component {
7982
className={styles.checkCell}
8083
onMouseUp={onMouseUpRowCheckBox}
8184
onMouseOver={() => onMouseOverRowCheckBox(obj.id)}
82-
style={
83-
freezeIndex >= 0
84-
? {
85-
position: 'sticky',
86-
left: 0,
87-
zIndex: 1,
88-
background: rowBackground,
89-
borderBottom: '1px solid #e3e3ea',
90-
}
91-
: {}
92-
}
85+
style={{
86+
position: 'sticky',
87+
left: 0,
88+
zIndex: 1,
89+
background: rowBackground,
90+
borderBottom: '1px solid #e3e3ea',
91+
}}
9392
>
9493
<input
9594
type="checkbox"
@@ -98,6 +97,21 @@ export default class BrowserRow extends Component {
9897
onMouseDown={e => onMouseDownRowCheckBox(e.target.checked)}
9998
/>
10099
</span>
100+
{showRowNumber && (
101+
<span
102+
className={styles.rowNumberCell}
103+
style={{
104+
position: 'sticky',
105+
left: 30,
106+
zIndex: 1,
107+
background: rowBackground,
108+
borderBottom: '1px solid #e3e3ea',
109+
width: rowNumberWidth,
110+
}}
111+
>
112+
{row >= 0 ? (skip + row + 1).toLocaleString() : ''}
113+
</span>
114+
)}
101115
{order.map(({ name, width, visible }, j) => {
102116
if (!visible) {
103117
return null;

src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,23 @@ import { DndProvider } from 'react-dnd';
1515
export default class DataBrowserHeaderBar extends React.Component {
1616
handleContextMenu = (index, event) => {
1717
event.preventDefault();
18-
const { freezeIndex, freezeColumns, unfreezeColumns, setContextMenu } = this.props;
19-
const items =
18+
const {
19+
freezeIndex,
20+
freezeColumns,
21+
unfreezeColumns,
22+
setContextMenu,
23+
showRowNumber,
24+
setShowRowNumber,
25+
} = this.props;
26+
const items = [
27+
{
28+
text: showRowNumber ? 'Hide row number' : 'Display row number',
29+
callback: () => setShowRowNumber(!showRowNumber),
30+
},
2031
freezeIndex >= 0 && index <= freezeIndex
21-
? [{ text: 'Unfreeze column', callback: () => unfreezeColumns() }]
22-
: [{ text: 'Freeze column', callback: () => freezeColumns(index) }];
32+
? { text: 'Unfreeze column', callback: () => unfreezeColumns() }
33+
: { text: 'Freeze column', callback: () => freezeColumns(index) },
34+
];
2335
setContextMenu(event.pageX, event.pageY, items);
2436
};
2537

@@ -39,19 +51,33 @@ export default class DataBrowserHeaderBar extends React.Component {
3951
stickyLefts,
4052
handleLefts,
4153
freezeIndex,
54+
showRowNumber,
55+
rowNumberWidth,
4256
} = this.props;
4357
const elements = [
4458
<div
4559
key="check"
4660
className={[styles.wrap, styles.check].join(' ')}
47-
style={freezeIndex >= 0 ? { position: 'sticky', left: 0, zIndex: 11 } : {}}
61+
style={{ position: 'sticky', left: 0, zIndex: 11 }}
4862
>
4963
{readonly ? null : (
5064
<input type="checkbox" checked={selected} onChange={e => selectAll(e.target.checked)} />
5165
)}
5266
</div>,
5367
];
5468

69+
if (showRowNumber) {
70+
elements.push(
71+
<div
72+
key="rowNumber"
73+
className={[styles.wrap, styles.rowNumber].join(' ')}
74+
style={{ position: 'sticky', left: 30, zIndex: 11, width: rowNumberWidth }}
75+
>
76+
#
77+
</div>
78+
);
79+
}
80+
5581
headers.forEach(({ width, name, type, targetClass, order, visible, preventSort }, i) => {
5682
if (!visible) {
5783
return;

src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
display: inline-block;
1919
min-width: 100%;
2020
// to resolve rendering issue with retina displays
21-
-webkit-transform: translate3d(0,0,0);
21+
-webkit-transform: translate3d(0, 0, 0);
2222
}
2323

2424
.wrap {
@@ -53,7 +53,19 @@
5353
vertical-align: top;
5454
text-align: center;
5555
width: 30px;
56-
background: rgb(114, 111, 133)
56+
background: rgb(114, 111, 133);
57+
}
58+
59+
.rowNumber {
60+
line-height: 30px;
61+
height: 30px;
62+
vertical-align: top;
63+
text-align: center;
64+
background: rgb(114, 111, 133);
65+
color: #A2A6B1;
66+
font-size: 12px;
67+
padding: 0 4px;
68+
box-sizing: border-box;
5769
}
5870

5971
.handle {
@@ -90,20 +102,19 @@
90102
border-top: 1px solid #e3e3ea;
91103
border-bottom: 1px solid #e3e3ea;
92104
height: 30px;
93-
width:100%;
105+
width: 100%;
94106
vertical-align: middle;
95107
padding-left: 2px;
96108
margin-top: 30px;
97109
line-height: 31px;
98110
animation: skeleton-loading 1s linear infinite alternate;
99111
}
100-
112+
101113
@keyframes skeleton-loading {
102114
0% {
103-
background-color:#ffffff;
115+
background-color: #ffffff;
104116
}
105117
100% {
106118
background-color: #e3e3ea;
107-
108119
}
109120
}

src/dashboard/Data/Browser/Browser.react.js

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ class Browser extends DashboardView {
661661
}
662662
obj.save(null, { useMasterKey }).then(
663663
objectSaved => {
664-
const msg = objectSaved.className + ' with id \'' + objectSaved.id + '\' created';
664+
const msg = `${objectSaved.className} with id '${objectSaved.id}' created`;
665665
this.showNote(msg, false);
666666

667667
const state = { data: this.state.data };
@@ -764,7 +764,7 @@ class Browser extends DashboardView {
764764

765765
obj.save(null, { useMasterKey: true }).then(
766766
objectSaved => {
767-
const msg = objectSaved.className + ' with id \'' + objectSaved.id + '\' ' + 'created';
767+
const msg = `${objectSaved.className} with id '${objectSaved.id}' created`;
768768
this.showNote(msg, false);
769769

770770
const state = {
@@ -908,7 +908,7 @@ class Browser extends DashboardView {
908908
const { useMasterKey, skip, limit } = this.state;
909909
this.setState({
910910
data: null,
911-
})
911+
});
912912
const query = await queryFromFilters(source, filters);
913913
const sortDir = this.state.ordering[0] === '-' ? '-' : '+';
914914
const field = this.state.ordering.substr(sortDir === '-' ? 1 : 0);
@@ -1270,7 +1270,7 @@ class Browser extends DashboardView {
12701270
const { useMasterKey } = this.state;
12711271
obj.save(null, { useMasterKey }).then(
12721272
objectSaved => {
1273-
const msg = objectSaved.className + ' with id \'' + objectSaved.id + '\' updated';
1273+
const msg = `${objectSaved.className} with id '${objectSaved.id}' updated`;
12741274
this.showNote(msg, false);
12751275

12761276
const state = {
@@ -1398,9 +1398,9 @@ class Browser extends DashboardView {
13981398
let deletedNote;
13991399

14001400
if (toDeleteObjectIds.length == 1) {
1401-
deletedNote = className + ' with id \'' + toDeleteObjectIds[0] + '\' deleted';
1401+
deletedNote = `${className} with id '${toDeleteObjectIds[0]}' deleted`;
14021402
} else {
1403-
deletedNote = toDeleteObjectIds.length + ' ' + className + ' objects deleted';
1403+
deletedNote = `${toDeleteObjectIds.length} ${className} objects deleted`;
14041404
}
14051405

14061406
this.showNote(deletedNote, false);
@@ -1426,27 +1426,21 @@ class Browser extends DashboardView {
14261426
if (error.code === Parse.Error.AGGREGATE_ERROR) {
14271427
if (error.errors.length == 1) {
14281428
errorDeletingNote =
1429-
'Error deleting ' + className + ' with id \'' + error.errors[0].object.id + '\'';
1429+
`Error deleting ${className} with id '${error.errors[0].object.id}'`;
14301430
} else if (error.errors.length < toDeleteObjectIds.length) {
14311431
errorDeletingNote =
1432-
'Error deleting ' +
1433-
error.errors.length +
1434-
' out of ' +
1435-
toDeleteObjectIds.length +
1436-
' ' +
1437-
className +
1438-
' objects';
1432+
`Error deleting ${error.errors.length} out of ${toDeleteObjectIds.length} ${className} objects`;
14391433
} else {
14401434
errorDeletingNote =
1441-
'Error deleting all ' + error.errors.length + ' ' + className + ' objects';
1435+
`Error deleting all ${error.errors.length} ${className} objects`;
14421436
}
14431437
} else {
14441438
if (toDeleteObjectIds.length == 1) {
14451439
errorDeletingNote =
1446-
'Error deleting ' + className + ' with id \'' + toDeleteObjectIds[0] + '\'';
1440+
`Error deleting ${className} with id '${toDeleteObjectIds[0]}'`;
14471441
} else {
14481442
errorDeletingNote =
1449-
'Error deleting ' + toDeleteObjectIds.length + ' ' + className + ' objects';
1443+
`Error deleting ${toDeleteObjectIds.length} ${className} objects`;
14501444
}
14511445
}
14521446

@@ -1598,13 +1592,15 @@ class Browser extends DashboardView {
15981592
script.cloudCodeFunction,
15991593
{ object: object.toPointer() },
16001594
{ useMasterKey: true }
1601-
).then(response => ({
1602-
objectId: object.id,
1603-
response,
1604-
})).catch(error => ({
1605-
objectId: object.id,
1606-
error,
1607-
}))
1595+
)
1596+
.then(response => ({
1597+
objectId: object.id,
1598+
response,
1599+
}))
1600+
.catch(error => ({
1601+
objectId: object.id,
1602+
error,
1603+
}))
16081604
);
16091605

16101606
const results = await Promise.all(promises);
@@ -1631,12 +1627,18 @@ class Browser extends DashboardView {
16311627
totalErrorCount += batchErrorCount;
16321628

16331629
if (objects.length > 1) {
1634-
this.showNote(`Ran script "${script.title}" on ${batch.length} objects in batch ${batchCount}/${totalBatchCount} with ${batchErrorCount} errors.`, batchErrorCount > 0);
1630+
this.showNote(
1631+
`Ran script "${script.title}" on ${batch.length} objects in batch ${batchCount}/${totalBatchCount} with ${batchErrorCount} errors.`,
1632+
batchErrorCount > 0
1633+
);
16351634
}
16361635
}
16371636

16381637
if (objects.length > 1) {
1639-
this.showNote(`Ran script "${script.title}" on ${objects.length} objects in ${batchCount} batches with ${totalErrorCount} errors.`, totalErrorCount > 0);
1638+
this.showNote(
1639+
`Ran script "${script.title}" on ${objects.length} objects in ${batchCount} batches with ${totalErrorCount} errors.`,
1640+
totalErrorCount > 0
1641+
);
16401642
}
16411643
this.refresh();
16421644
} catch (e) {
@@ -1957,7 +1959,7 @@ class Browser extends DashboardView {
19571959
}}
19581960
removeFilter={filter => {
19591961
this.resetPage();
1960-
this.removeFilter(filter)
1962+
this.removeFilter(filter);
19611963
}}
19621964
classClicked={() => {
19631965
this.resetPage();
@@ -1978,7 +1980,7 @@ class Browser extends DashboardView {
19781980
// Scroll to top
19791981
window.scrollTo({
19801982
top: 0,
1981-
behavior: 'smooth'
1983+
behavior: 'smooth',
19821984
});
19831985

19841986
// Reset pagination to page 1
@@ -2201,6 +2203,7 @@ class Browser extends DashboardView {
22012203
errorAggregatedData={this.state.errorAggregatedData}
22022204
appName={this.props.params.appId}
22032205
limit={this.state.limit}
2206+
skip={this.state.skip}
22042207
/>
22052208
<BrowserFooter
22062209
skip={this.state.skip}

0 commit comments

Comments
 (0)