From ecdba75fe1c598c1c3ecf453747f619a3babe9e3 Mon Sep 17 00:00:00 2001 From: Suren Date: Thu, 21 Nov 2024 16:11:00 +0530 Subject: [PATCH 1/2] Autocomplete enhancement with additional schema types --- .../components/SelectInfiniteScroll/SelectInfiniteScroll.jsx | 5 +++-- .../MetadataEditor/components/_fields/SchemaField.jsx | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx index cd1c251755..3094939511 100644 --- a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx +++ b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx @@ -46,8 +46,9 @@ function SelectInfiniteScroll({ const updateNewOption = (newOptions, query) => { if (props.creatable && !isEmpty(query)) { - const isValueExist = props.value?.some(v => v[labelKey] === query); - const isOptionExist = newOptions.some((o) => o[labelKey] === query); + const compareValue = (v) => v?.[labelKey]?.toLowerCase() === query.toLowerCase(); + const isValueExist = props.value?.some(compareValue); + const isOptionExist = newOptions.some(compareValue); // Add new option if it doesn't exist and `creatable` is enabled if (!isValueExist && !isOptionExist) { diff --git a/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx b/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx index fdd7764353..7ad0b6f004 100644 --- a/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx +++ b/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx @@ -29,7 +29,9 @@ const SchemaField = (props) => { uiSchema } = props; const autocomplete = uiSchema?.['ui:options']?.['geonode-ui:autocomplete']; - const isMultiSelect = schema?.items?.type === 'object' && !isEmpty(schema?.items?.properties); + const isMultiSelect = schema?.type === 'array' && (schema?.items?.type === 'string' || + (schema?.items?.type === 'object' && !isEmpty(schema?.items?.properties)) + ); const isSingleSelect = schema?.type === 'object' && !isEmpty(schema?.properties); if (autocomplete && (isMultiSelect || isSingleSelect)) { From 89b83b7344a53e557fb85fe9ed2a1bf549161eb5 Mon Sep 17 00:00:00 2001 From: Suren Date: Thu, 21 Nov 2024 20:05:48 +0530 Subject: [PATCH 2/2] enhance autocomplete --- .../components/Autocomplete/Autocomplete.jsx | 19 +++++----------- .../SelectInfiniteScroll.jsx | 13 +++++++---- .../components/_fields/SchemaField.jsx | 22 ++++++++++++------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx b/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx index deef564b02..559ec1d7fc 100644 --- a/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx +++ b/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx @@ -9,6 +9,7 @@ import React from 'react'; import isArray from 'lodash/isArray'; import isEmpty from 'lodash/isEmpty'; +import isString from 'lodash/isString'; import PropTypes from 'prop-types'; import SelectInfiniteScroll from '@js/components/SelectInfiniteScroll/SelectInfiniteScroll'; @@ -22,31 +23,26 @@ const Autocomplete = ({ description, helpTitleIcon, id, - labelKey, + labelKey = "label", name, title, value, - valueKey, + valueKey = "value", ...props }) => { const getValue = () => { - if (value && isArray(value) && valueKey && labelKey) { + if (value && isArray(value)) { return value.map((entry) => { return { result: entry, - value: entry[valueKey], - label: entry[labelKey] + [valueKey]: isString(entry) ? entry : entry[valueKey], + [labelKey]: isString(entry) ? entry : entry[labelKey] }; }); } return value; }; - const defaultNewOptionCreator = (option) => ({ - [valueKey]: option.label, - [labelKey]: option.label - }); - return (
@@ -59,9 +55,6 @@ const Autocomplete = ({ value={getValue()} valueKey={valueKey} labelKey={labelKey} - {...props.creatable && { - newOptionCreator: props.newOptionCreator ?? defaultNewOptionCreator - }} />
); diff --git a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx index 3094939511..dc33e6f4a0 100644 --- a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx +++ b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx @@ -19,8 +19,8 @@ function SelectInfiniteScroll({ loadOptions, pageSize = 20, debounceTime = 500, - labelKey, - valueKey, + labelKey = "label", + valueKey = "value", newOptionPromptText = "Create option", ...props }) { @@ -46,14 +46,17 @@ function SelectInfiniteScroll({ const updateNewOption = (newOptions, query) => { if (props.creatable && !isEmpty(query)) { - const compareValue = (v) => v?.[labelKey]?.toLowerCase() === query.toLowerCase(); + const compareValue = (option) => + option?.[labelKey]?.toLowerCase() === query.toLowerCase(); + const isValueExist = props.value?.some(compareValue); const isOptionExist = newOptions.some(compareValue); // Add new option if it doesn't exist and `creatable` is enabled if (!isValueExist && !isOptionExist) { return [{ - [labelKey]: `${newOptionPromptText} "${query}"`, value: query, + [labelKey]: `${newOptionPromptText} "${query}"`, + [valueKey]: query, result: { [valueKey]: query, [labelKey]: query } }].concat(newOptions); } @@ -142,6 +145,8 @@ function SelectInfiniteScroll({ {...props} isLoading={loading} options={options} + labelKey={labelKey} + valueKey={valueKey} onOpen={() => setOpen(true)} onClose={() => setOpen(false)} filterOptions={filterOptions} diff --git a/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx b/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx index 7ad0b6f004..75d4023a49 100644 --- a/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx +++ b/geonode_mapstore_client/client/js/plugins/MetadataEditor/components/_fields/SchemaField.jsx @@ -29,8 +29,10 @@ const SchemaField = (props) => { uiSchema } = props; const autocomplete = uiSchema?.['ui:options']?.['geonode-ui:autocomplete']; - const isMultiSelect = schema?.type === 'array' && (schema?.items?.type === 'string' || - (schema?.items?.type === 'object' && !isEmpty(schema?.items?.properties)) + const isSchemaItemString = schema?.items?.type === 'string'; + const isSchemaItemObject = schema?.items?.type === 'object'; + const isMultiSelect = schema?.type === 'array' && (isSchemaItemString || + (isSchemaItemObject && !isEmpty(schema?.items?.properties)) ); const isSingleSelect = schema?.type === 'object' && !isEmpty(schema?.properties); @@ -67,10 +69,14 @@ const SchemaField = (props) => { if (result === undefined) { return option; } - return Object.fromEntries( - Object.keys(schema.items.properties) - .map((key) => [key, result[key]]) - ); + return isString(result) + ? result + : isSchemaItemString + ? result[valueKey] + : Object.fromEntries( + Object.keys(schema.items?.properties) + .map((key) => [key, result[key]]) + ); }); } onChange(_selected); @@ -91,8 +97,8 @@ const SchemaField = (props) => { return { selectOption: { result, - value: result[valueKey], - label: result[labelKey] + [valueKey]: isString(result) ? result : result[valueKey], + [labelKey]: isString(result) ? result : result[labelKey] } }; })