Offer search colon operator instead of equals (#4527)
* Offer search colon operator instead of equals * lint
This commit is contained in:
Родитель
35edb50951
Коммит
9e96781b93
|
@ -264,12 +264,12 @@ export class ChromedashDrawer extends LitElement {
|
|||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const shippingThisYear = this.renderNavItem(
|
||||
'/features?q=shipping_year=' + year,
|
||||
'/features?q=shipping_year:' + year,
|
||||
'Shipping ' + year
|
||||
);
|
||||
const nextYear = year + 1;
|
||||
let shippingNextYear = this.renderNavItem(
|
||||
'/features?q=shipping_year=' + nextYear,
|
||||
'/features?q=shipping_year:' + nextYear,
|
||||
'Shipping ' + nextYear
|
||||
);
|
||||
// Only show next year starting on September 1.
|
||||
|
|
|
@ -8,14 +8,14 @@ import {ChromedashTypeahead, Candidate} from './chromedash-typeahead.js';
|
|||
|
||||
function convertQueriableFieldToVocabularyItems(qf): Candidate[] {
|
||||
if (qf.choices === undefined) {
|
||||
return [{group: qf.name, name: qf.name + '=', doc: qf.doc}];
|
||||
return [{group: qf.name, name: qf.name + ':', doc: qf.doc}];
|
||||
}
|
||||
const result: Candidate[] = [];
|
||||
for (const ch in qf.choices) {
|
||||
const label: string = qf.choices[ch][1];
|
||||
result.push({
|
||||
group: qf.name,
|
||||
name: qf.name + '="' + label + '"',
|
||||
name: qf.name + ':"' + label + '"',
|
||||
doc: qf.doc,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -70,15 +70,15 @@ export class ChromedashSearchHelpDialog extends LitElement {
|
|||
)}
|
||||
${this.renderExampleRow(
|
||||
[
|
||||
'browsers.chrome.desktop=123',
|
||||
'browsers.chrome.desktop=current_stable+1',
|
||||
'browsers.chrome.desktop:123',
|
||||
'browsers.chrome.desktop:current_stable+1',
|
||||
],
|
||||
'Features shipping in the specified milestone.'
|
||||
)}
|
||||
${this.renderExampleRow(
|
||||
[
|
||||
'browsers.chrome.desktop=120..122',
|
||||
'browsers.chrome.desktop=current_stable-1..current_stable+1',
|
||||
'browsers.chrome.desktop:120..122',
|
||||
'browsers.chrome.desktop:current_stable-1..current_stable+1',
|
||||
],
|
||||
'Features shipping in a milestone range.'
|
||||
)}
|
||||
|
@ -90,24 +90,24 @@ export class ChromedashSearchHelpDialog extends LitElement {
|
|||
[
|
||||
'created.when>2024-01-01',
|
||||
'created.when<now-8w',
|
||||
'updated.when=2023-01-01..2023-12-31',
|
||||
'updated.when:2023-01-01..2023-12-31',
|
||||
],
|
||||
'Features created or modified before or after a date.'
|
||||
)}
|
||||
${this.renderExampleRow(
|
||||
[
|
||||
'feature_type="Feature deprecation"',
|
||||
'feature_type:"Feature deprecation"',
|
||||
'feature_type!="Feature deprecation"',
|
||||
'-feature_type="Feature deprecation"',
|
||||
'-feature_type:"Feature deprecation"',
|
||||
],
|
||||
'Features of a specific type or excluding a type.'
|
||||
)}
|
||||
${this.renderExampleRow(
|
||||
['category=CSS,DOM'],
|
||||
['category:CSS,DOM'],
|
||||
'Features that have a value in a comma-separated list.'
|
||||
)}
|
||||
${this.renderExampleRow(
|
||||
['category=CSS OR category=DOM'],
|
||||
['category:CSS OR category:DOM'],
|
||||
'Combine two query clauses with a logical-OR.'
|
||||
)}
|
||||
</table>
|
||||
|
@ -139,8 +139,10 @@ export class ChromedashSearchHelpDialog extends LitElement {
|
|||
<ul>
|
||||
<li>FIELD: One of the fields listed below.</li>
|
||||
<li>
|
||||
OPERATOR: Usually an equals sign, but it can be an inequality for
|
||||
numeric, date, or enum fields.
|
||||
OPERATOR: Usually a colon, but it can be an inequality for numeric,
|
||||
date, or enum fields. The colon operator does case-insensitive
|
||||
matching of words within a text field, while an equals-sign does
|
||||
exact matching of an entire string value.
|
||||
</li>
|
||||
<li>
|
||||
VALUE(S): A single word, number, date, or enum value listed below.
|
||||
|
@ -184,7 +186,7 @@ export class ChromedashSearchHelpDialog extends LitElement {
|
|||
renderFieldRow(queryField: QueryField) {
|
||||
if (queryField.choices) {
|
||||
const choiceItems = Object.values(queryField.choices).map(
|
||||
c => html` <div>${queryField.name}="${c[1]}"</div> `
|
||||
c => html` <div>${queryField.name}:"${c[1]}"</div> `
|
||||
);
|
||||
return html`
|
||||
<tr>
|
||||
|
@ -198,7 +200,7 @@ export class ChromedashSearchHelpDialog extends LitElement {
|
|||
return html`
|
||||
<tr>
|
||||
<td>
|
||||
<code>${queryField.name}=<i>${queryField.kind}</i></code>
|
||||
<code>${queryField.name}:<i>${queryField.kind}</i></code>
|
||||
</td>
|
||||
<td>${queryField.doc}</td>
|
||||
</tr>
|
||||
|
|
|
@ -158,7 +158,7 @@ export class ChromedashTypeahead extends LitElement {
|
|||
if (!groupsSeenTwice.has(c.group)) {
|
||||
result.push(c);
|
||||
} else if (!groupsSeenTwiceProcessed.has(c.group)) {
|
||||
result.push({group: c.group, name: c.group + '=', doc: c.doc});
|
||||
result.push({group: c.group, name: c.group + ':', doc: c.doc});
|
||||
groupsSeenTwiceProcessed.add(c.group);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,17 +148,17 @@ describe('chromedash-typeahead', () => {
|
|||
it('groups candidates that have the same group value', async () => {
|
||||
const component = new ChromedashTypeahead();
|
||||
const candidates = [
|
||||
{group: 'a', name: 'a=1', doc: 'doc'},
|
||||
{group: 'b', name: 'b=1', doc: 'doc'},
|
||||
{group: 'c', name: 'c=1', doc: 'doc'},
|
||||
{group: 'b', name: 'b=2', doc: 'doc'},
|
||||
{group: 'b', name: 'b=3', doc: 'doc'},
|
||||
{group: 'a', name: 'a:1', doc: 'doc'},
|
||||
{group: 'b', name: 'b:1', doc: 'doc'},
|
||||
{group: 'c', name: 'c:1', doc: 'doc'},
|
||||
{group: 'b', name: 'b:2', doc: 'doc'},
|
||||
{group: 'b', name: 'b:3', doc: 'doc'},
|
||||
];
|
||||
const actual = component.groupCandidates(candidates);
|
||||
assert.deepEqual(actual, [
|
||||
{group: 'a', name: 'a=1', doc: 'doc'},
|
||||
{group: 'b', name: 'b=', doc: 'doc'},
|
||||
{group: 'c', name: 'c=1', doc: 'doc'},
|
||||
{group: 'a', name: 'a:1', doc: 'doc'},
|
||||
{group: 'b', name: 'b:', doc: 'doc'},
|
||||
{group: 'c', name: 'c:1', doc: 'doc'},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -223,10 +223,14 @@ def process_query_term(
|
|||
is_negation: bool, field_name: str, op_str: str, vals_str: str, context: QueryContext
|
||||
) -> Future:
|
||||
"""Parse and run a user-supplied query, if we can handle it."""
|
||||
val_list = parse_query_value_list(vals_str, context)
|
||||
# Use exact match rather than word match on non-string fields.
|
||||
if op_str == ':':
|
||||
if (core_enums.is_enum_field(field_name.lower()) or
|
||||
val_list and not isinstance(val_list[0], str)):
|
||||
op_str = '='
|
||||
if is_negation:
|
||||
op_str = search_queries.negate_operator(op_str)
|
||||
|
||||
val_list = parse_query_value_list(vals_str, context)
|
||||
logging.info('trying %r %r %r', field_name, op_str, val_list)
|
||||
|
||||
future = search_queries.single_field_query_async(
|
||||
|
|
Загрузка…
Ссылка в новой задаче