@trackunit/filters-asset-filter-definitions 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +209 -96
- package/index.esm.js +209 -98
- package/package.json +16 -16
- package/src/defaultFilters/defaults/area/areaSchemas.d.ts +155 -0
- package/src/defaultFilters/defaults/area/usePlacesSearch.d.ts +132 -0
- package/src/defaultFilters/defaults/index.d.ts +1 -1
- package/src/generated/graphql-api/gql.d.ts +2 -2
- package/src/generated/graphql-api/graphql.d.ts +19 -7
- package/src/generated/graphql-api/mock.d.ts +5 -2
- package/src/defaultFilters/defaults/area/useAreaSearch.d.ts +0 -74
package/index.cjs.js
CHANGED
|
@@ -12,9 +12,9 @@ var filtersGraphqlHook = require('@trackunit/filters-graphql-hook');
|
|
|
12
12
|
var utilizationIndicator = require('@trackunit/utilization-indicator');
|
|
13
13
|
var geoJsonUtils = require('@trackunit/geo-json-utils');
|
|
14
14
|
var reactComponents = require('@trackunit/react-components');
|
|
15
|
+
var stringTs = require('string-ts');
|
|
15
16
|
var zod = require('zod');
|
|
16
17
|
var sharedUtils = require('@trackunit/shared-utils');
|
|
17
|
-
var stringTs = require('string-ts');
|
|
18
18
|
var translationsMachineType = require('@trackunit/translations-machine-type');
|
|
19
19
|
var criticalityIndicator = require('@trackunit/criticality-indicator');
|
|
20
20
|
var tailwindMerge = require('tailwind-merge');
|
|
@@ -1540,13 +1540,13 @@ const GetAssetTelematicsDeviceConnectionSummaryDocument = {
|
|
|
1540
1540
|
},
|
|
1541
1541
|
],
|
|
1542
1542
|
};
|
|
1543
|
-
const
|
|
1543
|
+
const GetPlaceAutocompletePredictionsDocument = {
|
|
1544
1544
|
kind: "Document",
|
|
1545
1545
|
definitions: [
|
|
1546
1546
|
{
|
|
1547
1547
|
kind: "OperationDefinition",
|
|
1548
1548
|
operation: "query",
|
|
1549
|
-
name: { kind: "Name", value: "
|
|
1549
|
+
name: { kind: "Name", value: "GetPlaceAutocompletePredictions" },
|
|
1550
1550
|
variableDefinitions: [
|
|
1551
1551
|
{
|
|
1552
1552
|
kind: "VariableDefinition",
|
|
@@ -1559,7 +1559,7 @@ const FindPlacesDocument = {
|
|
|
1559
1559
|
selections: [
|
|
1560
1560
|
{
|
|
1561
1561
|
kind: "Field",
|
|
1562
|
-
name: { kind: "Name", value: "
|
|
1562
|
+
name: { kind: "Name", value: "placeAutocompletePredictions" },
|
|
1563
1563
|
arguments: [
|
|
1564
1564
|
{
|
|
1565
1565
|
kind: "Argument",
|
|
@@ -1567,6 +1567,46 @@ const FindPlacesDocument = {
|
|
|
1567
1567
|
value: { kind: "Variable", name: { kind: "Name", value: "search" } },
|
|
1568
1568
|
},
|
|
1569
1569
|
],
|
|
1570
|
+
selectionSet: {
|
|
1571
|
+
kind: "SelectionSet",
|
|
1572
|
+
selections: [
|
|
1573
|
+
{ kind: "Field", name: { kind: "Name", value: "placeId" } },
|
|
1574
|
+
{ kind: "Field", name: { kind: "Name", value: "description" } },
|
|
1575
|
+
],
|
|
1576
|
+
},
|
|
1577
|
+
},
|
|
1578
|
+
],
|
|
1579
|
+
},
|
|
1580
|
+
},
|
|
1581
|
+
],
|
|
1582
|
+
};
|
|
1583
|
+
const GetPlaceDetailsDocument = {
|
|
1584
|
+
kind: "Document",
|
|
1585
|
+
definitions: [
|
|
1586
|
+
{
|
|
1587
|
+
kind: "OperationDefinition",
|
|
1588
|
+
operation: "query",
|
|
1589
|
+
name: { kind: "Name", value: "GetPlaceDetails" },
|
|
1590
|
+
variableDefinitions: [
|
|
1591
|
+
{
|
|
1592
|
+
kind: "VariableDefinition",
|
|
1593
|
+
variable: { kind: "Variable", name: { kind: "Name", value: "placeId" } },
|
|
1594
|
+
type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } },
|
|
1595
|
+
},
|
|
1596
|
+
],
|
|
1597
|
+
selectionSet: {
|
|
1598
|
+
kind: "SelectionSet",
|
|
1599
|
+
selections: [
|
|
1600
|
+
{
|
|
1601
|
+
kind: "Field",
|
|
1602
|
+
name: { kind: "Name", value: "placeDetails" },
|
|
1603
|
+
arguments: [
|
|
1604
|
+
{
|
|
1605
|
+
kind: "Argument",
|
|
1606
|
+
name: { kind: "Name", value: "placeId" },
|
|
1607
|
+
value: { kind: "Variable", name: { kind: "Name", value: "placeId" } },
|
|
1608
|
+
},
|
|
1609
|
+
],
|
|
1570
1610
|
selectionSet: {
|
|
1571
1611
|
kind: "SelectionSet",
|
|
1572
1612
|
selections: [
|
|
@@ -1720,58 +1760,100 @@ const areaFilterInternalSchema = zod.z.object({
|
|
|
1720
1760
|
geometry: areaFilterInternalGeoJsonGeometrySchema,
|
|
1721
1761
|
properties: zod.z.object({
|
|
1722
1762
|
formattedAddress: zod.z.string(),
|
|
1763
|
+
addressComponents: zod.z
|
|
1764
|
+
.array(zod.z.object({
|
|
1765
|
+
longName: zod.z.string(),
|
|
1766
|
+
shortName: zod.z.string(),
|
|
1767
|
+
types: zod.z.array(zod.z.string()),
|
|
1768
|
+
}))
|
|
1769
|
+
.optional(),
|
|
1723
1770
|
}),
|
|
1724
1771
|
dateIsoString: zod.z.string().datetime().optional(), //can not be date object since useLocalStorage (with validation) does not support date objects
|
|
1725
1772
|
});
|
|
1773
|
+
// Complementary place schemas - used for the Places API search
|
|
1774
|
+
const placePredictionSchema = zod.z.object({
|
|
1775
|
+
placeId: zod.z.string(),
|
|
1776
|
+
description: zod.z.string(),
|
|
1777
|
+
});
|
|
1778
|
+
const placeSchema = areaFilterInternalSchema.extend({
|
|
1779
|
+
placeId: zod.z.string(),
|
|
1780
|
+
description: zod.z.string(),
|
|
1781
|
+
});
|
|
1726
1782
|
|
|
1727
1783
|
const SHARED_LOCATIONS_LOCAL_STORAGE_KEY = "shared-recent-locations";
|
|
1728
1784
|
const MAX_RECENT_SEARCHES$1 = 5;
|
|
1729
1785
|
const MIN_LENGTH_SEARCH = 3;
|
|
1730
1786
|
const MAX_RESULTS = 5;
|
|
1731
1787
|
/**
|
|
1732
|
-
*
|
|
1733
|
-
*
|
|
1734
|
-
*
|
|
1788
|
+
* Hook for place search with autocomplete predictions and recent places history.
|
|
1789
|
+
* Queries the internal GeoEnrichment API for predictions and place details (geo data) from Google's Places Autocomplete.
|
|
1790
|
+
*
|
|
1791
|
+
* Local storage for recent searches prevents unnecessary repetitive queries.
|
|
1735
1792
|
*/
|
|
1736
|
-
const
|
|
1793
|
+
const usePlacesSearch = ({ localStorageKey = SHARED_LOCATIONS_LOCAL_STORAGE_KEY, maxRecentSearches = MAX_RECENT_SEARCHES$1, maxResults = MAX_RESULTS, }) => {
|
|
1737
1794
|
const [t] = useTranslation();
|
|
1738
1795
|
const [searchString, setSearchString] = react.useState("");
|
|
1739
|
-
const [
|
|
1796
|
+
const [selectedPrediction, setSelectedPrediction] = react.useState(undefined);
|
|
1797
|
+
const [recentPlaces, setRecentPlaces] = reactCoreHooks.useLocalStorage({
|
|
1740
1798
|
defaultState: [],
|
|
1741
1799
|
key: localStorageKey,
|
|
1742
|
-
schema: zod.z.array(
|
|
1800
|
+
schema: zod.z.array(placeSchema),
|
|
1743
1801
|
});
|
|
1744
1802
|
const debouncedSearchString = reactComponents.useDebounce(searchString);
|
|
1745
|
-
const
|
|
1803
|
+
const isRecentPlace = react.useCallback((placeId) => {
|
|
1804
|
+
return recentPlaces.some(r => r.placeId === placeId);
|
|
1805
|
+
}, [recentPlaces]);
|
|
1806
|
+
// Query for place predictions
|
|
1807
|
+
const { data: placeAutocompleteData, previousData: previousPlaceAutocompleteData, loading: loadingPlaceAutocomplete, } = client.useQuery(GetPlaceAutocompletePredictionsDocument, {
|
|
1746
1808
|
variables: { search: debouncedSearchString },
|
|
1747
1809
|
skip: !debouncedSearchString || searchString.replace(/\s/g, "").length < MIN_LENGTH_SEARCH,
|
|
1748
1810
|
});
|
|
1749
|
-
const
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1811
|
+
const stablePlaceAutocompleteData = react.useMemo(() => placeAutocompleteData ?? previousPlaceAutocompleteData, [placeAutocompleteData, previousPlaceAutocompleteData]);
|
|
1812
|
+
// Query for place details when a place is selected
|
|
1813
|
+
const { data: placeDetailsData, loading: loadingDetails } = client.useQuery(GetPlaceDetailsDocument, {
|
|
1814
|
+
variables: { placeId: selectedPrediction?.placeId ?? "" },
|
|
1815
|
+
skip: !selectedPrediction?.placeId || isRecentPlace(selectedPrediction.placeId),
|
|
1816
|
+
});
|
|
1817
|
+
// Combine place details and selected prediction
|
|
1818
|
+
const selectedPlaceData = react.useMemo(() => {
|
|
1819
|
+
if (!selectedPrediction) {
|
|
1820
|
+
return null;
|
|
1821
|
+
}
|
|
1822
|
+
if (isRecentPlace(selectedPrediction.placeId)) {
|
|
1823
|
+
return recentPlaces.find(r => r.placeId === selectedPrediction.placeId);
|
|
1824
|
+
}
|
|
1825
|
+
if (!placeDetailsData?.placeDetails) {
|
|
1826
|
+
return null;
|
|
1827
|
+
}
|
|
1828
|
+
const details = placeDetailsData.placeDetails;
|
|
1829
|
+
const parsedBbox = geoJsonUtils.geoJsonBboxSchema.safeParse(details.bbox);
|
|
1830
|
+
const parsedGeometry = areaFilterInternalGeoJsonGeometrySchema.safeParse(details.geometry?.type
|
|
1831
|
+
? {
|
|
1832
|
+
type: stringTs.titleCase(details.geometry.type),
|
|
1833
|
+
coordinates: details.geometry.coordinates,
|
|
1762
1834
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
.
|
|
1770
|
-
|
|
1771
|
-
|
|
1835
|
+
: undefined);
|
|
1836
|
+
if (!parsedGeometry.success || !parsedBbox.success || !details.properties?.formattedAddress) {
|
|
1837
|
+
return null;
|
|
1838
|
+
}
|
|
1839
|
+
return {
|
|
1840
|
+
bBox: parsedBbox.data,
|
|
1841
|
+
geometry: parsedGeometry.data,
|
|
1842
|
+
properties: { formattedAddress: details.properties.formattedAddress },
|
|
1843
|
+
placeId: selectedPrediction.placeId,
|
|
1844
|
+
description: selectedPrediction.description,
|
|
1845
|
+
};
|
|
1846
|
+
}, [placeDetailsData, selectedPrediction, isRecentPlace, recentPlaces]);
|
|
1847
|
+
// List of predictions or recent places
|
|
1848
|
+
const places = react.useMemo(() => {
|
|
1849
|
+
if (debouncedSearchString) {
|
|
1850
|
+
return stablePlaceAutocompleteData?.placeAutocompletePredictions ?? [];
|
|
1851
|
+
}
|
|
1852
|
+
return recentPlaces;
|
|
1853
|
+
}, [debouncedSearchString, stablePlaceAutocompleteData, recentPlaces]);
|
|
1772
1854
|
const hint = react.useMemo(() => {
|
|
1773
1855
|
const noWhiteSpaceSearchString = searchString.replace(/\s/g, "");
|
|
1774
|
-
if (searchString.length === 0 &&
|
|
1856
|
+
if (searchString.length === 0 && places.length === 0) {
|
|
1775
1857
|
return t("filters.shared.noHistory");
|
|
1776
1858
|
}
|
|
1777
1859
|
else if (noWhiteSpaceSearchString.length === 0 && searchString.length > 0) {
|
|
@@ -1780,47 +1862,61 @@ const useAreaSearch = ({ localStorageKey = SHARED_LOCATIONS_LOCAL_STORAGE_KEY, m
|
|
|
1780
1862
|
else if (searchString.length > 0 && noWhiteSpaceSearchString.length < MIN_LENGTH_SEARCH) {
|
|
1781
1863
|
return t("filters.shared.typeMore");
|
|
1782
1864
|
}
|
|
1783
|
-
else if (
|
|
1865
|
+
else if (loadingPlaceAutocomplete && places.length === 0) {
|
|
1784
1866
|
return t("filtersBar.loading");
|
|
1785
1867
|
}
|
|
1786
|
-
else if (
|
|
1868
|
+
else if (places.length === 0) {
|
|
1787
1869
|
return t("filtersBar.emptyResults");
|
|
1788
1870
|
}
|
|
1789
1871
|
return null;
|
|
1790
|
-
}, [searchString,
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
const noDuplicatesRecent = prev.filter(r => r.
|
|
1872
|
+
}, [searchString, places, t, loadingPlaceAutocomplete]);
|
|
1873
|
+
const addRecentPlace = react.useCallback((place) => {
|
|
1874
|
+
setRecentPlaces(prev => {
|
|
1875
|
+
const noDuplicatesRecent = prev.filter(r => r.placeId !== place.placeId);
|
|
1794
1876
|
const cappedLengthRecentAreas = noDuplicatesRecent.slice(0, maxRecentSearches - 1);
|
|
1795
1877
|
return [
|
|
1796
1878
|
{
|
|
1797
|
-
...
|
|
1879
|
+
...place,
|
|
1798
1880
|
dateIsoString: new Date().toISOString(),
|
|
1799
1881
|
},
|
|
1800
1882
|
...cappedLengthRecentAreas,
|
|
1801
1883
|
];
|
|
1802
1884
|
});
|
|
1885
|
+
}, [maxRecentSearches, setRecentPlaces]);
|
|
1886
|
+
const removeRecentPlace = (place) => {
|
|
1887
|
+
setRecentPlaces(prev => prev.filter(r => r.placeId !== place.placeId));
|
|
1803
1888
|
};
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1889
|
+
react.useEffect(() => {
|
|
1890
|
+
if (!selectedPlaceData) {
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
if (!isRecentPlace(selectedPlaceData.placeId)) {
|
|
1894
|
+
addRecentPlace(selectedPlaceData);
|
|
1895
|
+
}
|
|
1896
|
+
}, [selectedPlaceData, addRecentPlace, isRecentPlace]);
|
|
1807
1897
|
return {
|
|
1808
|
-
|
|
1809
|
-
loading,
|
|
1898
|
+
places: places.slice(0, maxResults),
|
|
1899
|
+
loading: loadingPlaceAutocomplete || loadingDetails,
|
|
1810
1900
|
searchString,
|
|
1811
1901
|
setSearchString,
|
|
1812
1902
|
debouncedSearchString,
|
|
1813
|
-
|
|
1814
|
-
|
|
1903
|
+
recentPlaces,
|
|
1904
|
+
setRecentPlaces,
|
|
1815
1905
|
hint,
|
|
1816
|
-
|
|
1817
|
-
|
|
1906
|
+
removeRecentPlace,
|
|
1907
|
+
addRecentPlace,
|
|
1908
|
+
selectedPrediction,
|
|
1909
|
+
setSelectedPrediction,
|
|
1910
|
+
selectedPlaceData,
|
|
1818
1911
|
};
|
|
1819
1912
|
};
|
|
1820
1913
|
|
|
1821
1914
|
const AreaView = (props) => {
|
|
1822
1915
|
const [t] = useTranslation();
|
|
1823
1916
|
const { logEvent } = reactCoreHooks.useAnalytics(filtersFilterBar.FilterEvents);
|
|
1917
|
+
const { places, recentPlaces, setRecentPlaces, selectedPlaceData, setSelectedPrediction, searchString, setSearchString, debouncedSearchString, loading, hint, } = usePlacesSearch({
|
|
1918
|
+
localStorageKey: "shared-recent-locations",
|
|
1919
|
+
});
|
|
1824
1920
|
const placeholderOption = react.useMemo(() => {
|
|
1825
1921
|
// If no selected option, use this placeholder option
|
|
1826
1922
|
// Aka if applied from outside the filter UI
|
|
@@ -1834,59 +1930,73 @@ const AreaView = (props) => {
|
|
|
1834
1930
|
geometry: props.value,
|
|
1835
1931
|
properties: { formattedAddress: t("assetFilters.area.origin.mapArea") },
|
|
1836
1932
|
dateIsoString: undefined,
|
|
1933
|
+
placeId: "applied-map-area",
|
|
1934
|
+
description: t("assetFilters.area.origin.mapArea"),
|
|
1837
1935
|
}
|
|
1838
1936
|
: null;
|
|
1839
1937
|
}, [props.value, t]);
|
|
1840
|
-
const selectedOption = getSelectedOption(props.value, props.
|
|
1938
|
+
const selectedOption = react.useMemo(() => getSelectedOption(props.value, recentPlaces), [props.value, recentPlaces]);
|
|
1939
|
+
const setFilter = react.useCallback((place) => {
|
|
1940
|
+
const { properties, bBox, geometry, dateIsoString } = place;
|
|
1941
|
+
if (geometry.type === "Polygon") {
|
|
1942
|
+
// Polygons are stored directly
|
|
1943
|
+
props.filterBarActions.setArea(geometry);
|
|
1944
|
+
}
|
|
1945
|
+
else {
|
|
1946
|
+
// All other geometries are stored by the filter as a
|
|
1947
|
+
// polygon derived from the features bbox
|
|
1948
|
+
props.filterBarActions.setArea(geoJsonUtils.getPolygonFromBbox(bBox));
|
|
1949
|
+
}
|
|
1950
|
+
logEvent("Filters Applied - V2", {
|
|
1951
|
+
type: "AreaFilter",
|
|
1952
|
+
value: properties.formattedAddress,
|
|
1953
|
+
additionalProperties: {
|
|
1954
|
+
geometryType: geometry.type,
|
|
1955
|
+
wasPreviousSearch: Boolean(dateIsoString),
|
|
1956
|
+
},
|
|
1957
|
+
});
|
|
1958
|
+
}, [props.filterBarActions, logEvent]);
|
|
1959
|
+
react.useEffect(() => {
|
|
1960
|
+
if (!selectedPlaceData) {
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
if (selectedPlaceData.placeId === selectedOption?.placeId) {
|
|
1964
|
+
return;
|
|
1965
|
+
}
|
|
1966
|
+
setFilter(selectedPlaceData);
|
|
1967
|
+
}, [selectedPlaceData, setFilter, selectedOption]);
|
|
1841
1968
|
if (!props.showWithSearch) {
|
|
1842
|
-
//
|
|
1969
|
+
// Temporary while we are testing the new area filter bar behind feature flag
|
|
1843
1970
|
// This emulated the old look of the boundingbox filter
|
|
1844
1971
|
// TODO [BUSS] Remove this once the new area filter is ready for prime time
|
|
1845
1972
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(filtersFilterBar.FilterHeader, { ...props.filterDefinition, ...props.filterBarActions }), jsxRuntime.jsx(reactFilterComponents.FilterBody, { limitSize: true, children: jsxRuntime.jsx("p", { className: "p-2", children: `${t("assetFilters.boundingBoxFilter.value")}` }) })] }));
|
|
1846
1973
|
}
|
|
1847
|
-
return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(filtersFilterBar.FilterHeader, { ...props.filterDefinition, ...props.filterBarActions, loading:
|
|
1848
|
-
onChange:
|
|
1849
|
-
value:
|
|
1850
|
-
count:
|
|
1974
|
+
return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(filtersFilterBar.FilterHeader, { ...props.filterDefinition, ...props.filterBarActions, loading: loading, searchEnabled: true, searchProps: {
|
|
1975
|
+
onChange: setSearchString,
|
|
1976
|
+
value: searchString,
|
|
1977
|
+
count: places.length,
|
|
1851
1978
|
placeholder: t("assetFilters.area.searchPlaceholder"),
|
|
1852
|
-
} }), jsxRuntime.jsx(reactFilterComponents.FilterBody, { limitSize: true, children:
|
|
1979
|
+
} }), jsxRuntime.jsx(reactFilterComponents.FilterBody, { limitSize: true, children: places.length > 0 || placeholderOption ? (jsxRuntime.jsx(filtersFilterBar.FilterResults, { loading: false, results: [
|
|
1853
1980
|
// Show placeholder option first if selected option is not in filterResult
|
|
1854
1981
|
// Aka if applied from outside the filter UI
|
|
1855
|
-
...(placeholderOption && !selectedOption && !
|
|
1856
|
-
...
|
|
1982
|
+
...(placeholderOption && !selectedOption && !debouncedSearchString ? [placeholderOption] : []),
|
|
1983
|
+
...places,
|
|
1857
1984
|
], children: filterResult => (jsxRuntime.jsx(reactFormComponents.RadioGroup, { className: "m-1", id: "areaFilter", onChange: e => {
|
|
1858
|
-
const
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
});
|
|
1871
|
-
props.addRecentArea(parsedResultLookup.data);
|
|
1872
|
-
if (geometry.type === "Polygon") {
|
|
1873
|
-
// Polygons are stored directly
|
|
1874
|
-
props.filterBarActions.setArea(geometry);
|
|
1875
|
-
}
|
|
1876
|
-
else {
|
|
1877
|
-
// All other geometries are stored by the filter as a
|
|
1878
|
-
// polygon derived from the features bbox
|
|
1879
|
-
props.filterBarActions.setArea(geoJsonUtils.getPolygonFromBbox(bBox));
|
|
1880
|
-
}
|
|
1881
|
-
props.setSearchString(""); // Clear search input after selection
|
|
1882
|
-
}, value: selectedOption?.properties.formattedAddress ??
|
|
1883
|
-
placeholderOption?.properties.formattedAddress ?? // placeholder if no selected option
|
|
1884
|
-
"", children: filterResult.map(({ properties, dateIsoString }, index) => {
|
|
1885
|
-
const selected = selectedOption?.properties.formattedAddress === properties.formattedAddress;
|
|
1886
|
-
return (jsxRuntime.jsx(reactFilterComponents.RadioFilterItem, { label: properties.formattedAddress, selected: selected, suffix:
|
|
1985
|
+
const findOption = filterResult.find(result => result.description === e.currentTarget.value);
|
|
1986
|
+
findOption &&
|
|
1987
|
+
setSelectedPrediction({
|
|
1988
|
+
placeId: findOption.placeId,
|
|
1989
|
+
description: findOption.description,
|
|
1990
|
+
});
|
|
1991
|
+
setSearchString(""); // Clear search input after selection
|
|
1992
|
+
}, value: selectedOption?.description ??
|
|
1993
|
+
placeholderOption?.description ?? // placeholder if no selected option
|
|
1994
|
+
"", children: filterResult.map(({ ...rest }, index) => {
|
|
1995
|
+
const selected = selectedOption?.description === rest.description;
|
|
1996
|
+
return (jsxRuntime.jsx(reactFilterComponents.RadioFilterItem, { label: rest.description, selected: selected, suffix:
|
|
1887
1997
|
// Only show clear button if not currently selected and previously searched
|
|
1888
|
-
!selected && dateIsoString ? (jsxRuntime.jsx(ClearItemButton, { onClick: () =>
|
|
1889
|
-
}) })) })) : (jsxRuntime.jsx("p", { className: "py-2 text-center text-sm text-gray-400", children:
|
|
1998
|
+
!selected && "dateIsoString" in rest ? (jsxRuntime.jsx(ClearItemButton, { onClick: () => setRecentPlaces(prev => prev.filter(r => r.description !== rest.description)) })) : null, value: rest.description }, index));
|
|
1999
|
+
}) })) })) : (jsxRuntime.jsx("p", { className: "py-2 text-center text-sm text-gray-400", children: hint })) }), debouncedSearchString.length === 0 ? (jsxRuntime.jsx(RecentSearchesFooter, { count: recentPlaces.length, onClearAll: () => setRecentPlaces([]) })) : null] }));
|
|
1890
2000
|
};
|
|
1891
2001
|
/**
|
|
1892
2002
|
* Area filter definition
|
|
@@ -1897,7 +2007,7 @@ const useAreaFilter = ({ showWithSearch } = {
|
|
|
1897
2007
|
showWithSearch: () => true,
|
|
1898
2008
|
}) => {
|
|
1899
2009
|
const [t] = useTranslation();
|
|
1900
|
-
const
|
|
2010
|
+
const { recentPlaces } = usePlacesSearch({
|
|
1901
2011
|
localStorageKey: "shared-recent-locations",
|
|
1902
2012
|
});
|
|
1903
2013
|
const result = react.useMemo(() => {
|
|
@@ -1910,14 +2020,15 @@ const useAreaFilter = ({ showWithSearch } = {
|
|
|
1910
2020
|
showInStarredMenu: () => showWithSearch(),
|
|
1911
2021
|
showInFilterBar: () => showWithSearch(),
|
|
1912
2022
|
valueAsText: value => {
|
|
1913
|
-
|
|
2023
|
+
// Match the applied area filter to the places option if it exists in the recent places
|
|
2024
|
+
const nameOfSelectedArea = getSelectedOption(value, recentPlaces);
|
|
1914
2025
|
return showWithSearch()
|
|
1915
|
-
? (nameOfSelectedArea?.
|
|
2026
|
+
? (nameOfSelectedArea?.description ?? t("assetFilters.area.active"))
|
|
1916
2027
|
: t("assetFilters.boundingBoxFilter.value");
|
|
1917
2028
|
},
|
|
1918
|
-
component: props => jsxRuntime.jsx(AreaView, { ...props,
|
|
2029
|
+
component: props => jsxRuntime.jsx(AreaView, { ...props, showWithSearch: showWithSearch() }),
|
|
1919
2030
|
};
|
|
1920
|
-
}, [t, showWithSearch,
|
|
2031
|
+
}, [t, showWithSearch, recentPlaces]);
|
|
1921
2032
|
return result;
|
|
1922
2033
|
};
|
|
1923
2034
|
const getSelectedOption = (value, options) => {
|
|
@@ -3493,11 +3604,12 @@ exports.assetTypeConst = assetTypeConst;
|
|
|
3493
3604
|
exports.mapActivityToLabelId = mapActivityToLabelId;
|
|
3494
3605
|
exports.mapMetadataCompletenessToLabelId = mapMetadataCompletenessToLabelId;
|
|
3495
3606
|
exports.metadataCompleteness = metadataCompleteness;
|
|
3607
|
+
exports.placePredictionSchema = placePredictionSchema;
|
|
3608
|
+
exports.placeSchema = placeSchema;
|
|
3496
3609
|
exports.sortSiteTypeSummary = sortSiteTypeSummary;
|
|
3497
3610
|
exports.useActiveFilterFilter = useActiveFilterFilter;
|
|
3498
3611
|
exports.useActivityFilter = useActivityFilter;
|
|
3499
3612
|
exports.useAreaFilter = useAreaFilter;
|
|
3500
|
-
exports.useAreaSearch = useAreaSearch;
|
|
3501
3613
|
exports.useAssetIdsFilter = useAssetIdsFilter;
|
|
3502
3614
|
exports.useAssetTypeFilter = useAssetTypeFilter;
|
|
3503
3615
|
exports.useBrandFilter = useBrandFilter;
|
|
@@ -3512,6 +3624,7 @@ exports.useMetadataCompletenessFilter = useMetadataCompletenessFilter;
|
|
|
3512
3624
|
exports.useModelsFilter = useModelsFilter;
|
|
3513
3625
|
exports.useOwnerAccountIdsFilter = useOwnerAccountIdsFilter;
|
|
3514
3626
|
exports.usePeriodFilter = usePeriodFilter;
|
|
3627
|
+
exports.usePlacesSearch = usePlacesSearch;
|
|
3515
3628
|
exports.useProductionYearFilter = useProductionYearFilter;
|
|
3516
3629
|
exports.useSearchFilter = useSearchFilter;
|
|
3517
3630
|
exports.useServicePlanStatusFilter = useServicePlanStatusFilter;
|