Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ function Filters({
getFilters();
}, [dataSet]);

const updateEntityFieldType = ({item}: {item: IFilter}): string => {
let entityFieldType = '';
visit(fields, (field: IFieldTreeItem) => {
if (field.name === item.fieldName && field.entityFieldType) {
entityFieldType = field.entityFieldType;
}
});

return entityFieldType;
};

const updateFiltersOrder = async ({
filtersOrder,
}: {
Expand Down Expand Up @@ -426,6 +437,7 @@ function Filters({
noFilterClientExtensionsAvailableModal();
}
else {
item.entityFieldType = updateEntityFieldType({item});
setActiveMode(FILTER_MODE.EDITION);
setActiveFilter(item);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import React, {useState} from 'react';
import CheckboxMultiSelect from '../../../../components/CheckboxMultiSelect';
import RequiredMark from '../../../../components/RequiredMark';
import {
EFieldType,
ESelectionFilterSourceType,
IField,
IFilter,
Expand Down Expand Up @@ -81,12 +82,20 @@ function Body({

const [multiple, setMultiple] = useState(filter?.multiple ?? true);
const [picklists, setPicklists] = useState<IPickList[]>();
const [preselectedValueInput, setPreselectedValueInput] = useState('');
const [preselectedValueInput, setPreselectedValueInput] = useState<
string | number
>('');
const [preselectedValues, setPreselectedValues] = useState<TItem[]>(
JSON.parse(filter?.preselectedValues || '[]')
);
const [selectedField, setSelectedField] = useState<IField | undefined>(
filter ? {label: filter.fieldName, name: filter.fieldName} : undefined
filter
? {
entityFieldType: filter.entityFieldType,
label: filter.fieldName,
name: filter.fieldName,
}
: undefined
);
const [source, setSource] = useState<string | undefined>(filter?.source);
const [sourceType, setSourceType] = useState(filter?.sourceType);
Expand Down Expand Up @@ -214,14 +223,19 @@ function Body({

if (success) {
let formData: any = {
entityFieldType: selectedField?.entityFieldType,
fieldName: selectedField?.name,
include: includeMode === 'include',
label_i18n: i18nFilterLabels,
multiple,
preselectedValues: JSON.stringify(
preselectedValues.map((item: any) => ({
label: item.label,
value: item.value,
value:
selectedField?.entityFieldType ===
EFieldType.INTEGER
? Number(item.value)
: item.value,
}))
),
source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface IApiRestApplicationModalContentProps {
selectedRESTSchema: string | null;
sourceItems: TItem[];
}) => void;
preselectedValueInput: string;
preselectedValueInput: string | number;
requiredRESTApplicationValidationError: boolean;
resolvedRESTSchemas: string[];
restApplications: string[];
Expand Down Expand Up @@ -119,7 +119,7 @@ function ApiRestApplication({
selectedItemLabel,
source,
}: {
preselectedValueInput: string;
preselectedValueInput: string | number;
selectedItemKey: string;
selectedItemLabel: string;
source: string | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ function getValidFields({
});
}

field.entityFieldType = type;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this piece of code will make data set manager to store types like 'object' or 'array' as valid values for the entityFieldType field, in addition to the well known string, date or integer

This is fine 👍 . At this level, we don't want to "translate" anything to the FDS domain but just persist information provided by REST openapi metadata.


fields.push(field);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface IDateFilter extends IFilter {

export interface IField {
children?: Array<IField>;
entityFieldType?: string;
format?: EFieldFormat;
id?: string;
label?: string;
Expand All @@ -113,6 +114,7 @@ export interface IFieldTreeItem extends IField {
}

export interface IFilter extends IOrderable {
entityFieldType?: string;
fieldName: string;
filterType?: EFilterType;
include?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class FDSEntityFieldTypes {

public static final String DATE_TIME = "date-time";

public static final String INTEGER = "integer";

public static final String STRING = "string";

}
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,14 @@ private JSONObject _serializeFilterClientExtension(
return JSONUtil.put(
"clientExtensionFilterURL", fdsFilterCET.getURL()
).put(
"entityFieldType", FDSEntityFieldTypes.STRING
"entityFieldType",
() -> {
if (Validator.isNotNull(properties.get("entityFieldType"))) {
return properties.get("entityFieldType");
}

return FDSEntityFieldTypes.STRING;
}
).put(
"id", fieldName
).put(
Expand Down Expand Up @@ -964,6 +971,10 @@ private JSONObject _serializeFilterSelection(
Map<String, Object> properties, String sourceType)
throws Exception {

String entityFieldType = properties.get(
"entityFieldType"
).toString();

if (Objects.equals(
sourceType, FDSEntryItemImportPolicy.ITEM_PROXY.toString())) {

Expand All @@ -987,6 +998,10 @@ private JSONObject _serializeFilterSelection(
).put(
"entityFieldType",
() -> {
if (Validator.isNotNull(entityFieldType)) {
return entityFieldType;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change represents a breaking change, as follows:

  • Consider a new filter over a child-leaf field of a root-level field of type object or array (let's imagine they are announced as filterable)
  • Prior to this change, the method _isCollection() was able to guess the type using the field name.
  • In case it was considered a collection, we returned FDSEntityFieldTypes.COLLECTION
  • However, this code now returns literally the field type as coming in the filter object entry, that is, object or array in this example

Another example:

  • Consider a pre-existing filter (say, created a month ago) over a child-leaf field of a root-level field of type object or array (older versions of Data Set Manager allowed this)
  • Open the filter in the DSM, then save. This updates entityFieldType in the filter object entry, to object or array
  • Now, the serializer would send literally the field type as coming in the filter object entry, that is, object or array

Note FDS can't handle these values for entity field type, so odata query would be generated in a different way. This is the breaking change we'd like to avoid.

We can fix it bu translating both object and array field types to FDSEntityFieldTypes.COLLECTION to keep backwards compatibility

}

if (_isCollection(
String.valueOf(properties.get("fieldName")),
sourceType)) {
Expand All @@ -997,20 +1012,7 @@ private JSONObject _serializeFilterSelection(
return FDSEntityFieldTypes.STRING;
}
).put(
"id",
() -> {
if (!Objects.equals(sourceType, "OBJECT_PICKLIST")) {
return fieldName;
}

int index = fieldName.lastIndexOf(StringPool.FORWARD_SLASH);

if (index <= 0) {
return fieldName;
}

return fieldName.substring(0, index);
}
"id", fieldName
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this code was removed? Is now object REST api able to filter by a picklist field using parent/child format in the field name and using a non-collection entity type?

We had to add this special case for picklist because object REST api expects the parent field name (as exposed by the REST) even if the value used for comparison is a child field indeed.

).put(
"label",
MapUtil.getWithFallbackKey(properties, "label", "fieldName")
Expand Down Expand Up @@ -1075,7 +1077,17 @@ private JSONObject _serializeFilterSelection(
listTypeEntry.getName(
PortalUtil.getLocale(httpServletRequest))
).put(
"value", listTypeEntry.getKey()
"value",
() -> {
if (Validator.isNotNull(entityFieldType) &&
StringUtil.equalsIgnoreCase(
entityFieldType, FDSEntityFieldTypes.INTEGER)) {

return Integer.valueOf(listTypeEntry.getKey());
}

return listTypeEntry.getKey();
}
))
).put(
"preloadedData",
Expand Down Expand Up @@ -1106,7 +1118,19 @@ private JSONObject _serializeFilterSelection(
listTypeEntry.getName(
PortalUtil.getLocale(httpServletRequest))
).put(
"value", listTypeEntry.getKey()
"value",
() -> {
if (Validator.isNotNull(entityFieldType) &&
StringUtil.equalsIgnoreCase(
entityFieldType,
FDSEntityFieldTypes.INTEGER)) {

return Integer.valueOf(
listTypeEntry.getKey());
}

return listTypeEntry.getKey();
}
));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,22 @@
"system": true,
"type": "Boolean"
},
{
"DBType": "String",
"businessType": "Text",
"externalReferenceCode": "ENTITY_FIELD_TYPE",
"indexed": true,
"indexedAsKeyword": false,
"label": {
"en_US": "Entity Field Type"
},
"localized": false,
"name": "entityFieldType",
"required": false,
"state": false,
"system": true,
"type": "String"
},
{
"DBType": "String",
"businessType": "Text",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,8 @@ public boolean isReadOnly() {
_mockSerializeFilters(
FDS_NAMES[0],
HashMapBuilder.<String, Object>put(
"entityFieldType", FDSEntityFieldTypes.INTEGER
).put(
"fieldName", FIELD_NAMES[0]
).put(
"include", true
Expand Down Expand Up @@ -602,7 +604,7 @@ public boolean isReadOnly() {
).put(
"autocompleteEnabled", true
).put(
"entityFieldType", "string"
"entityFieldType", FDSEntityFieldTypes.INTEGER
).put(
"id", FIELD_NAMES[0]
).put(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,15 @@ function getOdataString({
}

const quotedSelectedItems = selectedItems.map((item) =>
typeof item.value === 'string' ||
entityFieldType === EEntityFieldType.STRING
? `'${item.value}'`
: item.value
entityFieldType === EEntityFieldType.INTEGER
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 this is great, now we don't need to guess.

This logic should be fine for old data sets which have STRING as default entity field type. Also, situation in case of a collection looks fine for the purposes of calculating quotedSelectedItems 👍

? Number(item.value)
: `'${item.value}'`
);

if (entityFieldType === EEntityFieldType.COLLECTION) {
if (
entityFieldType === EEntityFieldType.COLLECTION ||
entityFieldType === EEntityFieldType.ARRAY
) {
return `${id}/any(x:${quotedSelectedItems
.map((value) => `(x ${exclude ? 'ne' : 'eq'} ${value})`)
.join(exclude ? ' and ' : ' or ')})`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
*/

export enum EEntityFieldType {
ARRAY = 'array',
COLLECTION = 'collection',
DATE = 'date',
DATE_TIME = 'date-time',
INTEGER = 'integer',
STRING = 'string',
}
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,32 @@ else if (Objects.equals(
() -> _getValue(
dtoConverterContext, objectDefinition, objectEntry,
objectField, finalSerializable));

if (objectField.compareBusinessType(
ObjectFieldConstants.BUSINESS_TYPE_PICKLIST)) {

String keyFieldName = objectFieldName + "Key";

unsafeSuppliers.put(keyFieldName, () -> finalSerializable);
}
else if (objectField.compareBusinessType(
ObjectFieldConstants.
BUSINESS_TYPE_MULTISELECT_PICKLIST)) {

String keyFieldName = objectFieldName + "Key";

unsafeSuppliers.put(
keyFieldName,
() -> {
if (Validator.isNull(finalSerializable)) {
return null;
}

return StringUtil.split(
(String)finalSerializable,
StringPool.COMMA_AND_SPACE);
});
}
}
}

Expand Down
Loading