Skip to content

Commit 98da372

Browse files
committed
EditRowDialog - picker for pointer and relation
1 parent eb2e714 commit 98da372

File tree

18 files changed

+754
-108
lines changed

18 files changed

+754
-108
lines changed

src/components/BrowserCell/BrowserCell.react.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ export default class BrowserCell extends Component {
2424
componentDidUpdate() {
2525
if (this.props.current) {
2626
const node = this.cellRef.current;
27+
const { setRelation } = this.props;
2728
const { left, right, bottom, top } = node.getBoundingClientRect();
2829

2930
// Takes into consideration Sidebar width when over 980px wide.
30-
const leftBoundary = window.innerWidth > 980 ? 300 : 0;
31+
// If setRelation is undefined, DataBrowser is used as ObjectPicker, so it does not have a sidebar.
32+
const leftBoundary = window.innerWidth > 980 && setRelation ? 300 : 0;
3133

3234
// BrowserToolbar + DataBrowserHeader height
3335
const topBoundary = 126;
@@ -89,10 +91,12 @@ export default class BrowserCell extends Component {
8991
object.id = value.objectId;
9092
value = object;
9193
}
92-
content = (
94+
content = onPointerClick ? (
9395
<a href='javascript:;' onClick={onPointerClick.bind(undefined, value)}>
9496
<Pill value={value.id} />
9597
</a>
98+
) : (
99+
value.id
96100
);
97101
this.copyableValue = value.id;
98102
} else if (type === 'Date') {
@@ -136,10 +140,12 @@ export default class BrowserCell extends Component {
136140
} else if (type === 'Polygon') {
137141
this.copyableValue = content = value.coordinates.map(coord => `(${coord})`)
138142
} else if (type === 'Relation') {
139-
content = (
143+
content = setRelation ? (
140144
<div style={{ textAlign: 'center', cursor: 'pointer' }}>
141145
<Pill onClick={() => setRelation(value)} value='View relation' />
142146
</div>
147+
) : (
148+
'Relation'
143149
);
144150
this.copyableValue = undefined;
145151
}
@@ -158,7 +164,7 @@ export default class BrowserCell extends Component {
158164
}}
159165
onDoubleClick={() => {
160166
// Since objectId can't be edited, double click event opens edit row dialog
161-
if (name === 'objectId') {
167+
if (name === 'objectId' && onEditSelectedRow) {
162168
onEditSelectedRow(true, value);
163169
} else if (type !== 'Relation') {
164170
onEditChange(true)

src/components/BrowserFilter/BrowserFilter.react.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ import styles from 'components/BrowserFilter/BrowserFilter.scss';
1818
import { List, Map } from 'immutable';
1919

2020
const BLACKLISTED_FILTERS = [ 'containsAny', 'doesNotContainAny' ];
21+
const POPOVER_CONTENT_ID = 'browserFilterPopover';
2122

2223
export default class BrowserFilter extends React.Component {
23-
constructor() {
24-
super();
24+
constructor(props) {
25+
super(props);
2526

2627
this.state = {
2728
open: false,
2829
filters: new List(),
30+
blacklistedFilters: BLACKLISTED_FILTERS.concat(props.blacklistedFilters)
2931
};
3032
this.toggle = this.toggle.bind(this)
3133
}
@@ -43,7 +45,7 @@ export default class BrowserFilter extends React.Component {
4345
toggle() {
4446
let filters = this.props.filters;
4547
if (this.props.filters.size === 0) {
46-
let available = Filters.availableFilters(this.props.schema, null, BLACKLISTED_FILTERS);
48+
let available = Filters.availableFilters(this.props.schema, null, this.state.blacklistedFilters);
4749
let field = Object.keys(available)[0];
4850
filters = new List([new Map({ field: field, constraint: available[field][0] })]);
4951
}
@@ -55,7 +57,7 @@ export default class BrowserFilter extends React.Component {
5557
}
5658

5759
addRow() {
58-
let available = Filters.availableFilters(this.props.schema, this.state.filters, BLACKLISTED_FILTERS);
60+
let available = Filters.availableFilters(this.props.schema, this.state.filters, this.state.blacklistedFilters);
5961
let field = Object.keys(available)[0];
6062
this.setState(({ filters }) => ({
6163
filters: filters.push(new Map({ field: field, constraint: available[field][0] })),
@@ -92,12 +94,12 @@ export default class BrowserFilter extends React.Component {
9294
}
9395
let available = Filters.availableFilters(this.props.schema, this.state.filters);
9496
popover = (
95-
<Popover fixed={true} position={position} onExternalClick={this.toggle}>
96-
<div className={popoverStyle.join(' ')} onClick={() => this.props.setCurrent(null)}>
97+
<Popover fixed={true} position={position} onExternalClick={this.toggle} contentId={POPOVER_CONTENT_ID}>
98+
<div className={popoverStyle.join(' ')} onClick={() => this.props.setCurrent(null)} id={POPOVER_CONTENT_ID}>
9799
<div onClick={this.toggle} style={{ cursor: 'pointer', width: this.node.clientWidth, height: this.node.clientHeight }}></div>
98100
<div className={styles.body}>
99101
<Filter
100-
blacklist={BLACKLISTED_FILTERS}
102+
blacklist={this.state.blacklistedFilters}
101103
schema={this.props.schema}
102104
filters={this.state.filters}
103105
onChange={(filters) => this.setState({ filters: filters })}

src/components/BrowserFilter/BrowserFilter.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@
6868
}
6969
}
7070

71+
.objectPickerContent {
72+
.entry svg {
73+
fill: rgba(0, 0, 0, 0.3);
74+
}
75+
}
76+
7177
.body {
7278
position: absolute;
7379
top: 30px;

src/components/ChromeDropdown/ChromeDropdown.react.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default class ChromeDropdown extends React.Component {
7777
widthStyle = { width: measuredWidth };
7878
content = (
7979
<Popover fixed={true} position={position} onExternalClick={() => this.setState({ open: false })}>
80-
<div style={widthStyle} className={[styles.menu, styles[color]].join(' ')}>
80+
<div style={widthStyle} className={[styles.menu, styles[color], "chromeDropdown"].join(' ')}>
8181
{this.props.options.map((o) => {
8282
let key = o;
8383
let value = o;

src/components/ColumnsConfiguration/ColumnsConfiguration.react.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import Icon from 'components/Icon/Icon.react';
1010
import Popover from 'components/Popover/Popover.react';
1111
import Position from 'lib/Position';
1212

13+
const POPOVER_CONTENT_ID = 'columnsConfigurationPopover';
14+
1315
export default class ColumnsConfiguration extends React.Component {
1416
constructor() {
1517
super();
@@ -57,8 +59,8 @@ export default class ColumnsConfiguration extends React.Component {
5759
let popover = null;
5860
if (this.state.open) {
5961
popover = (
60-
<Popover fixed={true} position={Position.inDocument(this.node)} onExternalClick={this.toggle.bind(this)}>
61-
<div className={styles.popover}>
62+
<Popover fixed={true} position={Position.inDocument(this.node)} onExternalClick={this.toggle.bind(this)} contentId={POPOVER_CONTENT_ID}>
63+
<div className={styles.popover} id={POPOVER_CONTENT_ID}>
6264
{title}
6365
<div className={styles.body}>
6466
<div className={styles.columnConfigContainer}>

src/components/ColumnsConfiguration/ColumnsConfiguration.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
}
4343
}
4444

45+
.objectPickerContent {
46+
.entry svg {
47+
fill: rgba(0, 0, 0, 0.3);
48+
}
49+
}
50+
4551
.body {
4652
color: white;
4753
position: absolute;

src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,27 @@ export default class DataBrowserHeaderBar extends React.Component {
6060
);
6161
});
6262

63-
let finalStyle = {};
64-
if (headers.length % 2) {
65-
finalStyle.background = 'rgba(224,224,234,0.10)';
63+
if (onAddColumn) {
64+
let finalStyle = {};
65+
if (headers.length % 2) {
66+
finalStyle.background = 'rgba(224,224,234,0.10)';
67+
}
68+
69+
elements.push(
70+
readonly || preventSchemaEdits ? null : (
71+
<div key='add' className={styles.addColumn} style={finalStyle}>
72+
<a
73+
href='javascript:;'
74+
role='button'
75+
className={styles.addColumnButton}
76+
onClick={onAddColumn}>
77+
Add a new column
78+
</a>
79+
</div>
80+
)
81+
);
6682
}
6783

68-
elements.push(
69-
readonly || preventSchemaEdits ? null : (
70-
<div key='add' className={styles.addColumn} style={finalStyle}>
71-
<a
72-
href='javascript:;'
73-
role='button'
74-
className={styles.addColumnButton}
75-
onClick={onAddColumn}>
76-
Add a new column
77-
</a>
78-
</div>
79-
)
80-
);
81-
8284
return (
8385
<DndProvider backend={HTML5Backend}>
8486
<div className={styles.bar}>{elements}</div>

src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,11 @@
6464
margin: 0 -4px;
6565
cursor: ew-resize;
6666
}
67+
68+
.pickerPointer {
69+
.check {
70+
input {
71+
display: none;
72+
}
73+
}
74+
}

src/components/Popover/Popover.react.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import ReactDOM from 'react-dom';
1212
import styles from 'components/Popover/Popover.scss';
1313

1414
// We use this component to proxy the current tree's context (just the React Router history for now) to the new tree
15-
class ContextProxy extends React.Component {
15+
export class ContextProxy extends React.Component {
1616
getChildContext() {
1717
return this.props.cx;
1818
}
@@ -24,7 +24,8 @@ class ContextProxy extends React.Component {
2424

2525
ContextProxy.childContextTypes = {
2626
history: PropTypes.object,
27-
router: PropTypes.object
27+
router: PropTypes.object,
28+
currentApp: PropTypes.object
2829
};
2930

3031
export default class Popover extends React.Component {
@@ -33,8 +34,8 @@ export default class Popover extends React.Component {
3334
this._checkExternalClick = this._checkExternalClick.bind(this);
3435
}
3536
componentWillMount() {
36-
let wrapperStyle = this.props.fixed ?
37-
styles.fixed_wrapper :
37+
let wrapperStyle = this.props.fixed ?
38+
styles.fixed_wrapper :
3839
styles.popover_wrapper;
3940
this._popoverWrapper = document.getElementById(wrapperStyle);
4041
if (!this._popoverWrapper) {
@@ -83,8 +84,16 @@ export default class Popover extends React.Component {
8384
}
8485

8586
_checkExternalClick(e) {
86-
if (!hasAncestor(e.target, this._popoverWrapper) &&
87-
this.props.onExternalClick) {
87+
const { contentId } = this.props;
88+
const popoverWrapper = contentId
89+
? document.getElementById(contentId)
90+
: this._popoverWrapper;
91+
const isChromeDropdown = e.target.parentNode.classList.contains("chromeDropdown");
92+
if (
93+
!hasAncestor(e.target, popoverWrapper) &&
94+
this.props.onExternalClick &&
95+
!isChromeDropdown
96+
) {
8897
this.props.onExternalClick(e);
8998
}
9099
}

src/components/TextInput/TextInput.react.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ export default class TextInput extends React.Component {
2424
}
2525

2626
changeValue(e) {
27-
this.props.onChange(e.nativeEvent.target.value);
27+
const { onChange } = this.props;
28+
if (onChange) {
29+
onChange(e.nativeEvent.target.value);
30+
}
2831
}
2932
updateValue(e) {
30-
this.props.onBlur(e.nativeEvent.target.value);
33+
const { onBlur } = this.props;
34+
if (onBlur) {
35+
onBlur(e.nativeEvent.target.value);
36+
}
3137
}
3238

3339
render() {
@@ -39,6 +45,7 @@ export default class TextInput extends React.Component {
3945
return (
4046
<textarea
4147
ref="textarea"
48+
id={this.props.id}
4249
disabled={!!this.props.disabled}
4350
className={classes.join(' ')}
4451
style={{height: this.props.height || 80}}
@@ -51,6 +58,7 @@ export default class TextInput extends React.Component {
5158
return (
5259
<input
5360
ref="input"
61+
id={this.props.id}
5462
type={this.props.hidden ? 'password' : 'text'}
5563
disabled={!!this.props.disabled}
5664
className={classes.join(' ')}

0 commit comments

Comments
 (0)