diff --git a/cypress/integration/start_page.spec.js b/cypress/integration/start_page.spec.js
index 9521a7248..233dfeb5c 100644
--- a/cypress/integration/start_page.spec.js
+++ b/cypress/integration/start_page.spec.js
@@ -131,7 +131,11 @@ 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 1843511de..43ec6d006 100644
--- a/src/card/settings/custom/CardSettingsContentPropertySelect.tsx
+++ b/src/card/settings/custom/CardSettingsContentPropertySelect.tsx
@@ -30,9 +30,17 @@ 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 || 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 || settings.propertyDisplay);
+ }, [settings.suggestionLimit, settings.deduplicateSuggestions, settings.searchType, settings.caseSensitive]);
+
const cleanParameter = (parameter: string) => parameter.replaceAll(' ', '_').replaceAll('-', '_').toLowerCase();
const formatParameterId = (id: string | undefined | null) => {
const cleanedId = id || '';
@@ -40,11 +48,6 @@ const NeoCardSettingsContentPropertySelect = ({
return formattedId;
};
- // When certain settings are updated, a re-generated search query is needed.
- useEffect(() => {
- updateReportQuery(settings.entityType, settings.propertyType);
- }, [settings.suggestionLimit, settings.deduplicateSuggestions, settings.searchType, settings.caseSensitive]);
-
if (settings.type == undefined) {
onReportSettingUpdate('type', 'Node Property');
}
@@ -76,20 +79,23 @@ const NeoCardSettingsContentPropertySelect = ({
onReportSettingUpdate('propertyType', undefined);
onReportSettingUpdate('id', undefined);
onReportSettingUpdate('parameterName', undefined);
+ onReportSettingUpdate('propertyDisplay', undefined);
onReportSettingUpdate('type', newValue);
}
function handleNodeLabelSelectionUpdate(newValue) {
setPropertyInputText('');
+ setPropertyInputDisplayText('');
onReportSettingUpdate('entityType', newValue);
onReportSettingUpdate('propertyType', undefined);
onReportSettingUpdate('parameterName', undefined);
+ onReportSettingUpdate('propertyDisplay', undefined);
}
function handleFreeTextNameSelectionUpdate(newValue) {
if (newValue) {
const new_parameter_name = cleanParameter(`neodash_${newValue}`);
- handleReportQueryUpdate(new_parameter_name, newValue, undefined);
+ handleReportQueryUpdate(new_parameter_name, newValue, undefined, undefined);
} else {
onReportSettingUpdate('parameterName', undefined);
}
@@ -97,12 +103,22 @@ const NeoCardSettingsContentPropertySelect = ({
function handlePropertyNameSelectionUpdate(newValue) {
onReportSettingUpdate('propertyType', newValue);
+ onReportSettingUpdate('propertyDisplay', newValue);
if (newValue && settings.entityType) {
const newParameterName = `neodash_${settings.entityType}_${newValue}`;
const formattedParameterId = formatParameterId(settings.id);
const cleanedParameter = cleanParameter(newParameterName + formattedParameterId);
- handleReportQueryUpdate(cleanedParameter, settings.entityType, newValue);
+ handleReportQueryUpdate(cleanedParameter, settings.entityType, newValue, newValue);
+ } else {
+ onReportSettingUpdate('parameterName', undefined);
+ }
+ }
+
+ function handlePropertyDisplayNameSelectionUpdate(newValue) {
+ onReportSettingUpdate('propertyDisplay', newValue);
+ if (newValue && settings.entityType) {
+ updateReportQuery(settings.entityType, settings.propertyType, newValue);
} else {
onReportSettingUpdate('parameterName', undefined);
}
@@ -115,16 +131,18 @@ const NeoCardSettingsContentPropertySelect = ({
const newParameterName = `neodash_${settings.entityType}_${settings.propertyType}`;
const formattedParameterId = formatParameterId(`${newValue}`);
const cleanedParameter = cleanParameter(newParameterName + formattedParameterId);
- handleReportQueryUpdate(cleanedParameter, settings.entityType, settings.propertyType);
+
+ handleReportQueryUpdate(cleanedParameter, 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 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';
@@ -132,19 +150,21 @@ const NeoCardSettingsContentPropertySelect = ({
if (settings.type == 'Node Property') {
const newQuery =
`MATCH (n:\`${entityType}\`) \n` +
- `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyType}\`)) ${searchType} ${
+ `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplaySanitized}\`)) ${searchType} ${
caseSensitive ? '' : 'toLower'
}($input) \n` +
- `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value ` +
+ `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value, ` +
+ ` 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.\`${propertyType}\`)) ${searchType} ${
+ `WHERE ${caseSensitive ? '' : 'toLower'}(toString(n.\`${propertyDisplaySanitized}\`)) ${searchType} ${
caseSensitive ? '' : 'toLower'
}($input) \n` +
- `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value ` +
+ `RETURN ${deduplicate ? 'DISTINCT' : ''} n.\`${propertyType}\` as value, ` +
+ ` n.\`${propertyDisplaySanitized}\` as display ` +
`ORDER BY size(toString(value)) ASC LIMIT ${limit}`;
onQueryUpdate(newQuery);
} else {
@@ -156,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 (
@@ -173,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) => (