mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
Fix crashing search bars (#2765)
This commit is contained in:
parent
25858cae82
commit
6c621bf65b
@ -8,6 +8,7 @@ import useApplications from 'hooks/api/getters/useApplications/useApplications';
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { Search } from 'component/common/Search/Search';
|
import { Search } from 'component/common/Search/Search';
|
||||||
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
|
|
||||||
type PageQueryType = Partial<Record<'search', string>>;
|
type PageQueryType = Partial<Record<'search', string>>;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ export const ApplicationList = () => {
|
|||||||
}, [searchValue, setSearchParams]);
|
}, [searchValue, setSearchParams]);
|
||||||
|
|
||||||
const filteredApplications = useMemo(() => {
|
const filteredApplications = useMemo(() => {
|
||||||
const regExp = new RegExp(searchValue, 'i');
|
const regExp = safeRegExp(searchValue, 'i');
|
||||||
return searchValue
|
return searchValue
|
||||||
? applications?.filter(a => regExp.test(a.appName))
|
? applications?.filter(a => regExp.test(a.appName))
|
||||||
: applications;
|
: applications;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { useStyles } from './Highlighter.styles';
|
import { useStyles } from './Highlighter.styles';
|
||||||
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
|
|
||||||
interface IHighlighterProps {
|
interface IHighlighterProps {
|
||||||
search?: string;
|
search?: string;
|
||||||
@ -7,8 +8,6 @@ interface IHighlighterProps {
|
|||||||
caseSensitive?: boolean;
|
caseSensitive?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
|
|
||||||
export const Highlighter: VFC<IHighlighterProps> = ({
|
export const Highlighter: VFC<IHighlighterProps> = ({
|
||||||
search,
|
search,
|
||||||
children,
|
children,
|
||||||
@ -23,7 +22,7 @@ export const Highlighter: VFC<IHighlighterProps> = ({
|
|||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const regex = new RegExp(escapeRegex(search), caseSensitive ? 'g' : 'gi');
|
const regex = safeRegExp(search, caseSensitive ? 'g' : 'gi');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
|
@ -23,6 +23,7 @@ import { Search } from 'component/common/Search/Search';
|
|||||||
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
|
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
|
||||||
import { ITooltipResolverProps } from 'component/common/TooltipResolver/TooltipResolver';
|
import { ITooltipResolverProps } from 'component/common/TooltipResolver/TooltipResolver';
|
||||||
import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-feature-badge.svg';
|
import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-feature-badge.svg';
|
||||||
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
|
|
||||||
type PageQueryType = Partial<Record<'search', string>>;
|
type PageQueryType = Partial<Record<'search', string>>;
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ export const ProjectListNew = () => {
|
|||||||
}, [searchValue, setSearchParams]);
|
}, [searchValue, setSearchParams]);
|
||||||
|
|
||||||
const filteredProjects = useMemo(() => {
|
const filteredProjects = useMemo(() => {
|
||||||
const regExp = new RegExp(searchValue, 'i');
|
const regExp = safeRegExp(searchValue, 'i');
|
||||||
return (
|
return (
|
||||||
searchValue
|
searchValue
|
||||||
? projects.filter(project => regExp.test(project.name))
|
? projects.filter(project => regExp.test(project.name))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { createGlobalStateHook } from 'hooks/useGlobalState';
|
import { createGlobalStateHook } from 'hooks/useGlobalState';
|
||||||
import { FeatureSchema } from 'openapi';
|
import { FeatureSchema } from 'openapi';
|
||||||
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
|
|
||||||
export interface IFeaturesFilter {
|
export interface IFeaturesFilter {
|
||||||
query?: string;
|
query?: string;
|
||||||
@ -66,7 +67,7 @@ const filterFeaturesByQuery = (
|
|||||||
// Try to parse the search query as a RegExp.
|
// Try to parse the search query as a RegExp.
|
||||||
// Return all features if it can't be parsed.
|
// Return all features if it can't be parsed.
|
||||||
try {
|
try {
|
||||||
const regExp = new RegExp(filter.query, 'i');
|
const regExp = safeRegExp(filter.query, 'i');
|
||||||
return features.filter(f => filterFeatureByRegExp(f, filter, regExp));
|
return features.filter(f => filterFeatureByRegExp(f, filter, regExp));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof SyntaxError) {
|
if (err instanceof SyntaxError) {
|
||||||
|
@ -107,8 +107,6 @@ test.skip('will not blow up if userId is an array', () => {
|
|||||||
properties: ['some'],
|
properties: ['some'],
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log(context);
|
|
||||||
|
|
||||||
expect(context.userId).toBe('123');
|
expect(context.userId).toBe('123');
|
||||||
expect(context).not.toHaveProperty('tenantId');
|
expect(context).not.toHaveProperty('tenantId');
|
||||||
expect(context).not.toHaveProperty('region');
|
expect(context).not.toHaveProperty('region');
|
||||||
|
3
src/lib/util/escape-regex.ts
Normal file
3
src/lib/util/escape-regex.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function safeRegExp(pattern: string, flags?: string): RegExp {
|
||||||
|
return new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user