forked from metabase/metabase
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add BooleanPicker component (metabase#18950)
* add BooleanPicker component * add BooleanPicker unit test * fix typo * fix bool filter cy tests * fix button styling * remove 'admin' colorScheme and tweak design a lil
- Loading branch information
1 parent
4afdb6b
commit 2d5766a
Showing
11 changed files
with
248 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
...end/src/metabase/query_builder/components/filters/pickers/BooleanPicker/BooleanPicker.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import React from "react"; | ||
import { PropTypes } from "prop-types"; | ||
import _ from "underscore"; | ||
import { t } from "ttag"; | ||
|
||
import { useToggle } from "metabase/hooks/use-toggle"; | ||
import Filter from "metabase-lib/lib/queries/structured/Filter"; | ||
|
||
import { Container, Toggle, FilterRadio } from "./BooleanPicker.styled"; | ||
|
||
BooleanPicker.propTypes = { | ||
className: PropTypes.string, | ||
filter: PropTypes.instanceOf(Filter), | ||
onFilterChange: PropTypes.func.isRequired, | ||
}; | ||
|
||
const OPTIONS = [ | ||
{ name: t`true`, value: true }, | ||
{ name: t`false`, value: false }, | ||
]; | ||
const EXPANDED_OPTIONS = [ | ||
{ name: t`true`, value: true }, | ||
{ name: t`false`, value: false }, | ||
{ name: t`empty`, value: "is-null" }, | ||
{ name: t`not empty`, value: "not-null" }, | ||
]; | ||
|
||
function BooleanPicker({ className, filter, onFilterChange }) { | ||
const value = getValue(filter); | ||
const [isExpanded, { toggle }] = useToggle(!_.isBoolean(value)); | ||
|
||
const updateFilter = value => { | ||
if (_.isBoolean(value)) { | ||
onFilterChange(filter.setOperator("=").setArguments([value])); | ||
} else { | ||
onFilterChange(filter.setOperator(value)); | ||
} | ||
}; | ||
|
||
return ( | ||
<Container className={className}> | ||
<FilterRadio | ||
vertical | ||
colorScheme="accent7" | ||
options={isExpanded ? EXPANDED_OPTIONS : OPTIONS} | ||
value={value} | ||
onChange={updateFilter} | ||
/> | ||
{!isExpanded && <Toggle onClick={toggle} />} | ||
</Container> | ||
); | ||
} | ||
|
||
function getValue(filter) { | ||
const operatorName = filter.operatorName(); | ||
if (operatorName === "=") { | ||
const [value] = filter.arguments(); | ||
return value; | ||
} else { | ||
return operatorName; | ||
} | ||
} | ||
|
||
export default BooleanPicker; |
45 changes: 45 additions & 0 deletions
45
.../metabase/query_builder/components/filters/pickers/BooleanPicker/BooleanPicker.styled.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import styled from "styled-components"; | ||
import { t } from "ttag"; | ||
|
||
import { color } from "metabase/lib/colors"; | ||
import { space } from "metabase/styled-components/theme"; | ||
import Button from "metabase/components/Button"; | ||
import Radio from "metabase/components/Radio"; | ||
|
||
export const FilterRadio = styled(Radio).attrs({ | ||
colorScheme: "accent7", | ||
})` | ||
font-weight: 700; | ||
`; | ||
|
||
export const Container = styled.div` | ||
margin: 15px 20px 70px 20px; | ||
`; | ||
|
||
const ToggleButton = styled(Button).attrs({ | ||
iconRight: "chevrondown", | ||
iconSize: 12, | ||
})` | ||
margin-left: ${space(0)}; | ||
color: ${color("text-medium")}; | ||
border: none; | ||
background-color: transparent; | ||
&:hover { | ||
background-color: transparent; | ||
} | ||
.Icon { | ||
margin-top: 2px; | ||
} | ||
`; | ||
|
||
Toggle.propTypes = { | ||
onClick: PropTypes.func.isRequired, | ||
}; | ||
|
||
export function Toggle({ onClick }) { | ||
return <ToggleButton onClick={onClick}>{t`More options`}</ToggleButton>; | ||
} |
101 changes: 101 additions & 0 deletions
101
...etabase/query_builder/components/filters/pickers/BooleanPicker/BooleanPicker.unit.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import React from "react"; | ||
import { render, screen } from "@testing-library/react"; | ||
|
||
import { metadata } from "__support__/sample_dataset_fixture"; | ||
|
||
import Question from "metabase-lib/lib/Question"; | ||
import Field from "metabase-lib/lib/metadata/Field"; | ||
import Filter from "metabase-lib/lib/queries/structured/Filter"; | ||
|
||
import BooleanPicker from "./BooleanPicker"; | ||
|
||
const booleanField = new Field({ | ||
database_type: "bool", | ||
semantic_type: "type/Category", | ||
table_id: 8, | ||
name: "bool", | ||
has_field_values: "list", | ||
dimensions: {}, | ||
dimension_options: [], | ||
effective_type: "type/Boolean", | ||
id: 134, | ||
base_type: "type/Boolean", | ||
metadata, | ||
}); | ||
|
||
const card = { | ||
dataset_query: { | ||
database: 5, | ||
query: { | ||
"source-table": 8, | ||
filter: ["=", ["field", 134, null], true], | ||
}, | ||
type: "query", | ||
}, | ||
display: "table", | ||
visualization_settings: {}, | ||
}; | ||
|
||
metadata.fields[booleanField.id] = booleanField; | ||
|
||
const question = new Question(card, metadata); | ||
|
||
const fieldRef = ["field", 134, null]; | ||
const filters = { | ||
true: new Filter(["=", fieldRef, true], null, question.query()), | ||
false: new Filter(["=", fieldRef, false], null, question.query()), | ||
empty: new Filter(["is-null", fieldRef], null, question.query()), | ||
"not empty": new Filter(["not-null", fieldRef], null, question.query()), | ||
}; | ||
|
||
const mockOnFilterChange = jest.fn(); | ||
function setup(filter) { | ||
mockOnFilterChange.mockReset(); | ||
return render( | ||
<BooleanPicker filter={filter} onFilterChange={mockOnFilterChange} />, | ||
); | ||
} | ||
|
||
describe("BooleanPicker", () => { | ||
it("should hide empty options when empty options are not selected", () => { | ||
setup(filters.true); | ||
|
||
expect(screen.queryByLabelText("empty")).toBeNull(); | ||
expect(screen.queryByLabelText("not empty")).toBeNull(); | ||
|
||
screen.getByText("More options").click(); | ||
|
||
expect(screen.getByLabelText("empty")).toBeInTheDocument(); | ||
expect(screen.getByLabelText("not empty")).toBeInTheDocument(); | ||
}); | ||
|
||
it("should show empty options when given an empty filter", () => { | ||
setup(filters.empty); | ||
|
||
const option = screen.getByLabelText("empty"); | ||
expect(option.checked).toBe(true); | ||
|
||
expect(screen.getByLabelText("not empty")).toBeInTheDocument(); | ||
}); | ||
|
||
Object.entries(filters).forEach(([label, filter]) => { | ||
it(`should have the "${label}" option selected when given the associated filter`, () => { | ||
setup(filter); | ||
|
||
const option = screen.getByLabelText(label); | ||
expect(option.checked).toBe(true); | ||
}); | ||
|
||
it(`should correctly update the filter for the "${label}" option when it is selected`, () => { | ||
setup(label === "true" ? filters.false : filters.true); | ||
|
||
screen.getByText("More options").click(); | ||
|
||
screen.getByLabelText(label).click(); | ||
expect(mockOnFilterChange).toHaveBeenCalled(); | ||
const newFilter = mockOnFilterChange.mock.calls[0][0]; | ||
|
||
expect(newFilter.raw()).toEqual(filter.raw()); | ||
}); | ||
}); | ||
}); |
1 change: 1 addition & 0 deletions
1
frontend/src/metabase/query_builder/components/filters/pickers/BooleanPicker/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from "./BooleanPicker"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters