Skip to content

Commit

Permalink
Bugfix/add ignore case option for string filters (#1032)
Browse files Browse the repository at this point in the history
* Add ignoreCase option for string filter clause

* pinboard and string filter menu search boxes should ignore case for better UX

* change fixtures so they include default ignorCase value in results
  • Loading branch information
adrianmroz-allegro authored Feb 13, 2023
1 parent 5d1438b commit d559bb2
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 24 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/mkurl.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ context("mkurl", () => {

cy.request("POST", "http://localhost:9090/mkurl", body).then((hash: Cypress.Response<MkurlResponse>) => {
expect(hash.status).to.eq(200);
expect(hash.body.hash).to.eq("#wiki/4/N4IgbglgzgrghgGwgLzgFwgewHYgFwhpwBGCApiADTjTxKoY4DKZaG2A5lPqAMaYIEcAA5QyAJUwB3bngBmiMQF9qGALZlkOCgQCiaXgHoAqgBUAwlRByICNGQBOsgNqg0AT2E7CEDVYdkcvg+fqq+EnCcZC6gUEQOaMEATAAMAIwArAC0KQCcWWlJpikpeCVlKQB0JSkAWlZk2AAmyenZeQUAzMWl5SXVJfVKALoqbp7ecQ4QnP6BwbwAFpHYZAhWcLyMuAQzVmCIMNH4ziCNIMPU2JiJ8opkY4QTwcSYAmSRc0G7UJKvidQDggji40A4jpcQNdbmCjo8PF5glMZhwvsFhHAOBRqJttgscEQZtxAYdjnhTgApRxkNTuC5XG74BQIZSUcaIgjI2bUALfEAwMQOczLJwbLZYHYgNToJb7UkuEAAPQAggASelQxl3FkPNlPDlQmBqYiONEEfhqDTYNAAGUaHDQiys0KZ9x5kSxMRAcTgCXwnWojRaeGwMEE1FeMGashAzgAlCARiNqFBhEg0F6EZMwSirE1wtgoBKFstsKt1inMH68KBecEmmsiFYs0jHBBjtR8wFxTh69FeEHc9QvNNMMGQInqEg1BBbhkUvDngRXu9Pp2C0Xez8/ozK9Xa/MCA27HBm0vvW2OyAu2Qe5KG1AB80hyAR1hx5OQNPZ/gMouDaGxqmuuVqbpKFpWra9qOlYHAOJEYa+rOdJ4GkKR7rcB58seTaqOegrtsS14QN2eJHv2g7cq+bZjsEn7fnO/7eOo2LEaBxYECxsHwaGQjTB4wQAAqmGkAASVhQFWmEgHW5EnmeBoEVeN53n2j6Uaiw40R+Khfr4P4hmGCDJhe0xkq4MmBNS2ADn28nUHIVbStJLbkQoYYAuApJ0bprlSh8sABJOWHWbZ5qYFGnmOQ4zk8Pq3gNu5dhysC3ifn5GhwIFFCPLyoXeHATQNi0DlOegcV+YlcAeSlRw+XhBqZdliaQsIMyrE0AAiG4SgqSwrGszpwBoqabKx0A7okrXtWQTRMFJdlNkoQA=");
expect(hash.body.hash).to.eq("#wiki/4/N4IgbglgzgrghgGwgLzgFwgewHYgFwhpwBGCApiADTjTxKoY4DKZaG2A5lPqAMaYIEcAA5QyAJUwB3bngBmiMQF9qGALZlkOCgQCiaXgHoAqgBUAwlRByICNGQBOsgNqg0AT2E7CEDVYdkcvg+fqq+EnCcZC6gUEQOaMEATAAMAIwArAC0KQCcWWlJpikpeCVlKQB0JSkAWlZk2AAmyenZeQUAzMWl5SXVJfVKALoqbp7ecQ4QnP6BwbwAFpHYZAhWcLyMuAQzVmCIMNH4ziCNIMPU2JiJ8opk1BAc1wHmcGL4CgjKlONewcRMAIyJE5kFdlBJIDEtQDggji40A4jpcQNdbkijmNCBNglMZhwwcFhHAOBRqJttgscEQZtxYYdjnhTgApRxkNTuC5XG6fe6PZ6YV7vHRfH5/SZIglEggwMQOczLJwbLZYHYgNToJb7RkuEAAPQAggASblo3l3b4PEBPF5kN4fS3inH/AjYGBqYiOGUgfhqDTYNAAGUaHDQiys6L5VuoDkiZJiIDicAS+E61EaLTw7sE1EBMGashAzgAlCARiNqFBhEg0ImPK6k1LZtQmuFsFA1QtlthVusq0LbqAAuCQE01kQrA3Jo4IMdWxAAqqcMFx1BeJnpdQvNNMFmQOXqEg1BBbhkUtjpwCgeRQQuA52VxCobyB6m8MP5gRx3Y4FPcQQ8pzvSY6LmQy7qmuG7NFuIA7lg+6HiAx6nvgGSXgBaIel6DhWG2D5dgQfoBsGobhlYHBxjmKanlyeBpCkb5DiAI6rhOf6qJhQHzqBS5Ut+0TQW2LZwbOe7BEhKFnhhjbqOSoEEU+ITyZRkQwEI0weMEAAKphpAAElYUCDjwLFfmO7H/o23EgW2fGERZ66biJ8HiQQkm+Kh2bqQglZJrOTKuGZcjstgG5sb+VhyEKmrMVeAkKOpMLgIyEkqC63gaO8MABIen4hQEYXePwBbJdFDixaZ8UWYldg6vC3hIdVWWwLl2IjqF4UEHATTji01DlZVH4ZWxtXJXCRxpZxjYtTlFB+cIMyrE0AAi7aPh2Jy+j2faRnAGjVps8nQC+iSootvZkE0TAmQJkVKEAA");
});
});
});
3 changes: 2 additions & 1 deletion src/client/components/pinboard-tile/pinboard-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ export class PinboardTile extends React.Component<PinboardTileProps, PinboardTil
return new StringFilterClause({
action: StringFilterAction.CONTAINS,
reference,
values: Set.of(searchText)
values: Set.of(searchText),
ignoreCase: true
});
default:
throw new Error(`Expected String or Boolean dimension kind, got ${dimension.kind}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ export class SelectableStringFilterMenu extends React.Component<SelectableString
return new StringFilterClause({
action: StringFilterAction.CONTAINS,
reference,
values: Set.of(searchText)
values: Set.of(searchText),
ignoreCase: true
});
}

Expand Down
18 changes: 14 additions & 4 deletions src/common/models/filter-clause/filter-clause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@

import { Duration, minute, Timezone } from "chronoshift";
import { List, Record, Set as ImmutableSet } from "immutable";
import { Datum, Expression, NumberRange as PlywoodNumberRange, r, Set as PlywoodSet, TimeRange } from "plywood";
import {
ContainsExpression,
Datum,
Expression,
NumberRange as PlywoodNumberRange,
r,
Set as PlywoodSet,
TimeRange
} from "plywood";
import { constructFilter } from "../../../client/components/filter-menu/time-filter-menu/presets";
import { DateRange } from "../date-range/date-range";
import { Dimension } from "../dimension/dimension";
Expand Down Expand Up @@ -91,14 +99,16 @@ interface StringFilterDefinition extends FilterDefinition {
not: boolean;
action: StringFilterAction;
values: ImmutableSet<string>;
ignoreCase: boolean;
}

const defaultStringFilter: StringFilterDefinition = {
reference: null,
type: FilterTypes.STRING,
not: false,
action: StringFilterAction.CONTAINS,
values: ImmutableSet([])
values: ImmutableSet([]),
ignoreCase: false
};

export class StringFilterClause extends Record<StringFilterDefinition>(defaultStringFilter) {
Expand Down Expand Up @@ -186,11 +196,11 @@ export function toExpression(clause: FilterClause, { expression }: Dimension): E
return not ? numExp.not() : numExp;
}
case FilterTypes.STRING: {
const { not, action, values } = clause as StringFilterClause;
const { not, action, values, ignoreCase } = clause as StringFilterClause;
let stringExp: Expression = null;
switch (action) {
case StringFilterAction.CONTAINS:
stringExp = expression.contains(r(values.first()));
stringExp = expression.contains(r(values.first()), ignoreCase ? ContainsExpression.IGNORE_CASE : ContainsExpression.NORMAL);
break;
case StringFilterAction.IN:
stringExp = expression.overlap(r(values.toArray()));
Expand Down
25 changes: 13 additions & 12 deletions src/common/utils/url-hash-converter/url-hash-converter.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ export class UrlHashConverterFixtures {
}

static tableHashVersion4() {
return "4/N4IgbglgzgrghgGwgLzgFwgewHYgFwhpwBGCApiADTjTxKoY4DKZaG2A5lPqAMaYIEcAA5QyAJUwB3bngBmiMQF9qGALZlkOCgQCiaXgHoAqgBUAwlRByICNGQBOs" +
"gNqg0AT2E7CEDVYdkcvg+fqq+EnCcZC6gUEQOaMEATAAMAIwArAC0KQCcWWlJpikpeCVlKQB0JSkAWlZk2AAmyenZeQUAzMWl5SXVJfVKALoqbp7ecQ4QnP6BwbwAFpHYZAh" +
"WcLyMuAQzVmCIMNH4ziCNIMPU2JiJ8opkY4QTwcSYAmSRc0G7UJKvidQDggji40A4jpcQNdbmCjo8PF5glMZhwvsFhHAOBRqJttgscEQZtxAYdjnhTgApRxkNTuC5XG74BQI" +
"ZSUcaIgjI2bUALfEAwMQOczLJwbLZYHYgNToJb7UkuEAAPQAggASelQxl3FkPNlPDlQmBqYiONEEfhqDTYNAAGUaHDQiys0KZ9x5kSxMRAcTgCXwnWojRaeGwMEE1FeMGash" +
"AzgAlCARiNqFBhEg0F6EZMwSirE1wtgoBKFstsKt1inMH68KBecEmmsiFYs0jHBBjtR8wFxTh69FeEHc9QvNNMMGQInqEg1BBbhkUvDngRXu9Pp2C0Xez8/ozK9Xa/MCA27H" +
"Bm0vvW2OyAu2Qe5KG1AB80hyAR1hx5OQNPZ/gMouDaGxqmuuVqbpKFpWra9qOlYHAOJEYa+rOdJ4GkKR7rcB58seTaqOegrtsS14QN2eJHv2g7cq+bZjsEn7fnO/7eOo2LEa" +
"BxYECxsHwaGQjTB4wQAAqmGkAASVhQFWmEgHW5EnmeBoEVeN53n2j6Uaiw40R+Khfr4P4hmGCDJhe0xkq4MmBNS2ADn28nUHIVbStJLbkQoYYAuApJ0bprlSh8sABJOWHWbZ" +
"5qYFGnmOQ4zk8Pq3gNu5dhysC3ifn5GhwIFFCPLyoXeHATQNi0DlOegcV+YlcAeSlRw+XhBqZdliaQsIMyrE0AAiG4SgqSwrGszpwBoqabKx0A7okrXtWQTRMFJdlNkoQA=";
return "4/N4IgbglgzgrghgGwgLzgFwgewHYgFwhpwBGCApiADTjTxKoY4DKZaG2A5lPqAMaYIEcAA5QyAJUwB3bngBmiMQF9qGALZlkOCgQCiaXgHoAqgBUAwlRByICNGQ" +
"BOsgNqg0AT2E7CEDVYdkcvg+fqq+EnCcZC6gUEQOaMEATAAMAIwArAC0KQCcWWlJpikpeCVlKQB0JSkAWlZk2AAmyenZeQUAzMWl5SXVJfVKALoqbp7ecQ4QnP6BwbwAF" +
"pHYZAhWcLyMuAQzVmCIMNH4ziCNIMPU2JiJ8opk1BAc1wHmcGL4CgjKlONewcRMAIyJE5kFdlBJIDEtQDggji40A4jpcQNdbkijmNCBNglMZhwwcFhHAOBRqJttgscEQZ" +
"txYYdjnhTgApRxkNTuC5XG6fe6PZ6YV7vHRfH5/SZIglEggwMQOczLJwbLZYHYgNToJb7RkuEAAPQAggASblo3l3b4PEBPF5kN4fS3inH/AjYGBqYiOGUgfhqDTYNAAGU" +
"aHDQiys6L5VuoDkiZJiIDicAS+E61EaLTw7sE1EBMGashAzgAlCARiNqFBhEg0ImPK6k1LZtQmuFsFA1QtlthVusq0LbqAAuCQE01kQrA3Jo4IMdWxAAqqcMFx1BeJnpd" +
"QvNNMFmQOXqEg1BBbhkUtjpwCgeRQQuA52VxCobyB6m8MP5gRx3Y4FPcQQ8pzvSY6LmQy7qmuG7NFuIA7lg+6HiAx6nvgGSXgBaIel6DhWG2D5dgQfoBsGobhlYHBxjmK" +
"anlyeBpCkb5DiAI6rhOf6qJhQHzqBS5Ut+0TQW2LZwbOe7BEhKFnhhjbqOSoEEU+ITyZRkQwEI0weMEAAKphpAAElYUCDjwLFfmO7H/o23EgW2fGERZ66biJ8HiQQkm+K" +
"h2bqQglZJrOTKuGZcjstgG5sb+VhyEKmrMVeAkKOpMLgIyEkqC63gaO8MABIen4hQEYXePwBbJdFDixaZ8UWYldg6vC3hIdVWWwLl2IjqF4UEHATTji01DlZVH4ZWxtXJ" +
"XCRxpZxjYtTlFB+cIMyrE0AAi7aPh2Jy+j2faRnAGjVps8nQC+iSootvZkE0TAmQJkVKEAA";
}

static lineChartVersion2() {
Expand All @@ -72,10 +73,10 @@ export class UrlHashConverterFixtures {
static lineChartVersion4() {
return "4/N4IgbglgzgrghgGwgLzgFwgewHYgFwhLYCmAtAMYAWcATmiADTjTxKoY4DKxaG2A5lHyh+NTDAAO3GhGJC8AM0RRiAXyYYAtsWQ5i+EAFE05APQBVACoBhRiAU" +
"QEaYjXkBtUGgCeE/QS36TDTECgYBdgEACi5YACbuoLEwNOhYuASRAIwAInZQzhL4pJkaPn6E6HL0qgC66p5lBvkyAnbBoQRUcNgkCHZw5BzpIBC4TGCIMHL4biDEYyDYm" +
"HlgdrGB9jR25EI1TEv0ispqeyBQEkhoCSDevk1oLfxrENrYUGkGXT3EfUxQmHRhCB2gZ1k44BFGgQVDJpkxYhBgoMPgR1lByPMEa0mL4ZJhYgYQOpCC8IIdMgAGeo3KE3" +
"F4bBGvd44ML0uyibowBC0MleAyRSyZAASeQBh1AIP8bNKd1R9LeH3hiOIyJZBDg6MxoyexKQmjJ+GwXIQtT+MWmeA8wJCLnmGNBPzQEKYCgBmnQQNu5XWSi59HGk3KRJl" +
"5W0GuS+mp7Vt2HtnXE2H99jdHrwDVlIB9cD9dgmCCmhOJXoMYdgwWDEptwVj5TgsXWBJdKfFNIzWZzAfzQaLtNLEaJpwkoxIsWy8uZbxmIC+vTs2Dg2nOAw20AASpgAEa" +
"YeiD4fEWKcMUO8FEoA";
"HlgdrGB9jR25EI1TEv0isrETBD8S8HWcCr4SggqtUxQEkhoCSDevk1oLfxrENpsFA0gYuj1iH0npg6MIQO0DOsnHAIo0CCoZNMmLEIMFBiCCOsoOR5tjWkxfDJMLEDCB1" +
"IQARBDpkAAz1D6oj4AjbYwHAnBhLl2UTdGAIWiMrwGSKWTIACTy0MOoHh/kFpS+BK5QJBWJxxDx/II12J2FJfzpSE0jPw2FFCEeIHRsne7Rc82JCIhaGRTAU0M06Fhn3K" +
"6yUovo40m5Vp6vK2muyX0bNdwWwHs64mwEfs/sDeAaGpAobg4bsEwQUxpdODBnjsGCMeVITdafKcFi62pvtzSvZheLpcjFej1Y5dcTtL2IAkoxIsWyWr5QJmIDBvTs2Dg" +
"2meAw20AASpgAEaYehTmfg2KcRWepG0oA=";
}

static noSlashInEncodedDefinition2() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ export function booleanFilterDefinition(ref: string, values: Booleanish[], not =
};
}

export function stringFilterDefinition(ref: string, action: StringFilterAction, values: string[], not = false): StringFilterClauseDefinition {
export function stringFilterDefinition(ref: string, action: StringFilterAction, values: string[], not = false, ignoreCase = false): StringFilterClauseDefinition {
return {
ref,
type: FilterType.string,
action,
not,
values
values,
ignoreCase
};
}

Expand Down
9 changes: 6 additions & 3 deletions src/common/view-definitions/version-4/filter-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface StringFilterClauseDefinition extends BaseFilterClauseDefinition
type: FilterType.string;
action: StringFilterAction;
not: boolean;
ignoreCase: boolean;
values: string[];
}

Expand Down Expand Up @@ -103,7 +104,7 @@ const booleanFilterClauseConverter: FilterDefinitionConversion<BooleanFilterClau
};

const stringFilterClauseConverter: FilterDefinitionConversion<StringFilterClauseDefinition, StringFilterClause> = {
toFilterClause({ action, not, values }: StringFilterClauseDefinition, dimension: Dimension): StringFilterClause {
toFilterClause({ action, not, values, ignoreCase }: StringFilterClauseDefinition, dimension: Dimension): StringFilterClause {
if (action === null) {
throw Error(`String filter action cannot be empty. Dimension: ${dimension}`);
}
Expand All @@ -119,17 +120,19 @@ const stringFilterClauseConverter: FilterDefinitionConversion<StringFilterClause
reference: name,
action,
not,
ignoreCase,
values: Set(values)
});
},

fromFilterClause({ action, reference, not, values }: StringFilterClause): StringFilterClauseDefinition {
fromFilterClause({ action, reference, not, values, ignoreCase }: StringFilterClause): StringFilterClauseDefinition {
return {
type: FilterType.string,
ref: reference,
action,
values: values.toArray(),
not
not,
ignoreCase
};
}
};
Expand Down

0 comments on commit d559bb2

Please sign in to comment.