Skip to content

Commit 3915700

Browse files
committed
Manual Selection
1 parent 2fec0c1 commit 3915700

File tree

5 files changed

+110
-45
lines changed

5 files changed

+110
-45
lines changed

src/chart/parameter/ParameterSelectionChart.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
2828
const setParameterDisplayValue = (value) => setGlobalParameter(parameterDisplayName, value);
2929
const allParameters = props.parameters;
3030
const multiSelector = props?.settings?.multiSelector;
31-
31+
const setManual = props?.settings?.setManual;
3232
// in NeoDash 2.2.1 or earlier, there was no means to have a different display value in the selector. This condition handles that.
3333
const compatibilityMode = !query?.toLowerCase().includes('as display') || false;
3434

@@ -50,6 +50,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
5050
settings={props.settings}
5151
allParameters={allParameters}
5252
compatibilityMode={compatibilityMode}
53+
setManual={setManual}
5354
/>
5455
);
5556
} else if (type == 'Node Property') {
@@ -67,6 +68,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
6768
allParameters={allParameters}
6869
compatibilityMode={compatibilityMode}
6970
multiSelector={multiSelector}
71+
setManual={setManual}
7072
/>
7173
);
7274
} else if (type == 'Relationship Property') {
@@ -84,6 +86,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
8486
allParameters={allParameters}
8587
compatibilityMode={compatibilityMode}
8688
multiSelector={multiSelector}
89+
setManual={setManual}
8790
/>
8891
);
8992
} else if (type == 'Date Picker') {
@@ -100,6 +103,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
100103
settings={props.settings}
101104
allParameters={allParameters}
102105
compatibilityMode={compatibilityMode}
106+
setManual={setManual}
103107
/>
104108
);
105109
} else if (type == 'Custom Query') {
@@ -117,6 +121,7 @@ export const NeoParameterSelectionChart = (props: ChartProps) => {
117121
allParameters={allParameters}
118122
compatibilityMode={compatibilityMode}
119123
multiSelector={multiSelector}
124+
setManual={setManual}
120125
/>
121126
);
122127
}

src/chart/parameter/component/NodePropertyParameterSelect.tsx

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { debounce, TextField } from '@mui/material';
33
import Autocomplete from '@mui/material/Autocomplete';
44
import { ParameterSelectProps } from './ParameterSelect';
55
import { RenderSubValue } from '../../../report/ReportRecordProcessing';
6+
import { SelectionConfirmationButton } from './SelectionConfirmationButton';
67

78
const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => {
89
const suggestionsUpdateTimeout =
@@ -20,14 +21,17 @@ const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => {
2021
}
2122
return multi ? [] : value;
2223
};
23-
const { multiSelector } = props;
24+
const { multiSelector, setManual } = props;
2425
const allParameters = props.allParameters ? props.allParameters : {};
2526
const [extraRecords, setExtraRecords] = React.useState([]);
2627
const [inputDisplayText, setInputDisplayText] = React.useState(
2728
props.parameterDisplayValue && multiSelector ? '' : props.parameterDisplayValue
2829
);
2930
const [inputValue, setInputValue] = React.useState(getInitialValue(props.parameterDisplayValue, multiSelector));
3031

32+
const [paramValueTemp, setParamValueTemp] = React.useState(null);
33+
const [paramValueDisplayTemp, setParamValueDisplayTemp] = React.useState(null);
34+
3135
const debouncedQueryCallback = useCallback(debounce(props.queryCallback, suggestionsUpdateTimeout), []);
3236
const label = props.settings && props.settings.entityType ? props.settings.entityType : '';
3337
const propertyType = props.settings && props.settings.propertyType ? props.settings.propertyType : '';
@@ -42,38 +46,51 @@ const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => {
4246

4347
const realValueRowIndex = props.compatibilityMode ? 0 : 1 - displayValueRowIndex;
4448

49+
const manualHandleParameters = () => {
50+
handleParameters(paramValueTemp, paramValueDisplayTemp, false);
51+
};
52+
const handleParameters = (value, displayValue, manual = false) => {
53+
setParamValueTemp(value);
54+
setParamValueDisplayTemp(displayValue);
55+
56+
if (manual) {
57+
return;
58+
}
59+
60+
props.setParameterValue(value);
61+
props.setParameterDisplayValue(displayValue);
62+
};
4563
const handleCrossClick = (isMulti, value) => {
4664
if (isMulti) {
4765
if (value.length == 0 && clearParameterOnFieldClear) {
4866
setInputValue([]);
49-
props.setParameterValue(undefined);
50-
props.setParameterDisplayValue(undefined);
51-
return;
67+
handleParameters(undefined, undefined, setManual);
68+
return true;
5269
}
5370
if (value.length == 0) {
5471
setInputValue([]);
55-
props.setParameterValue([]);
56-
props.setParameterDisplayValue([]);
57-
72+
handleParameters([], [], setManual);
73+
return true;
5874
}
5975
} else {
6076
if (value && clearParameterOnFieldClear) {
6177
setInputValue(null);
62-
props.setParameterValue(undefined);
63-
props.setParameterDisplayValue(undefined);
64-
return;
78+
handleParameters(undefined, undefined, setManual);
79+
return true;
6580
}
6681
if (value == null) {
6782
setInputValue(null);
68-
props.setParameterValue(defaultValue);
69-
props.setParameterDisplayValue(defaultValue);
70-
83+
handleParameters(defaultValue, defaultValue, setManual);
84+
return true;
7185
}
86+
return false;
7287
}
7388
};
7489
const propagateSelection = (event, newDisplay) => {
7590
const isMulti = Array.isArray(newDisplay);
76-
handleCrossClick(isMulti, newDisplay);
91+
if (handleCrossClick(isMulti, newDisplay)) {
92+
return;
93+
}
7794
let newValue;
7895
// Multiple and new entry
7996
if (isMulti && inputValue.length < newDisplay.length) {
@@ -86,9 +103,8 @@ const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => {
86103

87104
newValue.push(val?.low ?? val);
88105
} else if (!isMulti) {
89-
newValue = extraRecords.filter((r) => r._fields[displayValueRowIndex].toString() == newDisplay)[0]._fields[
90-
realValueRowIndex
91-
];
106+
newValue = extraRecords.filter((r) => (r?._fields?.[displayValueRowIndex]?.toString() || null) == newDisplay)[0]
107+
._fields[realValueRowIndex];
92108

93109
newValue = newValue?.low || newValue;
94110
} else {
@@ -100,36 +116,42 @@ const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => {
100116
setInputDisplayText(isMulti ? '' : newDisplay);
101117
setInputValue(newDisplay);
102118

103-
props.setParameterValue(newValue);
104-
props.setParameterDisplayValue(newDisplay);
119+
handleParameters(newValue, newDisplay, setManual);
105120
};
106121
return (
107-
<Autocomplete
108-
id='autocomplete'
109-
multiple={multiSelector}
110-
options={extraRecords.map((r) => r?._fields?.[displayValueRowIndex] || '(no data)').sort()}
111-
style={{ maxWidth: 'calc(100% - 30px)', marginLeft: '15px', marginTop: '5px' }}
112-
inputValue={inputDisplayText}
113-
onInputChange={(event, value) => {
114-
setInputDisplayText(value);
115-
debouncedQueryCallback(props.query, { input: `${value}`, ...allParameters }, setExtraRecords);
116-
}}
117-
isOptionEqualToValue={(option, value) => {
118-
return (option && option.toString()) === (value && value.toString());
119-
}}
120-
value={inputValue}
121-
onChange={propagateSelection}
122-
renderInput={(params) => (
123-
<TextField
124-
{...params}
125-
InputLabelProps={{ shrink: true }}
126-
placeholder='Start typing...'
127-
label={helperText ? helperText : `${label} ${propertyType}`}
128-
variant='outlined'
129-
/>
122+
<div>
123+
<Autocomplete
124+
id='autocomplete'
125+
multiple={multiSelector}
126+
options={extraRecords.map((r) => r?._fields?.[displayValueRowIndex] || '(no data)').sort()}
127+
style={{ maxWidth: 'calc(100% - 30px)', marginLeft: '15px', marginTop: '5px' }}
128+
inputValue={inputDisplayText || ''}
129+
onInputChange={(event, value) => {
130+
setInputDisplayText(value);
131+
debouncedQueryCallback(props.query, { input: `${value}`, ...allParameters }, setExtraRecords);
132+
}}
133+
isOptionEqualToValue={(option, value) => {
134+
return (option && option.toString()) === (value && value.toString());
135+
}}
136+
value={inputValue}
137+
onChange={propagateSelection}
138+
renderInput={(params) => (
139+
<TextField
140+
{...params}
141+
InputLabelProps={{ shrink: true }}
142+
placeholder='Start typing...'
143+
label={helperText ? helperText : `${label} ${propertyType}`}
144+
variant='outlined'
145+
/>
146+
)}
147+
getOptionLabel={(option) => RenderSubValue(option)}
148+
/>
149+
{setManual ? (
150+
<SelectionConfirmationButton onClick={() => manualHandleParameters()} key={`selectionConfirmation`} />
151+
) : (
152+
<></>
130153
)}
131-
getOptionLabel={(option) => RenderSubValue(option)}
132-
/>
154+
</div>
133155
);
134156
};
135157

src/chart/parameter/component/ParameterSelect.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,8 @@ export interface ParameterSelectProps {
5050
* Add the possibility for multiple selections
5151
*/
5252
multiSelector?: boolean;
53+
/**
54+
* Add the possibility for manual selection confirmation
55+
*/
56+
setManual?: boolean;
5357
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import { Fab } from '@mui/material';
3+
import RefreshIcon from '@mui/icons-material/Refresh';
4+
5+
/**
6+
* Returns a button to delete a property entry from the table inside the GraphChartEditModal.
7+
*/
8+
export const SelectionConfirmationButton = ({ onClick, key }) => {
9+
return (
10+
<Fab
11+
key={key}
12+
size='small'
13+
aria-label='remove'
14+
style={{
15+
background: 'white',
16+
color: 'grey',
17+
marginTop: '-6px',
18+
marginLeft: '20px',
19+
width: '26px',
20+
height: '26px',
21+
minHeight: '26px',
22+
}}
23+
onClick={onClick}
24+
>
25+
<RefreshIcon key={`icon${key}`} />
26+
</Fab>
27+
);
28+
};

src/config/ReportConfig.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,12 @@ export const REPORT_TYPES = {
12961296
values: [true, false],
12971297
default: false,
12981298
},
1299+
setManual: {
1300+
label: 'Manual Set',
1301+
type: SELECTION_TYPES.LIST,
1302+
values: [true, false],
1303+
default: false,
1304+
},
12991305
overridePropertyDisplayName: {
13001306
label: 'Property Display Name Override',
13011307
type: SELECTION_TYPES.LIST,

0 commit comments

Comments
 (0)