Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 32 additions & 40 deletions app/view/netcreate/NetCreate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class NetCreate extends UNISYS.Component {
style={{
display: 'flex',
flexFlow: 'row nowrap',
backgroundColor: '#EEE',
width: '100%',
height: '100%',
overflow: 'hidden',
Expand Down Expand Up @@ -243,55 +244,46 @@ class NetCreate extends UNISYS.Component {
<NCGraph />
</div>
{/*** RIGHT VIEW COLUMN ***************/}
{layoutFiltersOpen ? (
// OPEN
<div
className="--NetCreate_Column_Filters_Open"
id="right"
style={{
marginTop: '38px',
padding: '0 5px',
backgroundColor: '#6c757d',
borderTopLeftRadius: '10px',
paddingBottom: '25px' // avoid footer
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'end',
height: '100%',
overflow: 'hidden'
}}
>
<Button onClick={this.onFilterBtnClick} style={{ width: '90px' }}>
{FILTER.PANEL_LABEL} &gt;
</Button>
<FiltersPanel />
</div>
</div>
) : (
// CLOSED
<div
className="--NetCreate_Column_Filters_Open"
id="right"
style={{
marginTop: '38px',
padding: '0 5px',
backgroundColor: '#6c757d',
borderTopLeftRadius: layoutFiltersOpen ? '10px' : '0',
paddingBottom: '25px' // avoid footer
}}
>
<div
className="--NetCreate_Column_Filters_Closed"
id="right"
style={{
marginTop: '38px',
paddingTop: '0px',
backgroundColor: '#6c757d',
width: '10px',
height: '100%'
display: 'flex',
flexDirection: 'column',
alignItems: 'end',
width: layoutFiltersOpen ? '100%' : '0',
height: layoutFiltersOpen ? '100%' : 'inherit',
overflow: 'hidden'
}}
>
<Button
onClick={this.onFilterBtnClick}
style={{ width: '90px', float: 'right' }}
style={{
width: '90px',
borderTopLeftRadius: '10px',
paddingBottom: '10px',
backgroundColor: '#6c757d',
border: 'none',
boxShadow: 'none',
position: layoutFiltersOpen ? 'inherit' : 'absolute'
}}
>
&lt; {FILTER.PANEL_LABEL}
{!layoutFiltersOpen && `< `}
{FILTER.PANEL_LABEL}
{layoutFiltersOpen && ` >`}
</Button>
<FiltersPanel hidden={!layoutFiltersOpen} />
</div>
)}
</div>
</div>
<div
className="--NetCreate_Column_Break_Info"
Expand Down
2 changes: 1 addition & 1 deletion app/view/netcreate/components/NCAutoSuggest.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class NCAutoSuggest extends UNISYS.Component {
))
: undefined;
return (
<div style={{ position: 'relative' }}>
<div style={{ position: 'relative', flexGrow: '1' }}>
<div className="helptop">Click on a node, or type a node name</div>
<input
id={statekey}
Expand Down
7 changes: 2 additions & 5 deletions app/view/netcreate/components/NCSearch.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
.ncsearch {
display: grid;
grid-template-columns: 1fr;
grid-auto-columns: 100px;
grid-auto-flow: column;
column-gap: 10px;
display: flex;
flex-wrap: wrap;
margin-top: 38px; /* match navbar height */
margin-bottom: 20px;
}
Expand Down
5 changes: 3 additions & 2 deletions app/view/netcreate/components/filter/FilterEnums.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ FILTER.TYPES.NUMBER = 'number';
FILTER.TYPES.SELECT = 'select';
FILTER.TYPES.NODE = 'node'; // edge source / target
FILTER.TYPES.DATE = 'date';
FILTER.TYPES.MARKDOWN = 'markdown';
FILTER.TYPES.HIDDEN = 'hidden';
// Special Edge Keys mapped to node objects
// Used by m_IsEdgeMatchedByFilter to find node labels
Expand All @@ -59,12 +60,12 @@ FILTER.OPERATORS.CONTAINS = { key: 'CONTAINS', label: 'contains' };
FILTER.OPERATORS.NOT_CONTAINS = { key: 'NOT_CONTAINS', label: 'does not contain' };
FILTER.OPERATORS.IS_EMPTY = { key: 'IS_EMPTY', label: 'is empty' };
FILTER.OPERATORS.IS_NOT_EMPTY = { key: 'IS_NOT_EMPTY', label: 'is not empty' };
FILTER.OPERATORS.EQ = { key: 'EQ', label: '=' };
FILTER.OPERATORS.NOT_EQ = { key: 'NOT_EQ', label: `\u2260` };
FILTER.OPERATORS.GT = { key: 'GT', label: '>' };
FILTER.OPERATORS.GT_EQ = { key: 'GT_EQ', label: '>=' };
FILTER.OPERATORS.LT = { key: 'LT', label: '<' };
FILTER.OPERATORS.LT_EQ = { key: 'LT_EQ', label: '<=' };
FILTER.OPERATORS.EQ = { key: 'EQ', label: '=' };
FILTER.OPERATORS.NOT_EQ = { key: 'NOT_EQ', label: `\u2260` };

/// MODULE EXPORTS ////////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
3 changes: 2 additions & 1 deletion app/view/netcreate/components/filter/FilterGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ function FilterGroup({ group, label, filters, filterAction, transparency }) {
</div>
{filters.map(filter => {
switch (filter.type) {
case FILTER.TYPES.STRING:
case FILTER.TYPES.MARKDOWN:
case FILTER.TYPES.NODE:
case FILTER.TYPES.STRING:
return (
<StringFilter
key={filter.id}
Expand Down
3 changes: 2 additions & 1 deletion app/view/netcreate/components/filter/FiltersPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class FiltersPanel extends UNISYS.Component {
}

render() {
const { hidden } = this.props;
const { filterAction, focusRange, focusSourceLabel, statsSummary } = this.state;
const defs = [this.state.nodes, this.state.edges];

Expand Down Expand Up @@ -148,10 +149,10 @@ class FiltersPanel extends UNISYS.Component {
<div
className="filterPanel"
style={{
display: hidden ? 'none' : 'flex',
overflow: 'hidden',
margin: '6px 0',
padding: '5px',
display: 'flex',
flexDirection: 'column',
backgroundColor: '#EEE',
zIndex: '2000'
Expand Down
50 changes: 35 additions & 15 deletions app/view/netcreate/components/filter/NumberFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
The `id` variable allows us to potentially support multiple search filters
using the same key, e.g. we could have two 'Label' filters.

In order to retain the input selection cursor between state updates, we use
a secondary state `inputval` that retains the cursor position.


\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * //////////////////////////////////////*/

const FILTER = require('./FilterEnums');
Expand All @@ -53,12 +57,12 @@ var UDATA = null;
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const OPERATORS = [
FILTER.OPERATORS.NO_OP,
FILTER.OPERATORS.GT,
FILTER.OPERATORS.GT_EQ,
FILTER.OPERATORS.EQ,
FILTER.OPERATORS.NOT_EQ,
FILTER.OPERATORS.LT,
FILTER.OPERATORS.LT_EQ,
FILTER.OPERATORS.EQ,
FILTER.OPERATORS.NOT_EQ
FILTER.OPERATORS.GT,
FILTER.OPERATORS.GT_EQ
];

/// CLASS DECLARATION /////////////////////////////////////////////////////////
Expand All @@ -70,34 +74,49 @@ class NumberFilter extends React.Component {
onChangeHandler
}) {
super();
this.m_ClearFilters = this.m_ClearFilters.bind(this);
this.OnChangeOperator = this.OnChangeOperator.bind(this);
this.OnChangeValue = this.OnChangeValue.bind(this);
this.TriggerChangeHandler = this.TriggerChangeHandler.bind(this);
this.OnSubmit = this.OnSubmit.bind(this);

this.state = {
operator: FILTER.OPERATORS.NO_OP, // Used locally to define result
value: '' // Used locally to define result
inputval: '', // Used to maintain input caret position
value: '' // Used to define the final result
};

/// Initialize UNISYS DATA LINK for REACT
UDATA = UNISYS.NewDataLink(this);
UDATA.HandleMessage('FILTER_CLEAR', this.m_ClearFilters);
}

componentWillUnmount() {
UDATA.UnhandleMessage('FILTER_CLEAR', this.m_ClearFilters);
}

m_ClearFilters() {
this.setState({ inputval: '' });
}

OnChangeOperator(e) {
const newstate = { operator: e.target.value };
// clear value if NO_OP
if (e.target.value === FILTER.OPERATORS.NO_OP.key) newstate.value = '';
if (e.target.value === FILTER.OPERATORS.NO_OP.key) {
newstate.inputval = '';
newstate.value = '';
}
this.setState(newstate, this.TriggerChangeHandler);
}

OnChangeValue(e) {
this.setState(
{
value: Number(e.target.value)
},
this.TriggerChangeHandler
);
OnChangeValue(event) {
const value = Number(event.target.value);
// First update the input field, retaining cursor position
this.setState({ inputval: value }, () => {
// Then send the result
this.setState({ value }, this.TriggerChangeHandler);
});

}

TriggerChangeHandler() {
Expand Down Expand Up @@ -126,6 +145,7 @@ class NumberFilter extends React.Component {
}

render() {
const { inputval } = this.state;
const { filterAction } = this.props;
const { id, key, keylabel, operator, value } = this.props.filter;
return (
Expand Down Expand Up @@ -154,8 +174,8 @@ class NumberFilter extends React.Component {
))}
</Input>
<Input
type="text"
value={value}
type="number"
value={inputval}
placeholder="..."
style={{ maxWidth: '12em', height: '1.5em', padding: '0' }}
onChange={this.OnChangeValue}
Expand Down
1 change: 1 addition & 0 deletions app/view/netcreate/components/filter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ The available types are:
* "number"
* "select" -- Drop down menu
* "node" -- Special type for edge "source" and "target" setting.
* "markdown" -- Special string subtype that renders markdown as "string" in view mode

Each type has specific operations associated with it, e.g. "string" supports "contains" and "not contains", whereas "number" supports ">" and "!=" etc.

Expand Down
39 changes: 29 additions & 10 deletions app/view/netcreate/components/filter/StringFilter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
The `id` variable allows us to potentially support multiple search filters
using the same key, e.g. we could have two 'Label' filters.

In order to retain the input selection cursor between state updates, we use
a secondary state `inputval` that retains the cursor position.

\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * //////////////////////////////////////*/

const FILTER = require('./FilterEnums');
Expand Down Expand Up @@ -63,34 +66,48 @@ class StringFilter extends React.Component {
onChangeHandler
}) {
super();
this.m_ClearFilters = this.m_ClearFilters.bind(this);
this.OnChangeOperator = this.OnChangeOperator.bind(this);
this.OnChangeValue = this.OnChangeValue.bind(this);
this.TriggerChangeHandler = this.TriggerChangeHandler.bind(this);
this.OnSubmit = this.OnSubmit.bind(this);

this.state = {
operator: FILTER.OPERATORS.NO_OP, // Used locally to define result
value: '' // Used locally to define result
inputval: '', // Used to maintain input caret position
value: '' // Used to define the final result
};

/// Initialize UNISYS DATA LINK for REACT
UDATA = UNISYS.NewDataLink(this);
UDATA.HandleMessage('FILTER_CLEAR', this.m_ClearFilters);
}

componentWillUnmount() {
UDATA.UnhandleMessage('FILTER_CLEAR', this.m_ClearFilters);
}

m_ClearFilters() {
this.setState({ inputval: '' });
}

OnChangeOperator(e) {
const newstate = { operator: e.target.value };
// clear value if NO_OP
if (e.target.value === FILTER.OPERATORS.NO_OP.key) newstate.value = '';
if (e.target.value === FILTER.OPERATORS.NO_OP.key) {
newstate.inputval = '';
newstate.value = '';
}
this.setState(newstate, this.TriggerChangeHandler);
}

OnChangeValue(e) {
this.setState(
{
value: e.target.value
},
this.TriggerChangeHandler
);
OnChangeValue(event) {
const value = event.target.value;
// First update the input field, retaining cursor position
this.setState({ inputval: value }, () => {
// Then send the result
this.setState({ value }, this.TriggerChangeHandler);
});
}

TriggerChangeHandler() {
Expand Down Expand Up @@ -119,8 +136,10 @@ class StringFilter extends React.Component {
}

render() {
const { inputval } = this.state;
const { filterAction } = this.props;
const { id, key, keylabel, operator, value } = this.props.filter;

return (
<Form inline className="filter-item" key={id} onSubmit={this.OnSubmit}>
{/* FormGroup needs to unset flexFlow or fields will overflow
Expand All @@ -145,7 +164,7 @@ class StringFilter extends React.Component {
</Input>
<Input
type="text"
value={value}
value={inputval}
placeholder="..."
style={{ maxWidth: '12em', height: '1.5em' }}
onChange={this.OnChangeValue}
Expand Down
Loading