Merge pull request #2678 from Maxime-J/search-formatted-metrics

#2665 fix proposal
This commit is contained in:
Mike Cao 2024-11-28 16:36:40 -08:00 committed by GitHub
commit 8925283564
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 61 additions and 14 deletions

View File

@ -2,12 +2,14 @@ import useMessages from './useMessages';
import { BROWSERS, OS_NAMES } from 'lib/constants'; import { BROWSERS, OS_NAMES } from 'lib/constants';
import useLocale from './useLocale'; import useLocale from './useLocale';
import useCountryNames from './useCountryNames'; import useCountryNames from './useCountryNames';
import useLanguageNames from './useLanguageNames';
import regions from '../../../public/iso-3166-2.json'; import regions from '../../../public/iso-3166-2.json';
export function useFormat() { export function useFormat() {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { locale } = useLocale(); const { locale } = useLocale();
const { countryNames } = useCountryNames(locale); const { countryNames } = useCountryNames(locale);
const { languageNames } = useLanguageNames(locale);
const formatOS = (value: string): string => { const formatOS = (value: string): string => {
return OS_NAMES[value] || value; return OS_NAMES[value] || value;
@ -34,6 +36,10 @@ export function useFormat() {
return countryNames[country] ? `${value}, ${countryNames[country]}` : value; return countryNames[country] ? `${value}, ${countryNames[country]}` : value;
}; };
const formatLanguage = (value: string): string => {
return languageNames[value?.split('-')[0]] || value;
};
const formatValue = (value: string, type: string, data?: { [key: string]: any }): string => { const formatValue = (value: string, type: string, data?: { [key: string]: any }): string => {
switch (type) { switch (type) {
case 'os': case 'os':
@ -48,12 +54,23 @@ export function useFormat() {
return formatRegion(value); return formatRegion(value);
case 'city': case 'city':
return formatCity(value, data?.country); return formatCity(value, data?.country);
case 'language':
return formatLanguage(value);
default: default:
return value; return value;
} }
}; };
return { formatOS, formatBrowser, formatDevice, formatCountry, formatRegion, formatValue }; return {
formatOS,
formatBrowser,
formatDevice,
formatCountry,
formatRegion,
formatCity,
formatLanguage,
formatValue,
};
} }
export default useFormat; export default useFormat;

View File

@ -1,25 +1,25 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable'; import MetricsTable, { MetricsTableProps } from './MetricsTable';
import { emptyFilter } from 'lib/filters'; import { emptyFilter } from 'lib/filters';
import FilterLink from 'components/common/FilterLink'; import FilterLink from 'components/common/FilterLink';
import TypeIcon from 'components/common/TypeIcon'; import TypeIcon from 'components/common/TypeIcon';
import { useLocale } from 'components/hooks'; import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
import { useCountryNames } from 'components/hooks'; import { useFormat } from 'components/hooks';
export function CitiesTable(props: MetricsTableProps) { export function CitiesTable(props: MetricsTableProps) {
const { locale } = useLocale();
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { countryNames } = useCountryNames(locale); const { formatCity } = useFormat();
const renderLabel = (city: string, country: string) => {
const countryName = countryNames[country];
return countryName ? `${city}, ${countryName}` : city;
};
const renderLink = ({ x: city, country }) => { const renderLink = ({ x: city, country }) => {
return ( return (
<FilterLink id="city" value={city} label={renderLabel(city, country)}> <FilterLink id="city" value={city} label={formatCity(city, country)}>
{country && <TypeIcon type="country" value={country} />} {country && (
<img
src={`${process.env.basePath}/images/flags/${country?.toLowerCase() || 'xx'}.png`}
alt={country}
/>
)}
</FilterLink> </FilterLink>
); );
}; };
@ -32,6 +32,7 @@ export function CitiesTable(props: MetricsTableProps) {
metric={formatMessage(labels.visitors)} metric={formatMessage(labels.visitors)}
dataFilter={emptyFilter} dataFilter={emptyFilter}
renderLabel={renderLink} renderLabel={renderLink}
searchFormattedValues={true}
/> />
); );
} }

View File

@ -29,6 +29,8 @@ export function CountriesTable({ ...props }: MetricsTableProps) {
type="country" type="country"
metric={formatMessage(labels.visitors)} metric={formatMessage(labels.visitors)}
renderLabel={renderLink} renderLabel={renderLink}
onDataLoad={handleDataLoad}
searchFormattedValues={true}
/> />
); );
} }

View File

@ -23,6 +23,7 @@ export function DevicesTable(props: MetricsTableProps) {
type="device" type="device"
metric={formatMessage(labels.visitors)} metric={formatMessage(labels.visitors)}
renderLabel={renderLink} renderLabel={renderLink}
searchFormattedValues={true}
/> />
); );
} }

View File

@ -1,8 +1,8 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable'; import MetricsTable, { MetricsTableProps } from './MetricsTable';
import { percentFilter } from 'lib/filters'; import { percentFilter } from 'lib/filters';
import { useLanguageNames } from 'components/hooks';
import { useLocale } from 'components/hooks'; import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
import { useFormat } from 'components/hooks';
export function LanguagesTable({ export function LanguagesTable({
onDataLoad, onDataLoad,
@ -10,10 +10,10 @@ export function LanguagesTable({
}: { onDataLoad: (data: any) => void } & MetricsTableProps) { }: { onDataLoad: (data: any) => void } & MetricsTableProps) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { locale } = useLocale(); const { locale } = useLocale();
const { languageNames } = useLanguageNames(locale); const { formatLanguage } = useFormat();
const renderLabel = ({ x }) => { const renderLabel = ({ x }) => {
return languageNames[x?.split('-')[0]] ?? x; return <div className={locale}>{formatLanguage(x)}</div>;
}; };
return ( return (
@ -24,6 +24,7 @@ export function LanguagesTable({
metric={formatMessage(labels.visitors)} metric={formatMessage(labels.visitors)}
onDataLoad={data => onDataLoad?.(percentFilter(data))} onDataLoad={data => onDataLoad?.(percentFilter(data))}
renderLabel={renderLabel} renderLabel={renderLabel}
searchFormattedValues={true}
/> />
); );
} }

View File

@ -26,6 +26,7 @@ export interface MetricsTableProps extends ListTableProps {
onDataLoad?: (data: any) => void; onDataLoad?: (data: any) => void;
onSearch?: (search: string) => void; onSearch?: (search: string) => void;
allowSearch?: boolean; allowSearch?: boolean;
searchFormattedValues?: boolean;
showMore?: boolean; showMore?: boolean;
params?: { [key: string]: any }; params?: { [key: string]: any };
children?: ReactNode; children?: ReactNode;
@ -40,6 +41,7 @@ export function MetricsTable({
onDataLoad, onDataLoad,
delay = null, delay = null,
allowSearch = false, allowSearch = false,
searchFormattedValues = false,
showMore = true, showMore = true,
params, params,
children, children,
@ -55,6 +57,20 @@ export function MetricsTable({
websiteId, websiteId,
{ type, limit, search, ...params }, { type, limit, search, ...params },
{ {
type,
startAt: +startDate,
endAt: +endDate,
url,
referrer,
os,
title,
browser,
device,
country,
region,
city,
limit,
search: (searchFormattedValues) ? undefined : search,
retryDelay: delay || DEFAULT_ANIMATION_DURATION, retryDelay: delay || DEFAULT_ANIMATION_DURATION,
onDataLoad, onDataLoad,
}, },
@ -74,6 +90,14 @@ export function MetricsTable({
} }
} }
if (searchFormattedValues && search) {
items = items.filter(({ x, ...data }) => {
const value = formatValue(x, type, data);
return value?.toLowerCase().includes(search.toLowerCase());
});
}
items = percentFilter(items); items = percentFilter(items);
return items; return items;

View File

@ -25,6 +25,7 @@ export function RegionsTable(props: MetricsTableProps) {
metric={formatMessage(labels.visitors)} metric={formatMessage(labels.visitors)}
dataFilter={emptyFilter} dataFilter={emptyFilter}
renderLabel={renderLink} renderLabel={renderLink}
searchFormattedValues={true}
/> />
); );
} }