Added support for dotted key paths in Data table column

Summary:
This adds support for the key of DataTableColumn to be a dotted path into a nested object, e.g foo.bar. Currently the typescript types only allow a top level key to be set, making this feature currently unusuable from plugin code.

While this could be addressed in a future commit the intention of this is to allow the user to add custom fields into their table columns at run time

Note there is a side effect to free text search from this commit. Previously it would search all top keys in the object. Now it will only search in columns that are in the table.

changelog: Searching data table will now only search columns in the table, rather than all top level attributes of the object

Reviewed By: mweststrate

Differential Revision: D36663929

fbshipit-source-id: 3688e9f26aa7e1828f8e9ee69f8e6f86268c8a54
This commit is contained in:
Luke De Feo
2022-05-30 04:37:25 -07:00
committed by Facebook GitHub Bot
parent 8c4b494d32
commit e07d5c5bfe
5 changed files with 152 additions and 63 deletions

View File

@@ -250,7 +250,7 @@ export const dataTableManagerReducer = produce<
addColumnFilter(
draft.columns,
action.column,
(item as any)[action.column],
getValueAtPath(item, String(action.column)),
index === 0, // remove existing filters before adding the first
);
});
@@ -541,6 +541,25 @@ function computeInitialColumns(
}));
}
/**
* A somewhat primitive and unsafe way to access nested fields an object.
* @param obj keys should only be strings
* @param keyPath dotted string path, e.g foo.bar
* @returns value at the key path
*/
export function getValueAtPath(obj: any, keyPath: string): any {
let res = obj;
for (const key of keyPath.split('.')) {
if (res == null) {
return null;
} else {
res = res[key];
}
}
return res;
}
export function computeDataTableFilter(
searchValue: string,
useRegex: boolean,
@@ -563,7 +582,10 @@ export function computeDataTableFilter(
for (const column of filteringColumns) {
const rowMatchesFilter = column.filters!.some(
(f) =>
f.enabled && String(item[column.key]).toLowerCase().includes(f.value),
f.enabled &&
String(getValueAtPath(item, column.key))
.toLowerCase()
.includes(f.value),
);
if (column.inversed && rowMatchesFilter) {
return false;
@@ -572,11 +594,14 @@ export function computeDataTableFilter(
return false;
}
}
return Object.values(item).some((v) =>
searchRegex
? searchRegex.test(String(v))
: String(v).toLowerCase().includes(searchString),
);
return columns
.map((c) => getValueAtPath(item, c.key))
.some((v) =>
searchRegex
? searchRegex.test(String(v))
: String(v).toLowerCase().includes(searchString),
);
};
}