From f7bc02e245aefc27b5f8ed2a5f89ea2868de1f20 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 10:20:28 -0500 Subject: [PATCH 01/10] remove ne matching and extra sorting --- fiftyone/server/lightning.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index 701588864d5..77a655ad0fc 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -324,6 +324,7 @@ async def _do_async_query( if filter: query.insert(0, {"$match": filter}) + fo.pprint(query) return [i async for i in collection.aggregate(query)] @@ -423,9 +424,6 @@ def _first( if floats: pipeline.extend(_handle_nonfinites(path, sort)) - if sort: - pipeline.append({"$match": {path: {"$ne": None}}}) - matched_arrays = _match_arrays(dataset, path, is_frame_field) if matched_arrays: pipeline += matched_arrays @@ -438,11 +436,6 @@ def _first( if floats: pipeline.extend(_handle_nonfinites(path, sort)) - if sort: - pipeline.append({"$match": {path: {"$ne": None}}}) - - pipeline.append({"$sort": {path: sort}}) - return pipeline + [ { "$group": { From aeb94338680791293d3575d20134cd47df00f20f Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 10:46:02 -0500 Subject: [PATCH 02/10] use exists --- fiftyone/server/lightning.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index 77a655ad0fc..eb3edcd0e33 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -324,7 +324,6 @@ async def _do_async_query( if filter: query.insert(0, {"$match": filter}) - fo.pprint(query) return [i async for i in collection.aggregate(query)] @@ -428,8 +427,7 @@ def _first( if matched_arrays: pipeline += matched_arrays - pipeline.append({"$limit": 1}) - + pipeline.extend([{"$match": {path: {"$exists": True}}}, {"$limit": 1}]) unwound = _unwind(dataset, path, is_frame_field) if unwound: pipeline += unwound From edc4ddcf60233e9ceea31203a34645e16514afbe Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 11:08:59 -0500 Subject: [PATCH 03/10] add to embedded list bounds tests --- tests/unittests/lightning_tests.py | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/tests/unittests/lightning_tests.py b/tests/unittests/lightning_tests.py index b631e8cf080..103fe75a7ca 100644 --- a/tests/unittests/lightning_tests.py +++ b/tests/unittests/lightning_tests.py @@ -1059,7 +1059,11 @@ async def test_group_dataset(self, dataset: fo.Dataset): group = fo.Group() one = fo.Sample( classifications=fo.Classifications( - classifications=[fo.Classification(label="one")] + classifications=[ + fo.Classification(label="one"), + fo.Classification(confidence=1), + fo.Classification(confidence=-1), + ] ), filepath="one.png", group=group.element("one"), @@ -1068,7 +1072,11 @@ async def test_group_dataset(self, dataset: fo.Dataset): ) two = fo.Sample( classifications=fo.Classifications( - classifications=[fo.Classification(label="two")] + classifications=[ + fo.Classification(label="two"), + fo.Classification(confidence=2), + fo.Classification(confidence=-2), + ] ), filepath="two.png", group=group.element("two"), @@ -1080,6 +1088,11 @@ async def test_group_dataset(self, dataset: fo.Dataset): query = """ query Query($input: LightningInput!) { lightning(input: $input) { + ... on FloatLightningResult { + path + min + max + } ... on IntLightningResult { path min @@ -1097,8 +1110,13 @@ async def test_group_dataset(self, dataset: fo.Dataset): result = await _execute( query, dataset, - (fo.IntField, fo.StringField), - ["classifications.classifications.label", "numeric", "string"], + (fo.FloatField, fo.IntField, fo.StringField), + [ + "classifications.classifications.confidence", + "classifications.classifications.label", + "numeric", + "string", + ], frames=False, slice="one", ) @@ -1106,6 +1124,11 @@ async def test_group_dataset(self, dataset: fo.Dataset): self.assertListEqual( result.data["lightning"], [ + { + "path": "classifications.classifications.confidence", + "min": -1.0, + "max": 1.0, + }, { "path": "classifications.classifications.label", "values": ["one"], @@ -1119,8 +1142,13 @@ async def test_group_dataset(self, dataset: fo.Dataset): result = await _execute( query, dataset, - (fo.IntField, fo.StringField), - ["classifications.classifications.label", "numeric", "string"], + (fo.FloatField, fo.IntField, fo.StringField), + [ + "classifications.classifications.confidence", + "classifications.classifications.label", + "numeric", + "string", + ], frames=False, slice="two", ) @@ -1128,6 +1156,11 @@ async def test_group_dataset(self, dataset: fo.Dataset): self.assertListEqual( result.data["lightning"], [ + { + "path": "classifications.classifications.confidence", + "min": -2.0, + "max": 2.0, + }, { "path": "classifications.classifications.label", "values": ["two"], From 46ab13fb60b9b3f723fb462f2bf65755bf221ef9 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 13:02:51 -0500 Subject: [PATCH 04/10] skip nonfinites sort for lists --- fiftyone/server/lightning.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index eb3edcd0e33..44865b5b11d 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -9,6 +9,7 @@ from bson import ObjectId from dataclasses import asdict, dataclass from datetime import date, datetime +import math import typing as t import asyncio @@ -419,20 +420,16 @@ def _first( floats=False, ): pipeline = [{"$sort": {path: sort}}] - - if floats: - pipeline.extend(_handle_nonfinites(path, sort)) - matched_arrays = _match_arrays(dataset, path, is_frame_field) if matched_arrays: pipeline += matched_arrays + elif floats: + pipeline.extend(_handle_nonfinites(path, sort)) pipeline.extend([{"$match": {path: {"$exists": True}}}, {"$limit": 1}]) unwound = _unwind(dataset, path, is_frame_field) if unwound: pipeline += unwound - if floats: - pipeline.extend(_handle_nonfinites(path, sort)) return pipeline + [ { @@ -504,8 +501,9 @@ def _match_arrays(dataset: fo.Dataset, path: str, is_frame_field: bool): def _parse_result(data): if data and data[0]: value = data[0] - if value.get("value", None) is not None: - return value["value"] + if "value" in value: + value = value["value"] + return value if math.isfinite(value) else None return value.get("_id", None) From c36ed04d745a5301b051c0c2c91f814225a0937a Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 13:26:37 -0500 Subject: [PATCH 05/10] handle NaN formatting --- app/packages/core/src/components/Common/utils.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/packages/core/src/components/Common/utils.tsx b/app/packages/core/src/components/Common/utils.tsx index cf70f4ca91d..b5cecb2050e 100644 --- a/app/packages/core/src/components/Common/utils.tsx +++ b/app/packages/core/src/components/Common/utils.tsx @@ -68,13 +68,14 @@ export const getFormatter = (fieldType: string, timeZone: string, bounds) => { ); } - return numeral(v).format( + const str = numeral(v).format( [INT_FIELD, FRAME_NUMBER_FIELD, FRAME_SUPPORT_FIELD].includes(fieldType) ? "0a" : bounds[1] - bounds[0] < 0.1 ? "0.0000a" : "0.00a" ); + return str === "NaN" ? v.toString() : str; }, }; }; From 0f9b3cad0b2ce28ec26fc77a476541ae900c0fb3 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 13:54:55 -0500 Subject: [PATCH 06/10] debugging --- fiftyone/server/lightning.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index 44865b5b11d..de9c38457ed 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -322,9 +322,6 @@ async def _do_async_query( return await _do_distinct_pipeline(dataset, collection, query, filter) - if filter: - query.insert(0, {"$match": filter}) - return [i async for i in collection.aggregate(query)] @@ -420,16 +417,20 @@ def _first( floats=False, ): pipeline = [{"$sort": {path: sort}}] + + if floats: + pipeline.extend(_handle_nonfinites(path, sort)) + matched_arrays = _match_arrays(dataset, path, is_frame_field) if matched_arrays: pipeline += matched_arrays - elif floats: - pipeline.extend(_handle_nonfinites(path, sort)) pipeline.extend([{"$match": {path: {"$exists": True}}}, {"$limit": 1}]) unwound = _unwind(dataset, path, is_frame_field) if unwound: pipeline += unwound + if floats: + pipeline.extend(_handle_nonfinites(path, sort)) return pipeline + [ { From 750694b1dd0ffe81a91a311555dacdcae8c040ea Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 15:03:05 -0500 Subject: [PATCH 07/10] nonfinites tweaks --- .../NumericFieldFilter/RangeSlider.tsx | 5 ++- .../Filters/NumericFieldFilter/state.ts | 22 ++++++++-- fiftyone/server/lightning.py | 16 +++++-- tests/unittests/lightning_tests.py | 43 ++++++++++--------- 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/app/packages/core/src/components/Filters/NumericFieldFilter/RangeSlider.tsx b/app/packages/core/src/components/Filters/NumericFieldFilter/RangeSlider.tsx index b9990cfa284..e098bcd9e03 100644 --- a/app/packages/core/src/components/Filters/NumericFieldFilter/RangeSlider.tsx +++ b/app/packages/core/src/components/Filters/NumericFieldFilter/RangeSlider.tsx @@ -35,9 +35,12 @@ const RangeSlider = ({ const one = useRecoilValue(state.oneBound({ path, modal })); const timeZone = useRecoilValue(fos.timeZone); const hasBounds = useRecoilValue(state.hasBounds({ path, modal })); + const nonfinitesText = useRecoilValue(state.nonfinitesText({ path, modal })); if (!hasBounds) { - return ; + return ( + + ); } const showSlider = hasBounds && !(excluded && defaultRange); diff --git a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts index 927b4af89e0..4cd412fc26b 100644 --- a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts +++ b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts @@ -25,14 +25,28 @@ export const hasDefaultRange = selectorFamily({ }, }); -export const hasNonfinites = selectorFamily({ - key: "hasNonfinites", +export const nonfinitesText = selectorFamily({ + key: "nonfinitesText", get: (params: { path: string; modal: boolean }) => ({ get }) => { - return FLOAT_NONFINITES.every((key) => - get(nonfiniteAtom({ key, ...params })) + console.log( + FLOAT_NONFINITES.map((key) => [ + key, + get(nonfiniteAtom({ key, ...params })), + ]) + .filter(([_, v]) => v) + .map(([k]) => k) + .join(", ") ); + const result = FLOAT_NONFINITES.map((key) => [ + key, + get(nonfiniteAtom({ key, ...params })), + ]) + .filter(([_, v]) => v) + .map(([k]) => k); + + return result.length ? result.join(", ") : null; }, }); diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index de9c38457ed..6119da36ff3 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -322,6 +322,11 @@ async def _do_async_query( return await _do_distinct_pipeline(dataset, collection, query, filter) + if filter: + for k, v in filter.items(): + query.insert(0, {"$match": {k: v}}) + query.insert(0, {"$sort": {k: 1}}) + return [i async for i in collection.aggregate(query)] @@ -418,12 +423,11 @@ def _first( ): pipeline = [{"$sort": {path: sort}}] - if floats: - pipeline.extend(_handle_nonfinites(path, sort)) - matched_arrays = _match_arrays(dataset, path, is_frame_field) if matched_arrays: pipeline += matched_arrays + elif floats: + pipeline.extend(_handle_nonfinites(path, sort)) pipeline.extend([{"$match": {path: {"$exists": True}}}, {"$limit": 1}]) unwound = _unwind(dataset, path, is_frame_field) @@ -504,7 +508,11 @@ def _parse_result(data): value = data[0] if "value" in value: value = value["value"] - return value if math.isfinite(value) else None + return ( + value + if not isinstance(value, float) or math.isfinite(value) + else None + ) return value.get("_id", None) diff --git a/tests/unittests/lightning_tests.py b/tests/unittests/lightning_tests.py index 103fe75a7ca..bd59703ee5e 100644 --- a/tests/unittests/lightning_tests.py +++ b/tests/unittests/lightning_tests.py @@ -535,6 +535,7 @@ async def test_floats(self, dataset: fo.Dataset): """ result = await _execute(query, dataset, fo.FloatField, keys) + self.assertListEqual( result.data["lightning"], [ @@ -568,7 +569,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "classification.inf_list", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -587,7 +588,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "classification.nan_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -605,7 +606,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "classification.ninf_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -631,7 +632,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "detections.detections.inf", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -640,7 +641,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "detections.detections.inf_list", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -650,7 +651,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "detections.detections.nan", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -659,7 +660,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "detections.detections.nan_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -668,7 +669,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "detections.detections.ninf", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -677,7 +678,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "detections.detections.ninf_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -730,7 +731,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "frames.classification.inf_list", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -749,7 +750,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.classification.nan_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -767,7 +768,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.classification.ninf_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -793,7 +794,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "frames.detections.detections.inf", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -802,7 +803,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "frames.detections.detections.inf_list", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -812,7 +813,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.detections.detections.nan", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -821,7 +822,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.detections.detections.nan_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -830,7 +831,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.detections.detections.ninf", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -839,7 +840,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "frames.detections.detections.ninf_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, @@ -928,7 +929,7 @@ async def test_floats(self, dataset: fo.Dataset): { "path": "inf_list", "inf": True, - "max": 1.0, + "max": None, "min": -1.0, "nan": False, "ninf": False, @@ -947,7 +948,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "nan_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": True, "ninf": False, "none": False, @@ -965,7 +966,7 @@ async def test_floats(self, dataset: fo.Dataset): "path": "ninf_list", "inf": False, "max": 1.0, - "min": -1.0, + "min": None, "nan": False, "ninf": True, "none": False, From f47878456a5638d95fbfd0338bfcd480abf42831 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 15:16:11 -0500 Subject: [PATCH 08/10] selector fixes --- .../Filters/NumericFieldFilter/state.ts | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts index 4cd412fc26b..b03e2c3134f 100644 --- a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts +++ b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts @@ -1,5 +1,5 @@ import type { Nonfinite } from "@fiftyone/state"; -import { boundsAtom, nonfiniteAtom, rangeAtom } from "@fiftyone/state"; +import { boundsAtom, nonfiniteData, rangeAtom } from "@fiftyone/state"; import { selectorFamily } from "recoil"; export const FLOAT_NONFINITES: Nonfinite[] = ["inf", "ninf", "nan"]; @@ -30,22 +30,10 @@ export const nonfinitesText = selectorFamily({ get: (params: { path: string; modal: boolean }) => ({ get }) => { - console.log( - FLOAT_NONFINITES.map((key) => [ - key, - get(nonfiniteAtom({ key, ...params })), - ]) - .filter(([_, v]) => v) - .map(([k]) => k) - .join(", ") + const data = get(nonfiniteData({ ...params, extended: false })); + const result = Object.fromEntries( + Object.entries(data).filter(([k, v]) => k !== "none" && Boolean(v)) ); - const result = FLOAT_NONFINITES.map((key) => [ - key, - get(nonfiniteAtom({ key, ...params })), - ]) - .filter(([_, v]) => v) - .map(([k]) => k); - return result.length ? result.join(", ") : null; }, }); From f085b74e74d1e1b568a88a2c66c1f38b43309396 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 16:17:26 -0500 Subject: [PATCH 09/10] always use distinct for embedded lists --- fiftyone/server/lightning.py | 12 ++++++------ fiftyone/server/view.py | 17 ++++++++++------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/fiftyone/server/lightning.py b/fiftyone/server/lightning.py index 6119da36ff3..9eeed0acb4b 100644 --- a/fiftyone/server/lightning.py +++ b/fiftyone/server/lightning.py @@ -140,11 +140,11 @@ async def lightning_resolver( for item in sublist ] - filter = ( - {f"{dataset.group_field}.name": input.slice} - if dataset.group_field and input.slice - else None - ) + if dataset.group_field and input.slice: + filter = {f"{dataset.group_field}.name": input.slice} + dataset.group_slice = input.slice + else: + filter = {} result = await _do_async_pooled_queries(dataset, flattened, filter) results = [] @@ -317,7 +317,7 @@ async def _do_async_query( filter: t.Optional[t.Mapping[str, str]], ): if isinstance(query, DistinctQuery): - if query.has_list and not query.filters: + if query.has_list: return await _do_distinct_query(collection, query, filter) return await _do_distinct_pipeline(dataset, collection, query, filter) diff --git a/fiftyone/server/view.py b/fiftyone/server/view.py index 9dbae98af9e..414386f7317 100644 --- a/fiftyone/server/view.py +++ b/fiftyone/server/view.py @@ -614,8 +614,9 @@ def _make_range_query(path: str, field: fof.Field, args): def _make_scalar_expression(f, args, field, list_field=None, is_label=False): expr = None if _is_support(field): - mn, mx = args["range"] - expr = (f[0] >= mn) & (f[1] <= mx) + if "range" in args: + mn, mx = args["range"] + expr = (f[0] >= mn) & (f[1] <= mx) elif isinstance(field, fof.ListField): if isinstance(list_field, str): return f.filter( @@ -640,12 +641,14 @@ def _make_scalar_expression(f, args, field, list_field=None, is_label=False): if not true and not false: expr = (f != True) & (f != False) elif _is_datetime(field): - mn, mx = args["range"] - p = fou.timestamp_to_datetime - expr = (f >= p(mn)) & (f <= p(mx)) + if "range" in args: + mn, mx = args["range"] + p = fou.timestamp_to_datetime + expr = (f >= p(mn)) & (f <= p(mx)) elif isinstance(field, (fof.FloatField, fof.IntField)): - mn, mx = args["range"] - expr = (f >= mn) & (f <= mx) + if "range" in args: + mn, mx = args["range"] + expr = (f >= mn) & (f <= mx) else: values = args["values"] if not values: From 249f48ea7c742cd1e19d1c9a3e12bcb8822091ba Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Mon, 2 Dec 2024 16:30:03 -0500 Subject: [PATCH 10/10] fix selector --- .../src/components/Filters/NumericFieldFilter/state.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts index b03e2c3134f..6dbaf87e231 100644 --- a/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts +++ b/app/packages/core/src/components/Filters/NumericFieldFilter/state.ts @@ -31,10 +31,11 @@ export const nonfinitesText = selectorFamily({ (params: { path: string; modal: boolean }) => ({ get }) => { const data = get(nonfiniteData({ ...params, extended: false })); - const result = Object.fromEntries( - Object.entries(data).filter(([k, v]) => k !== "none" && Boolean(v)) + const result = Object.entries(data).filter( + ([k, v]) => k !== "none" && Boolean(v) ); - return result.length ? result.join(", ") : null; + + return result.length ? result.map(([key]) => key).join(", ") : null; }, });