escape quotes for label search on Web

This commit is contained in:
Hongbo Wu
2024-04-03 17:07:36 +08:00
parent 95556f6597
commit e9a587bfdb
4 changed files with 13 additions and 13 deletions

View File

@ -510,7 +510,7 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
const checkboxRef = useRef<HTMLInputElement | null>(null) const checkboxRef = useRef<HTMLInputElement | null>(null)
const state = useMemo(() => { const state = useMemo(() => {
const term = props.searchTerm ?? '' const term = props.searchTerm ?? ''
if (term.indexOf(`label:\"${props.label.name}\"`) >= 0) { if (term.indexOf(`label:\"${escapeQuotes(props.label.name)}\"`) >= 0) {
return 'on' return 'on'
} }
return 'off' return 'off'
@ -560,7 +560,7 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
props.applySearchQuery(query.trim()) props.applySearchQuery(query.trim())
} else { } else {
props.applySearchQuery( props.applySearchQuery(
`${query.trim()} label:\"${props.label.name}\"` `${query.trim()} label:\"${escapeQuotes(props.label.name)}\"`
) )
} }
}} }}
@ -579,16 +579,14 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
type="checkbox" type="checkbox"
checked={state === 'on'} checked={state === 'on'}
onChange={(e) => { onChange={(e) => {
const escapedName = escapeQuotes(props.label.name)
if (e.target.checked) { if (e.target.checked) {
props.applySearchQuery( props.applySearchQuery(
`${props.searchTerm ?? ''} label:\"${props.label.name}\"` `${props.searchTerm ?? ''} label:\"${escapedName}\"`
) )
} else { } else {
const query = const query =
props.searchTerm?.replace( props.searchTerm?.replace(`label:\"${escapedName}\"`, '') ?? ''
`label:\"${props.label.name}\"`,
''
) ?? ''
props.applySearchQuery(query) props.applySearchQuery(query)
} }
}} }}

View File

@ -935,7 +935,7 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
const checkboxRef = useRef<HTMLInputElement | null>(null) const checkboxRef = useRef<HTMLInputElement | null>(null)
const state = useMemo(() => { const state = useMemo(() => {
const term = props.searchTerm ?? '' const term = props.searchTerm ?? ''
if (term.indexOf(`label:\"${props.label.name}\"`) >= 0) { if (term.indexOf(`label:\"${escapeQuotes(props.label.name)}\"`) >= 0) {
return 'on' return 'on'
} }
return 'off' return 'off'
@ -985,7 +985,7 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
props.applySearchQuery(query.trim()) props.applySearchQuery(query.trim())
} else { } else {
props.applySearchQuery( props.applySearchQuery(
`${query.trim()} label:\"${props.label.name}\"` `${query.trim()} label:\"${escapeQuotes(props.label.name)}\"`
) )
} }
}} }}
@ -1004,14 +1004,15 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
type="checkbox" type="checkbox"
checked={state === 'on'} checked={state === 'on'}
onChange={(e) => { onChange={(e) => {
const escapedLabelName = escapeQuotes(props.label.name)
if (e.target.checked) { if (e.target.checked) {
props.applySearchQuery( props.applySearchQuery(
`${props.searchTerm ?? ''} label:\"${props.label.name}\"` `${props.searchTerm ?? ''} label:\"${escapedLabelName}\"`
) )
} else { } else {
const query = const query =
props.searchTerm?.replace( props.searchTerm?.replace(
`label:\"${props.label.name}\"`, `label:\"${escapedLabelName}\"`,
'' ''
) ?? '' ) ?? ''
props.applySearchQuery(query) props.applySearchQuery(query)

View File

@ -21,6 +21,7 @@ import { Label } from '../../lib/networking/fragments/labelFragment'
import { CheckSquare, Circle, Square } from 'phosphor-react' import { CheckSquare, Circle, Square } from 'phosphor-react'
import { SavedSearch } from '../../lib/networking/fragments/savedSearchFragment' import { SavedSearch } from '../../lib/networking/fragments/savedSearchFragment'
import { usePersistedState } from '../../lib/hooks/usePersistedState' import { usePersistedState } from '../../lib/hooks/usePersistedState'
import { escapeQuotes } from '../../utils/helper'
export type PinnedSearch = { export type PinnedSearch = {
type: 'saved-search' | 'label' type: 'saved-search' | 'label'
@ -282,7 +283,7 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
type: 'label', type: 'label',
itemId: props.label.id, itemId: props.label.id,
name: props.label.name, name: props.label.name,
search: `label:\"${props.label.name}\"`, search: `label:\"${escapeQuotes(props.label.name)}\"`,
}} }}
listAction={props.listAction} listAction={props.listAction}
> >

View File

@ -357,7 +357,7 @@ const AvailableItems = (props: ListProps): JSX.Element => {
type: 'label', type: 'label',
label: label, label: label,
name: label.name, name: label.name,
filter: `label:\"${label.name}\"`, filter: `label:\"${escapeQuotes(label.name)}\"`,
} }
props.dispatchList({ props.dispatchList({
item, item,