From 7127530c0c6a689243d32feba260b9b0d3b7357c Mon Sep 17 00:00:00 2001 From: Bennu Date: Tue, 29 Nov 2022 12:47:56 +0100 Subject: [PATCH 1/5] Selector display vs value --- .../CardSettingsContentPropertySelect.tsx | 51 +++++++++++++++---- .../parameter/ParameterSelectionChart.tsx | 26 +++++----- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx index 4c6e3e591..56f027eab 100644 --- a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx +++ b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx @@ -21,12 +21,13 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens const [labelInputText, setLabelInputText] = React.useState(settings['entityType']); const [labelRecords, setLabelRecords] = React.useState([]); const [propertyInputText, setPropertyInputText] = React.useState(settings['propertyType']); + const [propertyInputDisplayText, setPropertyInputDisplayText] = React.useState(settings['propertyDisplay']); const [propertyRecords, setPropertyRecords] = React.useState([]); var parameterName = settings['parameterName']; // When certain settings are updated, a re-generated search query is needed. useEffect(() => { - updateReportQuery(settings.entityType, settings.propertyType); + updateReportQuery(settings.entityType, settings.propertyType, settings.propertyDisplay); }, [settings.suggestionLimit, settings.deduplicateSuggestions, settings.searchType, settings.caseSensitive]) if (settings["type"] == undefined) { @@ -52,31 +53,44 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens onReportSettingUpdate('propertyType', undefined); onReportSettingUpdate('id', undefined); onReportSettingUpdate('parameterName', undefined); + onReportSettingUpdate('parameterDisplay', undefined); onReportSettingUpdate("type", newValue); } function handleNodeLabelSelectionUpdate(newValue) { setPropertyInputText(""); + setPropertyInputDisplayText(""); onReportSettingUpdate('entityType', newValue); onReportSettingUpdate('propertyType', undefined); onReportSettingUpdate('parameterName', undefined); + onReportSettingUpdate('parameterDisplay', undefined); } function handleFreeTextNameSelectionUpdate(newValue) { if (newValue) { const new_parameter_name = ("neodash_" + newValue).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_"); - handleReportQueryUpdate(new_parameter_name, newValue, undefined); + handleReportQueryUpdate(new_parameter_name, newValue, undefined, undefined); } else { onReportSettingUpdate('parameterName', undefined); } } function handlePropertyNameSelectionUpdate(newValue) { - onReportSettingUpdate('propertyType', newValue); + onReportSettingUpdate("propertyType", newValue); + onReportSettingUpdate('propertyDisplay', newValue); if (newValue && settings['entityType']) { const id = settings['id'] ? settings['id'] : ""; const new_parameter_name = "neodash_" + (settings['entityType'] + "_" + newValue + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_"); - handleReportQueryUpdate(new_parameter_name, settings['entityType'], newValue); + handleReportQueryUpdate(new_parameter_name, settings['entityType'], settings['propertyType'], settings['propertyDisplay']); + } else { + onReportSettingUpdate('parameterName', undefined); + } + } + + function handlePropertyDisplayNameSelectionUpdate(newValue) { + onReportSettingUpdate("propertyDisplay", newValue); + if (newValue && settings['entityType']) { + updateReportQuery(settings['entityType'], settings['propertyType'], settings['propertyDisplay']); } else { onReportSettingUpdate('parameterName', undefined); } @@ -88,16 +102,16 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens if (settings['propertyType'] && settings['entityType']) { const id = value ? "_" + value : ""; const new_parameter_name = "neodash_" + (settings['entityType'] + "_" + settings['propertyType'] + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_"); - handleReportQueryUpdate(new_parameter_name, settings['entityType'], settings['propertyType']); + handleReportQueryUpdate(new_parameter_name, settings['entityType'], settings['propertyType'], settings['propertyDisplay']); } } - function handleReportQueryUpdate(new_parameter_name, entityType, propertyType) { + function handleReportQueryUpdate(new_parameter_name, entityType, propertyType, propertyDisplay) { onReportSettingUpdate('parameterName', new_parameter_name); - updateReportQuery(entityType, propertyType); + updateReportQuery(entityType, propertyType, propertyDisplay); } - function updateReportQuery(entityType, propertyType) { + function updateReportQuery(entityType, propertyType, propertyDisplay) { const limit = settings.suggestionLimit ? settings.suggestionLimit : 5; const deduplicate = settings.deduplicateSuggestions !== undefined ? settings.deduplicateSuggestions : true; const searchType = settings.searchType ? settings.searchType : "CONTAINS"; @@ -106,7 +120,8 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens const newQuery = "MATCH (n:`" + entityType + "`) \n"+ "WHERE "+(caseSensitive ? "" : "toLower")+"(toString(n.`" + propertyType + "`)) "+searchType+ " "+(caseSensitive ? "" : "toLower")+"($input) \n"+ - "RETURN " + (deduplicate ? "DISTINCT" : "") + " n.`" + propertyType + "` as value "+ + "RETURN " + (deduplicate ? "DISTINCT" : "") + " n.`" + propertyType + "` as value, "+ + " n.`" + propertyDisplay + "` as display "+ "ORDER BY size(toString(value)) ASC LIMIT " + limit; onQueryUpdate(newQuery); } else if (settings['type'] == "Relationship Property") { @@ -202,6 +217,24 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens onChange={(event, newValue) => handlePropertyNameSelectionUpdate(newValue)} renderInput={(params) => } /> + r["_fields"] ? r["_fields"][0] : "(no data)")} + getOptionLabel={(option) => option ? option : ""} + style={{ display: "inline-block", width: 185, marginLeft: "5px", marginTop: "5px" }} + inputValue={propertyInputDisplayText} + onInputChange={(event, value) => { + setPropertyInputDisplayText(value); + if (manualPropertyNameSpecification) { + handlePropertyDisplayNameSelectionUpdate(value); + } else { + queryCallback("CALL db.propertyKeys() YIELD propertyKey as propertyName WITH propertyName WHERE toLower(propertyName) CONTAINS toLower($input) RETURN DISTINCT propertyName LIMIT 5", { input: value }, setPropertyRecords); + } + }} + value={settings['propertyDisplay']} + onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue, 'propertyDisplay')} + renderInput={(params) => } + /> { // In case the components gets (re)loaded with a different/non-existing selected parameter, set the text to the current global parameter value. - if (query && value != currentValue && currentValue != inputText) { + /*if (query && value != currentValue && currentValue != inputText) { setValue(currentValue); setInputText(value == defaultValue ? "" : currentValue); setExtraRecords([]); - } + }*/ if (!query || query.trim().length == 0) { return

No selection specified. Open up the report settings and choose a node label and property.

@@ -60,6 +60,7 @@ const NeoParameterSelectionChart = (props: ChartProps) => { const label = props.settings && props.settings["entityType"] ? props.settings["entityType"] : ""; const property = props.settings && props.settings["propertyType"] ? props.settings["propertyType"] : ""; + const propertyDisplay = props.settings && props.settings["propertyDisplay"] ? props.settings["propertyDisplay"] : ""; const settings = (props.settings) ? props.settings : {}; const helperText = settings.helperText; const clearParameterOnFieldClear = settings.clearParameterOnFieldClear; @@ -70,7 +71,7 @@ const NeoParameterSelectionChart = (props: ChartProps) => {
{ : r["_fields"] && r["_fields"][0] !== null ? r["_fields"][0] : "(no data)").sort()} + options={extraRecords.map(r => r["_fields"] && r["_fields"][1] !== null ? r["_fields"][1] : "(no data)").sort()} getOptionLabel={(option) => option ? option.toString() : ""} style={{ maxWidth: "calc(100% - 30px)", marginLeft: "15px", marginTop: "5px" }} inputValue={inputText} - onInputChange={(event, value) => { - setInputText("" + value); - debouncedQueryCallback(query, { input: "" + value }, setExtraRecords); + onInputChange={(event, val) => { + setInputText("" + val); + debouncedQueryCallback(query, { input: "" + val }, setExtraRecords); }} - getOptionSelected={(option, value) => (option && option.toString()) === (value && value.toString())} - value={value ? value.toString() : "" + currentValue} - onChange={(event, newValue) => { - setValue(newValue); - setInputText("" + newValue); + getOptionSelected={(option, val) => (option && option.toString()) === (val && val.toString())} + value={inputText !== undefined ? inputText.toString() : "" + currentValue} + onChange={(event, newVal) => { + let newValue = extraRecords.filter(r => r["_fields"][1] == newVal)[0]["_fields"][0]; if (newValue && newValue["low"]) { newValue = newValue["low"]; } + setValue(newValue); + setInputText("" + newVal); if (newValue == null && clearParameterOnFieldClear) { props.setGlobalParameter(parameter, undefined); } else if (newValue == null) { From da417870b60da28e067346e44530abde8d5cc91d Mon Sep 17 00:00:00 2001 From: Bennu Date: Mon, 5 Dec 2022 19:42:03 +0100 Subject: [PATCH 2/5] extra changes . some test changes --- cypress/integration/start_page.spec.js | 4 +++- .../CardSettingsContentPropertySelect.tsx | 20 ++++++++++--------- .../parameter/ParameterSelectionChart.tsx | 13 +++++++++--- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cypress/integration/start_page.spec.js b/cypress/integration/start_page.spec.js index 570cbde59..d965d106a 100644 --- a/cypress/integration/start_page.spec.js +++ b/cypress/integration/start_page.spec.js @@ -102,7 +102,9 @@ describe('NeoDash E2E Tests', () => { it('creates a single value report', () => { createReportOfType('Single Value', barChartCypherQuery) - cy.get('main .react-grid-item:eq(2) .MuiCardContent-root > div > div:nth-child(2) > span').contains('1,999') + cy.get('main .react-grid-item:eq(2) .MuiCardContent-root > div > div:nth-child(2) > span').invoke('text').then(text => { + expect(text).to.be.oneOf(['1999', '1,999']) + }) }) it('creates a gauge chart report', () => { diff --git a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx index 56f027eab..bcabd60b9 100644 --- a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx +++ b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx @@ -53,7 +53,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens onReportSettingUpdate('propertyType', undefined); onReportSettingUpdate('id', undefined); onReportSettingUpdate('parameterName', undefined); - onReportSettingUpdate('parameterDisplay', undefined); + onReportSettingUpdate('propertyDisplay', undefined); onReportSettingUpdate("type", newValue); } @@ -63,7 +63,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens onReportSettingUpdate('entityType', newValue); onReportSettingUpdate('propertyType', undefined); onReportSettingUpdate('parameterName', undefined); - onReportSettingUpdate('parameterDisplay', undefined); + onReportSettingUpdate('propertyDisplay', undefined); } function handleFreeTextNameSelectionUpdate(newValue) { @@ -77,11 +77,11 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens function handlePropertyNameSelectionUpdate(newValue) { onReportSettingUpdate("propertyType", newValue); - onReportSettingUpdate('propertyDisplay', newValue); + onReportSettingUpdate("propertyDisplay", newValue); if (newValue && settings['entityType']) { const id = settings['id'] ? settings['id'] : ""; const new_parameter_name = "neodash_" + (settings['entityType'] + "_" + newValue + (id == "" || id.startsWith("_") ? id : "_" + id)).toLowerCase().replaceAll(" ", "_").replaceAll("-", "_"); - handleReportQueryUpdate(new_parameter_name, settings['entityType'], settings['propertyType'], settings['propertyDisplay']); + handleReportQueryUpdate(new_parameter_name, settings['entityType'], newValue, newValue); } else { onReportSettingUpdate('parameterName', undefined); } @@ -90,7 +90,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens function handlePropertyDisplayNameSelectionUpdate(newValue) { onReportSettingUpdate("propertyDisplay", newValue); if (newValue && settings['entityType']) { - updateReportQuery(settings['entityType'], settings['propertyType'], settings['propertyDisplay']); + updateReportQuery(settings['entityType'], settings['propertyType'], newValue); } else { onReportSettingUpdate('parameterName', undefined); } @@ -118,7 +118,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens const caseSensitive = settings.caseSensitive !== undefined ? settings.caseSensitive : false; if (settings['type'] == "Node Property") { const newQuery = "MATCH (n:`" + entityType + "`) \n"+ - "WHERE "+(caseSensitive ? "" : "toLower")+"(toString(n.`" + propertyType + "`)) "+searchType+ + "WHERE "+(caseSensitive ? "" : "toLower")+"(toString(n.`" + propertyDisplay + "`)) "+searchType+ " "+(caseSensitive ? "" : "toLower")+"($input) \n"+ "RETURN " + (deduplicate ? "DISTINCT" : "") + " n.`" + propertyType + "` as value, "+ " n.`" + propertyDisplay + "` as display "+ @@ -126,9 +126,10 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens onQueryUpdate(newQuery); } else if (settings['type'] == "Relationship Property") { const newQuery = "MATCH ()-[n:`" + entityType + "`]->() \n"+ - "WHERE "+(caseSensitive ? "" : "toLower")+"(toString(n.`" + propertyType + "`)) "+searchType+ + "WHERE "+(caseSensitive ? "" : "toLower")+"(toString(n.`" + propertyDisplay + "`)) "+searchType+ " "+(caseSensitive ? "" : "toLower")+"($input) \n"+ - "RETURN " + (deduplicate ? "DISTINCT" : "") + " n.`" + propertyType + "` as value "+ + "RETURN " + (deduplicate ? "DISTINCT" : "") + " n.`" + propertyType + "` as value, "+ + " n.`" + propertyDisplay + "` as display "+ "ORDER BY size(toString(value)) ASC LIMIT " + limit; onQueryUpdate(newQuery); } else { @@ -207,6 +208,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens inputValue={propertyInputText} onInputChange={(event, value) => { setPropertyInputText(value); + setPropertyInputDisplayText(value); if (manualPropertyNameSpecification) { handlePropertyNameSelectionUpdate(value); } else { @@ -232,7 +234,7 @@ const NeoCardSettingsContentPropertySelect = ({ type, database, settings, extens } }} value={settings['propertyDisplay']} - onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue, 'propertyDisplay')} + onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue)} renderInput={(params) => } /> { const records = props.records; const query = records[0]["input"] ? records[0]["input"] : undefined; const parameter = props.settings && props.settings["parameterName"] ? props.settings["parameterName"] : undefined; + const parameterDisplay = parameter + "_display"; const type = props.settings && props.settings["type"] ? props.settings["type"] : undefined; const suggestionsUpdateTimeout = props.settings && props.settings["suggestionsUpdateTimeout"] ? props.settings["suggestionsUpdateTimeout"] : 250; const setParameterTimeout = props.settings && props.settings["setParameterTimeout"] ? props.settings["setParameterTimeout"] : 1000; const defaultValue = props.settings && props.settings["defaultValue"] && props.settings["defaultValue"].length > 0 ? props.settings["defaultValue"] : ""; - const currentValue = (props.getGlobalParameter && props.getGlobalParameter(parameter)) ? props.getGlobalParameter(parameter) : ""; + const currentValue = (props.getGlobalParameter && props.getGlobalParameter(parameterDisplay)) ? props.getGlobalParameter(parameterDisplay) : ""; const [extraRecords, setExtraRecords] = React.useState([]); const [inputText, setInputText] = React.useState(currentValue); const queryCallback = props.queryCallback ? props.queryCallback : () => { }; @@ -91,7 +92,10 @@ const NeoParameterSelectionChart = (props: ChartProps) => { : r["_fields"] && r["_fields"][1] !== null ? r["_fields"][1] : "(no data)").sort()} + options={ + extraRecords.map(r => r["_fields"] && r["_fields"][1] !== null ? r["_fields"][1] : "(no data)") + .sort() + } getOptionLabel={(option) => option ? option.toString() : ""} style={{ maxWidth: "calc(100% - 30px)", marginLeft: "15px", marginTop: "5px" }} inputValue={inputText} @@ -110,15 +114,18 @@ const NeoParameterSelectionChart = (props: ChartProps) => { setInputText("" + newVal); if (newValue == null && clearParameterOnFieldClear) { props.setGlobalParameter(parameter, undefined); + props.setGlobalParameter(parameterDisplay, undefined); } else if (newValue == null) { props.setGlobalParameter(parameter, defaultValue); + props.setGlobalParameter(parameterDisplay, defaultValue); } else { props.setGlobalParameter(parameter, newValue); + props.setGlobalParameter(parameterDisplay, newVal); } }} renderInput={(params) => } + label={helperText ? helperText : label + " " + propertyDisplay} variant="outlined" />} /> }
From 5255fab943a57eafec047a4281b86379bac9131a Mon Sep 17 00:00:00 2001 From: Niels de Jong Date: Sat, 21 Jan 2023 15:39:39 +0100 Subject: [PATCH 3/5] Fix typo --- src/chart/Chart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chart/Chart.ts b/src/chart/Chart.ts index 7f3d452ee..907fd1987 100644 --- a/src/chart/Chart.ts +++ b/src/chart/Chart.ts @@ -11,6 +11,6 @@ export interface ChartProps { fullscreen?: boolean; // flag indicating whether the report is rendered in a fullscreen view. parameters?: Record; // A dictionary with the global dashboard parameters. queryCallback?: (query: string, parameters: Record, records: Neo4jRecord[]) => null; // Optionally, a way for the report to read more data from Neo4j. - setGlobalParameter?: (name: string, value?: string) => void; // Allows a chart to update a global dashboard parameter to be used in Cypher queries for other reports. + setGlobalParameter?: (name: string, value: string) => void; // Allows a chart to update a global dashboard parameter to be used in Cypher queries for other reports. getGlobalParameter?: (name) => string; // Allows a chart to get a global dashboard parameter. } From d6c46f1e89320c8ffb09d9158ef467145b812383 Mon Sep 17 00:00:00 2001 From: Bennu Date: Wed, 1 Feb 2023 15:48:00 +0100 Subject: [PATCH 4/5] FIx on Parameter selec --- .../CardSettingsContentPropertySelect.tsx | 23 +++++++++-------- .../parameter/ParameterSelectionChart.tsx | 25 +++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx index f53bd72dd..df139b372 100644 --- a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx +++ b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx @@ -30,13 +30,15 @@ const NeoCardSettingsContentPropertySelect = ({ const [labelInputText, setLabelInputText] = React.useState(settings.entityType); const [labelRecords, setLabelRecords] = React.useState([]); const [propertyInputText, setPropertyInputText] = React.useState(settings.propertyType); - const [propertyInputDisplayText, setPropertyInputDisplayText] = React.useState(settings.propertyDisplay); + const [propertyInputDisplayText, setPropertyInputDisplayText] = React.useState( + settings.propertyDisplay || settings.propertyType + ); const [propertyRecords, setPropertyRecords] = React.useState([]); let { parameterName } = settings; // When certain settings are updated, a re-generated search query is needed. useEffect(() => { - updateReportQuery(settings.entityType, settings.propertyType, settings.propertyDisplay); + updateReportQuery(settings.entityType, settings.propertyType, settings.propertyDisplay || settings.propertyDisplay); }, [settings.suggestionLimit, settings.deduplicateSuggestions, settings.searchType, settings.caseSensitive]); const cleanParameter = (parameter: string) => parameter.replaceAll(' ', '_').replaceAll('-', '_').toLowerCase(); @@ -140,6 +142,7 @@ const NeoCardSettingsContentPropertySelect = ({ } function updateReportQuery(entityType, propertyType, propertyDisplay) { + const propertyDisplaySanitized = propertyDisplay || propertyType; const limit = settings.suggestionLimit ? settings.suggestionLimit : 5; const deduplicate = settings.deduplicateSuggestions !== undefined ? settings.deduplicateSuggestions : true; const searchType = settings.searchType ? settings.searchType : 'CONTAINS'; @@ -147,21 +150,21 @@ const NeoCardSettingsContentPropertySelect = ({ if (settings.type == 'Node Property') { const newQuery = `MATCH (n:\`${entityType}\`) \n` + - `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplay}\`)) ${searchType} ${ + `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplaySanitized}\`)) ${searchType} ${ caseSensitive ? '' : 'toLower' }($input) \n` + `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value, ` + - ` n.\`${propertyDisplay}\` as display ` + + ` n.\`${propertyDisplaySanitized}\` as display ` + `ORDER BY size(toString(value)) ASC LIMIT ${limit}`; onQueryUpdate(newQuery); } else if (settings.type == 'Relationship Property') { const newQuery = `MATCH ()-[n:\`${entityType}\`]->() \n` + - `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplay}\`)) ${searchType} ${ + `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplaySanitized}\`)) ${searchType} ${ caseSensitive ? '' : 'toLower' }($input) \n` + `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value, ` + - ` n.\`${propertyDisplay}\` as display ` + + ` n.\`${propertyDisplaySanitized}\` as display ` + `ORDER BY size(toString(value)) ASC LIMIT ${limit}`; onQueryUpdate(newQuery); } else { @@ -222,7 +225,7 @@ const NeoCardSettingsContentPropertySelect = ({ ? [settings.entityType] : labelRecords.map((r) => (r._fields ? r._fields[0] : '(no data)')) } - getOptionLabel={(option) => (option ? option : '')} + getOptionLabel={(option) => option || ''} style={{ width: 335, marginLeft: '5px', marginTop: '5px' }} inputValue={labelInputText} onInputChange={(event, value) => { @@ -295,7 +298,7 @@ const NeoCardSettingsContentPropertySelect = ({ id='autocomplete-property-display' options={ manualPropertyNameSpecification - ? [settings.propertyDisplay] + ? [settings.propertyDisplay || settins.propertyType] : propertyRecords.map((r) => (r._fields ? r._fields[0] : '(no data)')) } getOptionLabel={(option) => (option ? option : '')} @@ -313,14 +316,14 @@ const NeoCardSettingsContentPropertySelect = ({ ); } }} - value={settings.propertyDisplay} + value={settings.propertyDisplay || settings.propertyType} onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue)} renderInput={(params) => ( )} /> diff --git a/src/chart/parameter/ParameterSelectionChart.tsx b/src/chart/parameter/ParameterSelectionChart.tsx index 070ae7d0c..3c38443e1 100644 --- a/src/chart/parameter/ParameterSelectionChart.tsx +++ b/src/chart/parameter/ParameterSelectionChart.tsx @@ -22,18 +22,23 @@ const NeoParameterSelectionChart = (props: ChartProps) => { ? props.settings.defaultValue : ''; const currentValue = + props.getGlobalParameter && props.getGlobalParameter(parameter) ? props.getGlobalParameter(parameter) : ''; + + const currentDisplayValue = props.getGlobalParameter && props.getGlobalParameter(parameterDisplay) ? props.getGlobalParameter(parameterDisplay) : ''; + const [extraRecords, setExtraRecords] = React.useState([]); - const [inputText, setInputText] = React.useState(currentValue); + const [inputText, setInputText] = React.useState(currentDisplayValue); const queryCallback = props.queryCallback ? props.queryCallback : () => {}; const setGlobalParameter = props.setGlobalParameter ? props.setGlobalParameter : () => {}; const [value, setValue] = React.useState(currentValue); const debouncedQueryCallback = useCallback(debounce(queryCallback, suggestionsUpdateTimeout), []); const debouncedSetGlobalParameter = useCallback(debounce(setGlobalParameter, setParameterTimeout), []); - + const compatibilityMode = !query.includes('as display'); + const indexCompatibility = compatibilityMode ? 0 : 1; const queryTimeOut = setTimeout(() => { debouncedQueryCallback && debouncedQueryCallback(query, { input: inputText, ...props.parameters }, setExtraRecords); }, 150); @@ -55,15 +60,15 @@ const NeoParameterSelectionChart = (props: ChartProps) => { }, [value]); // In case the components gets (re)loaded with a different/non-existing selected parameter, set the text to the current global parameter value. - if (query && value != currentValue && currentValue != inputText) { + if (query && value != currentValue && currentDisplayValue != inputText) { setValue(currentValue); - setInputText(value == defaultValue ? '' : currentValue); + setInputText(value == defaultValue ? '' : currentDisplayValue); setExtraRecords([]); } const label = props.settings && props.settings.entityType ? props.settings.entityType : ''; const property = props.settings && props.settings.propertyType ? props.settings.propertyType : ''; - const propertyDisplay = props.settings && props.settings.propertyDisplay ? props.settings.propertyDisplay : ''; + const propertyDisplay = props?.settings?.propertyDisplay || property; const settings = props.settings ? props.settings : {}; const { helperText } = settings; const { clearParameterOnFieldClear } = settings; @@ -82,7 +87,7 @@ const NeoParameterSelectionChart = (props: ChartProps) => {
{ ) : ( (r._fields && r._fields[1] !== null ? r._fields[1] : '(no data)')).sort()} + options={extraRecords.map((r) => (r._fields ? r._fields[indexCompatibility] : '(no data)')).sort()} getOptionLabel={(option) => (option ? option.toString() : '')} style={{ maxWidth: 'calc(100% - 30px)', marginLeft: '15px', marginTop: '5px' }} inputValue={inputText !== null ? inputText.toString() : ''} @@ -116,8 +121,8 @@ const NeoParameterSelectionChart = (props: ChartProps) => { }} getOptionSelected={(option, val) => (option && option.toString()) === (val && val.toString())} value={inputText !== null ? inputText.toString() : `${currentValue}`} - onChange={(event, newVal) => { - let newValue = extraRecords.filter((r) => r._fields[1] == newVal)[0]._fields[0]; + onChange={(event, newVal: string) => { + let newValue = extraRecords.filter((r) => r._fields[indexCompatibility].toString() == newVal)[0]._fields[0]; if (newValue && newValue.low) { newValue = newValue.low; } @@ -134,7 +139,7 @@ const NeoParameterSelectionChart = (props: ChartProps) => { props.setGlobalParameter(parameterDisplay, defaultValue); } else { props.setGlobalParameter(parameter, newValue); - props.setGlobalParameter(parameterDisplay, newValue); + props.setGlobalParameter(parameterDisplay, newVal); } }} renderInput={(params) => ( From d9cb350c56b595d8d3b062e30d6b7739ffb620cd Mon Sep 17 00:00:00 2001 From: Niels de Jong Date: Thu, 2 Feb 2023 11:09:30 +0100 Subject: [PATCH 5/5] Minor style fixes --- .../CardSettingsContentPropertySelect.tsx | 78 ++++++++++--------- src/config/ReportConfig.tsx | 6 ++ 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx index df139b372..43ec6d006 100644 --- a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx +++ b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx @@ -176,6 +176,8 @@ const NeoCardSettingsContentPropertySelect = ({ // TODO: since this component is only rendered for parameter select, this is technically not needed const parameterSelectTypes = ['Node Property', 'Relationship Property', 'Free Text']; const reportTypes = getReportTypes(extensions); + const overridePropertyDisplayName = + settings.overridePropertyDisplayName !== undefined ? settings.overridePropertyDisplayName : false; return (
@@ -193,7 +195,7 @@ const NeoCardSettingsContentPropertySelect = ({ style={{ width: '25%' }} label='Selection Type' type='text' - style={{ width: 335, marginLeft: '5px', marginTop: '0px' }} + style={{ width: 350, marginLeft: '5px', marginTop: '0px' }} > {parameterSelectTypes.map((option) => ( @@ -226,7 +228,7 @@ const NeoCardSettingsContentPropertySelect = ({ : labelRecords.map((r) => (r._fields ? r._fields[0] : '(no data)')) } getOptionLabel={(option) => option || ''} - style={{ width: 335, marginLeft: '5px', marginTop: '5px' }} + style={{ width: 350, marginLeft: '5px', marginTop: '5px' }} inputValue={labelInputText} onInputChange={(event, value) => { setLabelInputText(value); @@ -268,7 +270,7 @@ const NeoCardSettingsContentPropertySelect = ({ : propertyRecords.map((r) => (r._fields ? r._fields[0] : '(no data)')) } getOptionLabel={(option) => (option ? option : '')} - style={{ display: 'inline-block', width: 185, marginLeft: '5px', marginTop: '5px' }} + style={{ display: 'inline-block', width: 170, marginLeft: '5px', marginTop: '5px' }} inputValue={propertyInputText} onInputChange={(event, value) => { setPropertyInputText(value); @@ -294,45 +296,49 @@ const NeoCardSettingsContentPropertySelect = ({ /> )} /> - (r._fields ? r._fields[0] : '(no data)')) - } - getOptionLabel={(option) => (option ? option : '')} - style={{ display: 'inline-block', width: 185, marginLeft: '5px', marginTop: '5px' }} - inputValue={propertyInputDisplayText} - onInputChange={(event, value) => { - setPropertyInputDisplayText(value); - if (manualPropertyNameSpecification) { - handlePropertyDisplayNameSelectionUpdate(value); - } else { - queryCallback( - 'CALL db.propertyKeys() YIELD propertyKey as propertyName WITH propertyName WHERE toLower(propertyName) CONTAINS toLower($input) RETURN DISTINCT propertyName LIMIT 5', - { input: value }, - setPropertyRecords - ); + {overridePropertyDisplayName ? ( + (r._fields ? r._fields[0] : '(no data)')) } - }} - value={settings.propertyDisplay || settings.propertyType} - onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue)} - renderInput={(params) => ( - - )} - /> + getOptionLabel={(option) => (option ? option : '')} + style={{ display: 'inline-block', width: 170, marginLeft: '10px', marginTop: '5px' }} + inputValue={propertyInputDisplayText} + onInputChange={(event, value) => { + setPropertyInputDisplayText(value); + if (manualPropertyNameSpecification) { + handlePropertyDisplayNameSelectionUpdate(value); + } else { + queryCallback( + 'CALL db.propertyKeys() YIELD propertyKey as propertyName WITH propertyName WHERE toLower(propertyName) CONTAINS toLower($input) RETURN DISTINCT propertyName LIMIT 5', + { input: value }, + setPropertyRecords + ); + } + }} + value={settings.propertyDisplay || settings.propertyType} + onChange={(event, newValue) => handlePropertyDisplayNameSelectionUpdate(newValue)} + renderInput={(params) => ( + + )} + /> + ) : ( + <> + )} { handleIdSelectionUpdate(value); }} diff --git a/src/config/ReportConfig.tsx b/src/config/ReportConfig.tsx index af989724d..4e91f712f 100644 --- a/src/config/ReportConfig.tsx +++ b/src/config/ReportConfig.tsx @@ -1062,6 +1062,12 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.COLOR, default: '#fafafa', }, + overridePropertyDisplayName: { + label: 'Property Display Name Override', + type: SELECTION_TYPES.LIST, + values: [true, false], + default: false, + }, suggestionLimit: { label: 'Value Suggestion Limit', type: SELECTION_TYPES.NUMBER,