diff --git a/i18n/en-US.properties b/i18n/en-US.properties index aa1c61ddf4..dbffee273e 100644 --- a/i18n/en-US.properties +++ b/i18n/en-US.properties @@ -1408,46 +1408,6 @@ boxui.presence.timeSinceLastModified = Edited {timeAgo} boxui.presence.timeSinceLastPreviewed = Previewed {timeAgo} # Description of the button to toggle the presence overlay with recent activity boxui.presence.toggleButtonLabel = Recent Activity -# Text on the add filter button, on click generates another filter row -boxui.queryBar.addFilterButtonText = + Add Filter -# Text on the apply filter button, on click applies the filters -boxui.queryBar.applyFiltersButtonText = Apply -# Text on the columns button, on click opens a menu which allows users to choose which columns to render -boxui.queryBar.columnsButtonText = Columns -# Text on the columns button, if one or more columns have been hidden then it will display this text -boxui.queryBar.columnsHiddenButtonText = {count, plural, one {1 Column Hidden} other {{count} Columns Hidden}} -# Text on the connector dropdown, on click should open a dropdown showing either AND or OR -boxui.queryBar.connectorAndText = AND -# Text on the connector dropdown, on click should open a dropdown showing either AND or OR -boxui.queryBar.connectorOrText = OR -# Text on the label, the first condition will show WHERE -boxui.queryBar.connectorWhereText = WHERE -# Text on the filters button, on click opens a menu which allows users to filter through the files -boxui.queryBar.filtersButtonText = Modify Filters -# Header text shown in template dropdown -boxui.queryBar.metadataViewTemplateListHeaderTitle = METADATA TEMPLATES -# Text on the filters button, will display a number in front of the filters text indicating how many filters are applied -boxui.queryBar.multipleFiltersButtonText = {number} Filters -# Text on the filters dropdown that is displayed when no filters have been inserted -boxui.queryBar.noFiltersAppliedText = No Filters Applied -# Text on the templates button when templates have been loaded and there are no templates in the enterprise -boxui.queryBar.noTemplatesText = No Templates Available -# Placeholder text on the value button, on click should open a dropdown -boxui.queryBar.selectValuePlaceholderText = Select value -# Text on the templates button, on click opens a menu which allows users to select a metadata templates -boxui.queryBar.templatesButtonText = Select Metadata -# Text on the templates button when templates are still being loaded -boxui.queryBar.templatesLoadingButtonText = Template Name -# Text displayed on the Tooltip for an input field -boxui.queryBar.tooltipEnterValueError = Please Enter a Value -# Text displayed on the Tooltip for an input field of type float -boxui.queryBar.tooltipInvalidFloatError = Please Enter a Decimal Number -# Text displayed on the Tooltip for an input field of type number -boxui.queryBar.tooltipInvalidNumberError = Please Enter an Integer -# Text displayed on the Tooltip for a date field -boxui.queryBar.tooltipSelectDateError = Please Select a Date -# Text displayed on the Tooltip for a value field -boxui.queryBar.tooltipSelectValueError = Please Select a Value # Icon title for a Box item of type bookmark or web-link boxui.quickSearch.bookmark = Bookmark # Icon title for a Box item of type folder that has collaborators diff --git a/src/features/query-bar/QueryBar.js b/src/features/query-bar/QueryBar.js deleted file mode 100644 index d8493afb49..0000000000 --- a/src/features/query-bar/QueryBar.js +++ /dev/null @@ -1,47 +0,0 @@ -// @flow -import * as React from 'react'; - -import TemplateButton from './components/TemplateButton'; -import FilterButton from './components/filter/FilterButton'; -import ColumnButton from './components/ColumnButton'; - -import type { ColumnType, ConditionType } from './flowTypes'; -import type { MetadataTemplate } from '../../common/types/metadata'; - -import './styles/QueryBarButtons.scss'; - -type Props = { - activeTemplate?: MetadataTemplate, - columns?: Array, - conditions: Array, - onColumnChange?: Function, - onFilterChange?: Function, - onTemplateChange?: Function, - templates?: Array, -}; - -const isItemName = (column: ColumnType) => { - return column.source === 'item' && column.property === 'name'; -}; - -const QueryBar = ({ - activeTemplate, - columns, - conditions, - onColumnChange, - onFilterChange, - onTemplateChange, - templates, -}: Props) => { - const metadataColumns = columns && columns.filter(column => column.source !== 'item'); - const columnsWithoutItemName = columns && columns.filter(column => !isItemName(column)); - return ( -
- - - -
- ); -}; - -export default QueryBar; diff --git a/src/features/query-bar/README.md b/src/features/query-bar/README.md deleted file mode 100644 index ee160eae15..0000000000 --- a/src/features/query-bar/README.md +++ /dev/null @@ -1,23 +0,0 @@ -### Description - -### Demo - -**Query Bar Loading State** -```js -const MetadataViewQueryBarExamples = require('examples').MetadataViewQueryBarExamples; - -
- -
-``` - -**Query Bar** -```js -const MetadataViewQueryBarExamples = require('examples').MetadataViewQueryBarExamples; -const template = require('./components/fixtures').template; - -
- - Note: When Apply is clicked, the results of onFilterChange are logged to console. -
-``` \ No newline at end of file diff --git a/src/features/query-bar/__tests__/ColumnButton.test.js b/src/features/query-bar/__tests__/ColumnButton.test.js deleted file mode 100644 index 709ef68591..0000000000 --- a/src/features/query-bar/__tests__/ColumnButton.test.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as React from 'react'; - -import { columnForDateType, columnWithFloatType, template } from '../components/fixtures'; -import ColumnButton from '../components/ColumnButton'; - -describe('features/query-bar/components/ColumnButton', () => { - const getWrapper = (props = {}) => { - const columns = [columnForDateType, columnWithFloatType]; - return shallow(); - }; - - describe('render', () => { - test('should render ColumnButton default state when menu is closed', () => { - const wrapper = getWrapper(); - expect(wrapper).toMatchSnapshot(); - }); - - test('should render ColumnButton default state when menu is open', () => { - const wrapper = getWrapper(); - wrapper.instance().setState({ - isColumnMenuOpen: true, - }); - expect(wrapper).toMatchSnapshot(); - }); - - test('should render ColumnButton with template passed in', () => { - const wrapper = getWrapper({ template }); - expect(wrapper).toMatchSnapshot(); - }); - - const visibleColumns = [columnForDateType, columnWithFloatType]; - const oneHiddenColumn = [{ ...columnForDateType, isShown: false }]; - const twoHiddenColumns = [ - { ...columnForDateType, isShown: false }, - { ...columnWithFloatType, isShown: false }, - ]; - - test.each` - columns | values | should - ${visibleColumns} | ${undefined} | ${'should render ColumnButton with no column count when all columns are visible'} - ${oneHiddenColumn} | ${{ count: 1 }} | ${'should render ColumnButton with a column count of 1 when one column is hidden'} - ${twoHiddenColumns} | ${{ count: 2 }} | ${'should render ColumnButton with a column count of 2 when multiple columns are hidden'} - `('$should', ({ columns, values }) => { - const wrapper = getWrapper({ columns }); - const FormattedMessage = wrapper.find('FormattedMessage'); - expect(FormattedMessage.props().values).toEqual(values); - }); - }); - - describe('onClose()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isColumnMenuOpen: false, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - wrapper.instance().onClose(); - - expect(wrapper.state('isColumnMenuOpen')).toEqual(updatedState.isColumnMenuOpen); - }); - }); - }); - - describe('onOpen()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isColumnMenuOpen: true, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - wrapper.instance().onOpen(); - - expect(wrapper.state('isColumnMenuOpen')).toEqual(updatedState.isColumnMenuOpen); - }); - }); - }); - - describe('toggleColumnButton()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isColumnMenuOpen: true, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - wrapper.instance().toggleColumnButton(); - - expect(wrapper.state('isColumnMenuOpen')).toEqual(updatedState.isColumnMenuOpen); - }); - }); - }); - - describe('getNumberOfHiddenColumns()', () => { - [ - { - description: 'Should return the number of hidden columns', - numberOfHiddenColumns: 0, - }, - ].forEach(({ description, numberOfHiddenColumns }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - const result = wrapper.instance().getNumberOfHiddenColumns(); - - expect(result).toEqual(numberOfHiddenColumns); - }); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/ColumnButtonOverlay.test.js b/src/features/query-bar/__tests__/ColumnButtonOverlay.test.js deleted file mode 100644 index 48c1f9ff94..0000000000 --- a/src/features/query-bar/__tests__/ColumnButtonOverlay.test.js +++ /dev/null @@ -1,76 +0,0 @@ -import * as React from 'react'; - -import { columnForDateType, columnWithFloatType } from '../components/fixtures'; -import ColumnButtonOverlay from '../components/ColumnButtonOverlay'; - -const columns = [columnForDateType, columnWithFloatType]; - -describe('features/query-bar/components/ColumnButtonOverlay', () => { - const getWrapper = (props = {}) => { - return shallow(); - }; - - describe('render', () => { - test('should render ColumnButtonOverlay default state', () => { - const wrapper = getWrapper(); - expect(wrapper).toMatchSnapshot(); - }); - }); - - describe('onDragEnd()', () => { - [ - { - description: 'Should update state with new ordering', - sourceIndex: 0, - destinationIndex: 1, - updatedColumns: [columnWithFloatType, columnForDateType], - }, - { - description: 'Should not update state due to no destinationIndex', - sourceIndex: 0, - updatedColumns: columns, - }, - ].forEach(({ description, sourceIndex, destinationIndex, updatedColumns }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - wrapper.instance().onDragEnd(sourceIndex, destinationIndex); - - expect(wrapper.state('pendingColumns')).toEqual(updatedColumns); - }); - }); - }); - - describe('applyFilters()', () => { - [ - { - description: 'Should apply filters to parent state', - pendingColumns: columns, - }, - ].forEach(({ description, pendingColumns }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - - wrapper.setState({ - pendingColumns, - }); - wrapper.instance().applyFilters(); - }); - }); - }); - - describe('updatePendingColumns()', () => { - test('Should update state with pendingColumns', () => { - const pendingColumns = columns; - - const wrapper = getWrapper(); - wrapper.setState({ - pendingColumns, - }); - - wrapper.instance().updatePendingColumns(columnForDateType); - - expect(wrapper.state('pendingColumns')[0].isShown).toBeFalsy(); - expect(wrapper.state('pendingColumns')[1].isShown).toBeTruthy(); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/Condition.test.js b/src/features/query-bar/__tests__/Condition.test.js deleted file mode 100644 index 4eb4e5ddef..0000000000 --- a/src/features/query-bar/__tests__/Condition.test.js +++ /dev/null @@ -1,113 +0,0 @@ -// @flow -import * as React from 'react'; - -import { columnWithEnumType } from '../components/fixtures'; -import Condition from '../components/filter/Condition'; -import { EQUALS } from '../constants'; - -const invalidCondition: ConditionType = { columnId: '3', id: '0', operator: EQUALS, values: [] }; -const columns = [columnWithEnumType]; - -describe('features/query-bar/components/filter/Condition', () => { - const getWrapper = (props = {}) => { - return shallow( - {}} - update={() => {}} - intl={{ formatMessage: () => {} }} - {...props} - />, - ); - }; - - describe('render()', () => { - test('should render Condition', () => { - const condition = invalidCondition; - const wrapper = getWrapper({ condition }); - - expect(wrapper).toMatchSnapshot(); - }); - }); - - describe('handleColumnChange()', () => { - test('should select a column', () => { - const condition = invalidCondition; - const columnId = '1'; - const option = { - type: 'string', - value: columnId, - }; - const onColumnChange = jest.fn(); - const wrapper = getWrapper({ - onColumnChange, - }); - - wrapper - .find('SingleSelectField') - .at(0) - .simulate('change', option); - - expect(onColumnChange).toHaveBeenCalledWith(condition, columnId); - }); - }); - - describe('handleOperatorChange()', () => { - const displayText = 'Vendor Name'; - const condition = invalidCondition; - const value = '0'; - const option = { - displayText, - value, - }; - - test('should select an operator', () => { - const onOperatorChange = jest.fn(); - const wrapper = getWrapper({ - onOperatorChange, - }); - - wrapper - .find('SingleSelectField') - .at(1) - .simulate('change', option); - expect(onOperatorChange).toHaveBeenCalledWith(condition.id, value); - }); - }); - - describe('handleValueChange()', () => { - const condition = invalidCondition; - const textInputValue = 'string'; - const selectFieldValue = '1'; - const dateFieldValue = new Date(2018, 11, 24, 10, 33, 30, 0); - - test.each` - description | option | value - ${'should invoke onValueChange with "string"'} | ${textInputValue} | ${textInputValue} - ${'should invoke onValueChange with selectFieldValue'} | ${selectFieldValue} | ${selectFieldValue} - ${'should invoke onValueChange with Date'} | ${dateFieldValue} | ${dateFieldValue} - `('$description', ({ option, value }) => { - const onValueChange = jest.fn(); - const wrapper = getWrapper({ onValueChange }); - - wrapper.find('ValueField').prop('onChange')(option); - - expect(onValueChange).toHaveBeenCalledWith(condition.id, value); - }); - }); - - describe('getColumnOptions()', () => { - test('should open the value dropdown and see the options', () => { - const wrapper = getWrapper(); - const ValueField = wrapper.find('ValueField'); - expect(ValueField.props().valueOptions).toEqual([ - { - displayText: '$100', - value: '$100', - }, - ]); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/FilterButton.test.js b/src/features/query-bar/__tests__/FilterButton.test.js deleted file mode 100644 index e14411c9f5..0000000000 --- a/src/features/query-bar/__tests__/FilterButton.test.js +++ /dev/null @@ -1,291 +0,0 @@ -// @flow -import * as React from 'react'; - -import { columnForTemplateFieldName, columnForDateType } from '../components/fixtures'; -import FilterButton from '../components/filter/FilterButton'; -import type { ConditionType } from '../flowTypes'; -import { EQUALS, LESS_THAN } from '../constants'; - -const validCondition: ConditionType = { - columnId: columnForTemplateFieldName.id, - id: '0', - operator: EQUALS, - values: [1], -}; -const invalidCondition: ConditionType = { - ...validCondition, - values: [], -}; -const columns = [columnForTemplateFieldName, columnForDateType]; -const validConditions = [validCondition]; -const invalidConditions = [invalidCondition]; - -describe('feature/query-bar/components/filter/FilterButton', () => { - const getWrapper = (props = {}) => { - return shallow(); - }; - - describe('render', () => { - test('should disable FilterButton when columns is undefined', () => { - const wrapper = getWrapper({ columns: null }); - const Button = wrapper.find('Button'); - expect(Button.props().isDisabled).toBeTruthy(); - }); - - test('should enable FilterButton when columns is non-empty', () => { - const wrapper = getWrapper({ columns }); - const Button = wrapper.find('Button'); - expect(Button.props().isDisabled).toBeFalsy(); - }); - - test('Should close the menu and clear out transientConditions when Apply button is clicked', () => { - const wrapper = getWrapper({ conditions: validConditions }); - wrapper.instance().setState({ - transientConditions: validConditions, - isMenuOpen: true, - }); - - wrapper.find('.apply-filters-button').simulate('click'); - - const Flyout = wrapper.find('Flyout'); - expect(Flyout.props().overlayIsVisible).toBeFalsy(); - expect(wrapper.state('transientConditions')).toHaveLength(0); - }); - - test('Should set hasUserSubmitted to true for Condition if any condition is invalid', () => { - const wrapper = getWrapper({ conditions: [{ values: [] }] }); - wrapper.instance().setState({ - transientConditions: invalidConditions, - isMenuOpen: true, - }); - - wrapper.find('.apply-filters-button').simulate('click'); - - const Condition = wrapper.find('Condition'); - expect(Condition.props().hasUserSubmitted).toBeTruthy(); - }); - }); - - describe('componentDidUpdate()', () => { - const initialCondition = { - columnId: columnForTemplateFieldName.id, - id: '1', - operator: '=', - values: [], - }; - - test.each` - innerColumns | conditions | transientConditions | expectedConditions | should - ${columns} | ${validConditions} | ${[]} | ${validConditions} | ${'should reinitialize conditions from props.conditions when flyout is opened and props.conditions is not empty'} - ${columns} | ${[]} | ${[]} | ${[initialCondition]} | ${'should set initial condition if props.conditions is empty and transientConditions are empty'} - ${[]} | ${[]} | ${[]} | ${[]} | ${'should set empty array if props.conditions is empty and transientConditions are empty and columns are empty'} - `('$should', ({ innerColumns, conditions, transientConditions, expectedConditions }) => { - const wrapper = getWrapper({ columns: innerColumns, conditions }); - wrapper.setState({ - isMenuOpen: true, - transientConditions, - }); - wrapper.instance().componentDidUpdate({}, { isMenuOpen: false }); - - expect(wrapper.state('transientConditions')).toEqual(expectedConditions); - }); - }); - - describe('handleColumnChange()', () => { - test('should update condition to the selected column', () => { - const conditions2 = { - ...validConditions, - columnId: columnForTemplateFieldName.id, - }; - - const wrapper = getWrapper({ columns }); - wrapper.setState({ - conditions: conditions2, - }); - wrapper.instance().handleColumnChange(conditions2[0], columnForDateType.id); - - expect(wrapper.state('transientConditions')[0].columnId).toEqual(columnForDateType.id); - }); - }); - - describe('handleOperatorChange()', () => { - const transientConditions = [ - { - columnId: '1', - id: '4', - operator: EQUALS, - values: [], - }, - ]; - const expectedConditions = [{ columnId: '1', id: '4', operator: LESS_THAN, values: [] }]; - test.each` - conditionId | value - ${'4'} | ${LESS_THAN} - `('should update condition.operator', ({ conditionId, value }) => { - const wrapper = getWrapper({ columns }); - wrapper.setState({ - transientConditions, - }); - wrapper.instance().handleOperatorChange(conditionId, value); - - expect(wrapper.state('transientConditions')).toEqual(expectedConditions); - }); - }); - - describe('handleValueChange()', () => { - const transientConditions = [ - { - columnId: '1', - id: '5', - operator: EQUALS, - values: [], - }, - ]; - const expectedConditions = [{ columnId: '1', id: '5', operator: EQUALS, values: ['0'] }]; - test.each` - conditionId | values - ${'5'} | ${['0']} - `('should update condition.values', ({ conditionId, values }) => { - const wrapper = getWrapper({ columns }); - wrapper.setState({ - transientConditions, - }); - wrapper.instance().handleValueChange(conditionId, values); - - expect(wrapper.state('transientConditions')).toEqual(expectedConditions); - }); - }); - - describe('deleteCondition()', () => { - const transientConditions = [ - { - id: '2', - operator: EQUALS, - values: [], - }, - { - id: '3', - operator: EQUALS, - values: [], - }, - ]; - const expectedConditions = [ - { - id: '3', - operator: EQUALS, - values: [], - }, - ]; - - test.each` - index - ${0} - `('should delete condition at index 0', ({ index }) => { - const wrapper = getWrapper({ columns }); - wrapper.instance().setState({ - transientConditions, - }); - wrapper.instance().deleteCondition(index); - - expect(wrapper.state('transientConditions')).toEqual(expectedConditions); - }); - }); - - describe('onClose()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isMenuOpen: false, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper({ columns }); - wrapper.instance().onClose(); - - expect(wrapper.state('isMenuOpen')).toEqual(updatedState.isMenuOpen); - }); - }); - }); - - describe('onOpen()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isMenuOpen: true, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper({ columns }); - wrapper.instance().onOpen(); - - expect(wrapper.state('isMenuOpen')).toEqual(updatedState.isMenuOpen); - }); - }); - }); - - describe('toggleButton()', () => { - [ - { - description: 'Should update state with new ordering', - updatedState: { - isMenuOpen: true, - }, - }, - ].forEach(({ description, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper({ columns }); - wrapper.instance().toggleButton(); - - expect(wrapper.state('isMenuOpen')).toEqual(updatedState.isMenuOpen); - }); - }); - }); - - describe('createCondition()', () => { - test('Should return a condition object if columns is non-empty', () => { - const wrapper = getWrapper({ columns }); - wrapper.instance().setState({ - transientConditions: [], - }); - - const condition = wrapper.instance().createCondition(); - expect(condition.columnId).toEqual(columnForTemplateFieldName.id); - expect(condition.id).toBeDefined(); - expect(condition.operator).toEqual(EQUALS); - expect(condition.values).toEqual([]); - }); - - test('Should throw an error if columns is empty', () => { - const wrapper = getWrapper({ columns: [] }); - - expect(() => { - wrapper.instance().createCondition(); - }).toThrow('Columns Required'); - }); - }); - - describe('closeOnClickPredicate()', () => { - test.each` - description | transientConditions | shouldCloseResult - ${'Should return true if Apply button was clicked and value is not empty'} | ${validConditions} | ${true} - ${'Should return false if Apply button was clicked and value is empty'} | ${invalidConditions} | ${false} - `('$description', ({ transientConditions, shouldCloseResult }) => { - const wrapper = getWrapper({ columns }); - const targetWithClassName = { - target: document.createElement('button'), - }; - wrapper.instance().setState({ - transientConditions, - }); - targetWithClassName.target.className = 'apply-filters-button'; - const closeOnClickPredicateResult = wrapper.instance().shouldClose(targetWithClassName); - - wrapper.update(); - expect(closeOnClickPredicateResult).toEqual(shouldCloseResult); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/QueryBar.test.js b/src/features/query-bar/__tests__/QueryBar.test.js deleted file mode 100644 index f8bd03f630..0000000000 --- a/src/features/query-bar/__tests__/QueryBar.test.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as React from 'react'; - -import { columnForItemName, columnForTemplateFieldName, template } from '../components/fixtures'; -import QueryBar from '../QueryBar'; - -const columns = [columnForItemName, columnForTemplateFieldName]; - -describe('features/query-bar/components/QueryBar', () => { - const getWrapper = props => { - return shallow(); - }; - - test('should render', () => { - const wrapper = getWrapper(); - expect(wrapper).toMatchSnapshot(); - }); - - test('should render when template is not selected', () => { - const wrapper = getWrapper({ - templates: [template], - }); - expect(wrapper).toMatchSnapshot(); - }); - - test('should render ColumnButton with columns that do not include item name', () => { - const wrapper = getWrapper({ columns }); - const ColumnButton = wrapper.find('ColumnButton'); - expect(ColumnButton.props().columns).toEqual([columnForTemplateFieldName]); - }); - - test('should render FilterButton with metadata columns', () => { - const wrapper = getWrapper({ columns }); - const FilterButton = wrapper.find('FilterButton'); - expect(FilterButton.props().columns).toEqual([columnForTemplateFieldName]); - }); -}); diff --git a/src/features/query-bar/__tests__/TemplateButton.test.js b/src/features/query-bar/__tests__/TemplateButton.test.js deleted file mode 100644 index db3ed5f049..0000000000 --- a/src/features/query-bar/__tests__/TemplateButton.test.js +++ /dev/null @@ -1,96 +0,0 @@ -// @flow -import * as React from 'react'; - -import TemplateButton from '../components/TemplateButton'; -import { template } from '../components/fixtures'; - -describe('feature/query-bar/components/TemplateButton', () => { - const getWrapper = (props = {}) => { - return shallow(); - }; - - describe('render()', () => { - test('should render TemplateButton', () => { - const wrapper = getWrapper(); - expect(wrapper).toMatchSnapshot(); - }); - }); - - describe('updateActiveTemplate', () => { - test('should call onTemplateChange', () => { - const onTemplateChangeMock = jest.fn(); - const wrapper = getWrapper({ - onTemplateChange: onTemplateChangeMock, - }); - - wrapper.instance().updateActiveTemplate(template); - expect(onTemplateChangeMock.mock.calls.length).toBe(1); - }); - }); - - describe('toggleTemplateDropdownButton()', () => { - [ - { - description: 'Should open the dropdown', - initialState: { - isTemplateMenuOpen: false, - }, - updatedState: { - isTemplateMenuOpen: true, - }, - }, - { - description: 'Should close the dropdown', - initialState: { - isTemplateMenuOpen: true, - }, - updatedState: { - isTemplateMenuOpen: false, - }, - }, - ].forEach(({ description, initialState, updatedState }) => { - test(`${description}`, () => { - const wrapper = getWrapper(); - wrapper.instance().setState({ - isTemplateMenuOpen: initialState.isTemplateMenuOpen, - }); - wrapper.instance().toggleTemplateDropdownButton(); - - expect(wrapper.state('isTemplateMenuOpen')).toEqual(updatedState.isTemplateMenuOpen); - }); - }); - }); - - describe('renderEntryButton()', () => { - const templ = { - id: '123', - displayName: 'template name 1', - }; - const activeTemplateClassName = 'is-active'; - - test.each` - activeTemplate | expectedReturn | description - ${templ} | ${true} | ${'Should render div with class containing is-active'} - ${null} | ${false} | ${'Should render div with class that does not contain is-active'} - `('$description', ({ activeTemplate, expectedReturn }) => { - const wrapper = getWrapper({ activeTemplate }); - wrapper.instance().setState({ - isTemplateMenuOpen: true, - }); - - const entryButtonWrapper = shallow(wrapper.instance().renderEntryButton()); - expect(entryButtonWrapper.props().className.includes(activeTemplateClassName)).toEqual(expectedReturn); - }); - - test.each` - templates | expectedMessage | description - ${null} | ${'Template Name'} | ${'Should render templates loading message'} - ${[]} | ${'No Templates Available'} | ${'Should render no templates message'} - `('$description', ({ templates, expectedMessage }) => { - const wrapper = getWrapper({ templates }); - - const entryButtonWrapper = shallow(wrapper.instance().renderEntryButton()); - expect(entryButtonWrapper.find('FormattedMessage').props().defaultMessage).toEqual(expectedMessage); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/ValueField.test.js b/src/features/query-bar/__tests__/ValueField.test.js deleted file mode 100644 index c2fa0a384d..0000000000 --- a/src/features/query-bar/__tests__/ValueField.test.js +++ /dev/null @@ -1,103 +0,0 @@ -import * as React from 'react'; - -import ValueField from '../components/filter/ValueField'; - -describe('features/query-bar/components/filter/ValueField', () => { - const getWrapper = (props = {}) => { - const intl = { - formatMessage: jest.fn(), - }; - - return shallow( - , - ); - }; - - describe('render value fields', () => { - const emptyArray = []; - const valuePropNames = { - MultiSelectField: 'selectedValues', - SingleSelectField: 'selectedValue', - DatePicker: 'value', - TextInput: 'value', - }; - - describe('when selected values are empty', () => { - test.each` - description | valueType | componentName | selectedValues - ${'should render SingleSelectField for valueType of enum'} | ${'enum'} | ${'SingleSelectField'} | ${emptyArray} - ${'should render DatePicker for valueType of date'} | ${'date'} | ${'DatePicker'} | ${emptyArray} - ${'should render TextInput for valueType of string'} | ${'string'} | ${'TextInput'} | ${emptyArray} - ${'should render TextInput for valueType of float'} | ${'float'} | ${'TextInput'} | ${emptyArray} - ${'should render TextInput for valueType of number'} | ${'number'} | ${'TextInput'} | ${emptyArray} - `('$description', ({ componentName, selectedValues, valueType }) => { - const wrapper = getWrapper({ valueType, selectedValues }); - - const component = wrapper.find(componentName); - expect(component).toHaveLength(1); - expect(component.prop(valuePropNames[componentName])).toBeFalsy(); - }); - }); - - describe('when selected values are non-empty', () => { - const stringValue = 'r'; - const dateValue = new Date(1995, 11, 25, 9, 30, 0); - - test.each` - description | valueType | componentName | selectedValues | expectedValue - ${'should render MultiSelectField for valueType of multiSelect'} | ${'multiSelect'} | ${'MultiSelectField'} | ${['r', 'g', 'b']} | ${['r', 'g', 'b']} - ${'should render SingleSelectField for valueType of enum'} | ${'enum'} | ${'SingleSelectField'} | ${[stringValue]} | ${stringValue} - ${'should render DatePicker for valueType of date'} | ${'date'} | ${'DatePicker'} | ${[dateValue]} | ${dateValue} - ${'should render DatePicker for valueType of date and user tries to delete the existing input'} | ${'date'} | ${'DatePicker'} | ${[null]} | ${undefined} - ${'should render TextInput for valueType of string'} | ${'string'} | ${'TextInput'} | ${[stringValue]} | ${stringValue} - ${'should render TextInput for valueType of float'} | ${'float'} | ${'TextInput'} | ${[stringValue]} | ${stringValue} - ${'should render TextInput for valueType of number'} | ${'number'} | ${'TextInput'} | ${[stringValue]} | ${stringValue} - `('$description', ({ componentName, expectedValue, selectedValues, valueType }) => { - const wrapper = getWrapper({ valueType, selectedValues }); - - const component = wrapper.find(componentName); - expect(component).toHaveLength(1); - expect(component.prop(valuePropNames[componentName])).toEqual(expectedValue); - }); - }); - - describe('should not show an error for a', () => { - test.each` - valueType | componentName | should - ${'multiSelect'} | ${'MultiSelectField'} | ${'MultiSelectField of type multiSelect'} - ${'enum'} | ${'SingleSelectField'} | ${'SingleSelectField of type enum'} - ${'date'} | ${'DatePicker'} | ${'DatePicker of type date'} - `('$should', ({ componentName, valueType }) => { - const wrapper = getWrapper({ valueType, error: null, selectedValues: [] }); - const component = wrapper.find(componentName); - expect(component.prop('error')).toBe(undefined); - }); - }); - - describe('should show an error for a TextInput of ', () => { - const error =
; - test.each` - valueType | should - ${'string'} | ${'type string'} - ${'float'} | ${'type float'} - ${'number'} | ${'type number'} - `('$should', ({ valueType }) => { - const wrapper = getWrapper({ valueType, error, selectedValues: [] }); - const component = wrapper.find('TextInput'); - expect(component.prop('error')).toBe(error); - }); - }); - }); -}); diff --git a/src/features/query-bar/__tests__/__snapshots__/ColumnButton.test.js.snap b/src/features/query-bar/__tests__/__snapshots__/ColumnButton.test.js.snap deleted file mode 100644 index 98db269efa..0000000000 --- a/src/features/query-bar/__tests__/__snapshots__/ColumnButton.test.js.snap +++ /dev/null @@ -1,152 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`features/query-bar/components/ColumnButton render should render ColumnButton default state when menu is closed 1`] = ` - - - -
- - -`; - -exports[`features/query-bar/components/ColumnButton render should render ColumnButton default state when menu is open 1`] = ` - - - - - - -`; - -exports[`features/query-bar/components/ColumnButton render should render ColumnButton with template passed in 1`] = ` - - - -
- - -`; diff --git a/src/features/query-bar/__tests__/__snapshots__/ColumnButtonOverlay.test.js.snap b/src/features/query-bar/__tests__/__snapshots__/ColumnButtonOverlay.test.js.snap deleted file mode 100644 index c0bcc582c9..0000000000 --- a/src/features/query-bar/__tests__/__snapshots__/ColumnButtonOverlay.test.js.snap +++ /dev/null @@ -1,57 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`features/query-bar/components/ColumnButtonOverlay render should render ColumnButtonOverlay default state 1`] = ` -
-
- - - - - - - - -
-
- - - -
-
-`; diff --git a/src/features/query-bar/__tests__/__snapshots__/Condition.test.js.snap b/src/features/query-bar/__tests__/__snapshots__/Condition.test.js.snap deleted file mode 100644 index 26e3b6c904..0000000000 --- a/src/features/query-bar/__tests__/__snapshots__/Condition.test.js.snap +++ /dev/null @@ -1,109 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`features/query-bar/components/filter/Condition render() should render Condition 1`] = ` -
-
- -
-
-

- -

-
-
-
- -
-
-
-
- ", - }, - { - "displayText": "is greater than", - "value": ">", - }, - { - "displayText": "is less than", - "value": "<", - }, - ] - } - selectedValue="=" - /> -
-
-
- -
-
-`; diff --git a/src/features/query-bar/__tests__/__snapshots__/QueryBar.test.js.snap b/src/features/query-bar/__tests__/__snapshots__/QueryBar.test.js.snap deleted file mode 100644 index bc561b7551..0000000000 --- a/src/features/query-bar/__tests__/__snapshots__/QueryBar.test.js.snap +++ /dev/null @@ -1,178 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`features/query-bar/components/QueryBar should render 1`] = ` -
- - - -
-`; - -exports[`features/query-bar/components/QueryBar should render when template is not selected 1`] = ` -
- - - -
-`; diff --git a/src/features/query-bar/__tests__/__snapshots__/TemplateButton.test.js.snap b/src/features/query-bar/__tests__/__snapshots__/TemplateButton.test.js.snap deleted file mode 100644 index 114f410367..0000000000 --- a/src/features/query-bar/__tests__/__snapshots__/TemplateButton.test.js.snap +++ /dev/null @@ -1,54 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`feature/query-bar/components/TemplateButton render() should render TemplateButton 1`] = ` - - } - className="query-bar-template-dropdown-flyout" - defaultTemplateIcon={ - - } - entryButton={ - - } - onAdd={[Function]} - templates={[]} - title={ -
- -
- } - usedTemplates={[]} -/> -`; diff --git a/src/features/query-bar/components/ColumnButton.js b/src/features/query-bar/components/ColumnButton.js deleted file mode 100644 index ce320ca519..0000000000 --- a/src/features/query-bar/components/ColumnButton.js +++ /dev/null @@ -1,118 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; - -import { Flyout, Overlay } from '../../../components/flyout'; -import Button from '../../../components/button/Button'; -import MenuToggle from '../../../components/dropdown-menu/MenuToggle'; -import IconMetadataColumns from '../../../icons/metadata-view/IconMetadataColumns'; -import ColumnButtonOverlay from './ColumnButtonOverlay'; - -import type { ColumnType } from '../flowTypes'; -import type { MetadataTemplate } from '../../../common/types/metadata'; - -import messages from '../messages'; - -type State = { - isColumnMenuOpen: boolean, -}; - -type Props = { - columns?: Array, - onColumnChange?: (columnTypes: Array) => void, - template?: MetadataTemplate, -}; - -class ColumnButton extends React.Component { - constructor(props: Props) { - super(props); - this.state = { - isColumnMenuOpen: false, - }; - } - - onClose = () => { - this.setState({ - isColumnMenuOpen: false, - }); - }; - - onOpen = () => { - this.setState({ - isColumnMenuOpen: true, - }); - }; - - toggleColumnButton = () => { - this.setState({ isColumnMenuOpen: !this.state.isColumnMenuOpen }); - }; - - getNumberOfHiddenColumns = () => { - const { columns } = this.props; - - return columns - ? columns.reduce((total, column) => { - if (!column.isShown) { - return total + 1; - } - return total; - }, 0) - : 0; - }; - - render() { - const { template, columns, onColumnChange } = this.props; - const { isColumnMenuOpen } = this.state; - const numberOfHiddenColumns = this.getNumberOfHiddenColumns(); - - const buttonClasses = classNames('query-bar-button', numberOfHiddenColumns !== 0 ? 'is-active' : ''); - - let columnsButtonText; - if (numberOfHiddenColumns === 0) { - columnsButtonText = ; - } else { - columnsButtonText = ( - - ); - } - - return ( - - - - - {isColumnMenuOpen ? ( - - ) : ( -
- )} - - - ); - } -} - -export default ColumnButton; diff --git a/src/features/query-bar/components/ColumnButtonOverlay.js b/src/features/query-bar/components/ColumnButtonOverlay.js deleted file mode 100644 index b831acc663..0000000000 --- a/src/features/query-bar/components/ColumnButtonOverlay.js +++ /dev/null @@ -1,111 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import uniqueId from 'lodash/uniqueId'; -import cloneDeep from 'lodash/cloneDeep'; - -import Checkbox from '../../../components/checkbox/Checkbox'; -import DraggableList from '../../../components/draggable-list'; -import PortaledDraggableListItem from '../../../components/draggable-list/PortaledDraggableListItem'; -import PrimaryButton from '../../../components/primary-button/PrimaryButton'; -import reorder from '../../../components/draggable-list/draggable-list-utils/reorder'; - -import type { ColumnType } from '../flowTypes'; - -import messages from '../messages'; - -type State = { - listId: string, - pendingColumns: Array, -}; - -type Props = { - columns?: Array, - onColumnChange?: (columnTypes: Array) => void, -}; - -class ColumnButtonOverlay extends React.Component { - constructor(props: Props) { - super(props); - this.state = { - listId: uniqueId(), - pendingColumns: props.columns ? cloneDeep(props.columns) : [], - }; - } - - onDragEnd = (sourceIndex: number, destinationIndex: number) => { - const { pendingColumns } = this.state; - const columns = reorder(pendingColumns, sourceIndex, destinationIndex); - this.setState({ - pendingColumns: cloneDeep(columns), - }); - }; - - updatePendingColumns = (column: ColumnType) => { - const { pendingColumns } = this.state; - - const pendingColumnsCopy = cloneDeep(pendingColumns); - - const newColumn = { ...column, isShown: !column.isShown }; - - const foundIndex = pendingColumnsCopy.findIndex(originalColumn => originalColumn.id === column.id); - - pendingColumnsCopy[foundIndex] = newColumn; - this.setState({ - pendingColumns: pendingColumnsCopy, - }); - }; - - applyFilters = () => { - const { onColumnChange } = this.props; - const { pendingColumns } = this.state; - if (onColumnChange) { - onColumnChange(pendingColumns); - } - }; - - getNumberOfHiddenColumns = () => { - const { columns } = this.props; - - return columns - ? columns.reduce((total, column) => { - if (!column.isShown) { - return total + 1; - } - return total; - }, 0) - : 0; - }; - - render() { - const { listId, pendingColumns } = this.state; - - return ( -
-
- - {pendingColumns.map((item, index) => { - return ( - - this.updatePendingColumns(item)} - /> - - ); - })} - -
-
- - - -
-
- ); - } -} - -export default ColumnButtonOverlay; diff --git a/src/features/query-bar/components/TemplateButton.js b/src/features/query-bar/components/TemplateButton.js deleted file mode 100644 index cf51de8875..0000000000 --- a/src/features/query-bar/components/TemplateButton.js +++ /dev/null @@ -1,113 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; - -import MetadataDefaultBadge from '../../../icons/badges/MetadataDefaultBadge'; -import MetadataActiveBadge from '../../../icons/badges/MetadataActiveBadge'; -import TemplateDropdown from '../../metadata-instance-editor/TemplateDropdown'; -import Button from '../../../components/button/Button'; -import MenuToggle from '../../../components/dropdown-menu/MenuToggle'; -import messages from '../messages'; -import LoadingIndicator from '../../../components/loading-indicator'; -import type { MetadataTemplate } from '../../../common/types/metadata'; - -type State = { - isTemplateMenuOpen: boolean, -}; - -type Props = { - activeTemplate?: MetadataTemplate, - onAdd?: Function, - onTemplateChange?: Function, - templates?: Array, - usedTemplates: Array, -}; - -class TemplateButton extends React.Component { - static defaultProps = { - usedTemplates: [], - }; - - state = { - isTemplateMenuOpen: false, - }; - - toggleTemplateDropdownButton = () => { - this.setState({ isTemplateMenuOpen: !this.state.isTemplateMenuOpen }); - }; - - updateActiveTemplate = (template: MetadataTemplate) => { - const { onTemplateChange } = this.props; - - if (onTemplateChange) { - onTemplateChange(template); - } - }; - - renderEntryButton = () => { - const { templates, activeTemplate } = this.props; - - let icon; - let text; - - const isLoadingTemplates = !templates; - const hasTemplates = templates && templates.length > 0; - - if (isLoadingTemplates) { - icon = ; - text = ; - } else if (!hasTemplates) { - text = ; - } else if (activeTemplate) { - icon = ; - text = activeTemplate.displayName; - } else if (!activeTemplate) { - icon = ; - text = ; - } - - const buttonClasses = classNames('query-bar-button', { - 'is-active': activeTemplate, - }); - - return ( - - ); - }; - - renderTitle = () => ( -
- -
- ); - - render() { - const { activeTemplate, templates, usedTemplates } = this.props; - return ( - } - title={this.renderTitle()} - onAdd={this.updateActiveTemplate} - activeTemplate={activeTemplate} - activeTemplateIcon={} - templates={templates || []} - usedTemplates={usedTemplates} - entryButton={this.renderEntryButton()} - /> - ); - } -} - -export default TemplateButton; diff --git a/src/features/query-bar/components/filter/Condition.js b/src/features/query-bar/components/filter/Condition.js deleted file mode 100644 index ace0cb5562..0000000000 --- a/src/features/query-bar/components/filter/Condition.js +++ /dev/null @@ -1,318 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import isFinite from 'lodash/isFinite'; -import isInteger from 'lodash/isInteger'; -import classNames from 'classnames'; - -import IconClose from '../../../../icons/general/IconClose'; -import Tooltip from '../../../../components/tooltip'; -import IconAlertDefault from '../../../../icons/general/IconAlertDefault'; -import SingleSelectField from '../../../../components/select-field/SingleSelectField'; -import ValueField from './ValueField'; - -import messages from '../../messages'; -import { - AND, - COLUMN, - COLUMN_OPERATORS, - DATE, - ENUM, - FLOAT, - MULTI_SELECT, - NUMBER, - OPERATOR, - OR, - STRING, -} from '../../constants'; -import type { - ColumnType, - ConditionType, - ConditionValueType, - ConnectorType, - OperatorOptionType, - OperatorType, - OptionType, -} from '../../flowTypes'; - -import '../../styles/Condition.scss'; - -type Props = { - columns?: Array, - condition: ConditionType, - deleteCondition: (index: number) => void, - hasUserSubmitted: boolean, - index: number, - onColumnChange: (condition: ConditionType, columnId: string) => void, - onConnectorChange: (option: OptionType) => void, - onOperatorChange: (conditionId: string, value: OperatorType) => void, - onValueChange: (conditionId: string, values: Array) => void, - selectedConnector: ConnectorType, -}; - -const deleteButtonIconHeight = 18; -const deleteButtonIconWidth = 18; - -const Condition = ({ - hasUserSubmitted, - columns, - condition, - deleteCondition, - onColumnChange, - onOperatorChange, - onValueChange, - index, - selectedConnector, - onConnectorChange, -}: Props) => { - const onDeleteButtonClick = () => { - deleteCondition(index); - }; - - const handleColumnChange = (option: OptionType) => { - const { value: columnId } = option; - onColumnChange(condition, columnId); - }; - - const handleOperatorChange = (option: OperatorOptionType) => { - const { id } = condition; - const { value } = option; - onOperatorChange(id, value); - }; - - const handleValueChange = (values: Array) => { - const { id } = condition; - onValueChange(id, values); - }; - - const getColumnOperators = () => { - const { columnId } = condition; - const column = columns && columns.find(c => c.id === columnId); - const type = column && column.type; - - if (!type) { - return []; - } - return COLUMN_OPERATORS[type]; - }; - - const getColumnOptions = () => { - const { columnId } = condition; - const column = columns && columns.find(c => c.id === columnId); - if (column && column.options) { - return column.options.map(option => { - const { key } = option; - return { - displayText: key, - value: key, - }; - }); - } - return []; - }; - - const validateValue = (values: Array, type: string) => { - switch (type) { - case NUMBER: - return isInteger(Number(values[0])); - case FLOAT: - return isFinite(Number(values[0])); - default: - break; - } - return true; - }; - - const getErrorMessage = () => { - const { values, columnId } = condition; - const column = columns && columns.find(c => c.id === columnId); - const type = column && column.type; - - const isValueEmpty = values.length === 0; - - let isValueValid = false; - if (!isValueEmpty && type) { - isValueValid = validateValue(values, type); - } - - /** - * isValueValid handles the error case when the user tries to enter an invalid input in either a - * number type field or a float type field - * - * (!hasUserSubmitted && !isValueSet) handles the error case when a user presses on the Apply button - * but the input field is empty - */ - if (isValueValid || (!hasUserSubmitted && isValueEmpty)) { - return null; - } - - let messageText; - switch (type) { - case STRING: - messageText = messages.tooltipEnterValueError; - break; - case NUMBER: - messageText = !isValueValid ? messages.tooltipInvalidNumberError : messages.tooltipEnterValueError; - break; - case FLOAT: - messageText = !isValueValid ? messages.tooltipInvalidFloatError : messages.tooltipEnterValueError; - break; - case DATE: - messageText = messages.tooltipSelectDateError; - break; - case ENUM: - messageText = messages.tooltipSelectValueError; - break; - case MULTI_SELECT: - messageText = messages.tooltipSelectValueError; - break; - default: - break; - } - - return messageText && ; - }; - - const renderDeleteButton = () => { - return ( -
- -
- ); - }; - - const renderConnectorField = () => { - const connectorOptions = [AND, OR].map(connector => ({ - displayText: connector, - value: connector, - })); - - return ( -
- {index === 0 ? ( -

- -

- ) : ( - - )} -
- ); - }; - - const renderColumnField = () => { - const { columnId } = condition; - - const columnOptions = - columns && - columns.map(column => { - const { displayName, id, type } = column; - return { - displayText: displayName, - type, - value: id, - }; - }); - - return ( -
-
- -
-
- ); - }; - - const renderOperatorField = () => { - const { operator } = condition; - const columnOperators = getColumnOperators(); - const operatorOptions = columnOperators.map(_operator => { - const { displayText, key } = _operator; - return { - displayText, - value: key, - }; - }); - - return ( -
-
- -
-
- ); - }; - - const renderValueField = () => { - const column = columns && columns.find(c => c.id === condition.columnId); - - if (!column) { - throw new Error('Expected Column'); - } - - const valueOptions = getColumnOptions(); - const error = getErrorMessage(); - - const classnames = classNames('condition-value-dropdown-container', { - 'show-error': error, - }); - - return ( -
- -
- ); - }; - - const renderErrorIcon = () => { - const error = getErrorMessage(); - return ( - error && ( -
- - - - - -
- ) - ); - }; - - return ( -
- {renderDeleteButton()} - {renderConnectorField()} - {renderColumnField()} - {renderOperatorField()} - {renderValueField()} - {renderErrorIcon()} -
- ); -}; - -export default Condition; diff --git a/src/features/query-bar/components/filter/FilterButton.js b/src/features/query-bar/components/filter/FilterButton.js deleted file mode 100644 index a0f9591a5c..0000000000 --- a/src/features/query-bar/components/filter/FilterButton.js +++ /dev/null @@ -1,357 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; -import uniqueId from 'lodash/uniqueId'; -import cloneDeep from 'lodash/cloneDeep'; - -import IconMetadataFilter from '../../../../icons/metadata-view/IconMetadataFilter'; -import Condition from './Condition'; -import Button from '../../../../components/button/Button'; -import PrimaryButton from '../../../../components/primary-button/PrimaryButton'; -import MenuToggle from '../../../../components/dropdown-menu/MenuToggle'; -import { Flyout, Overlay } from '../../../../components/flyout'; -import { AND, OR, COLUMN_OPERATORS } from '../../constants'; - -import messages from '../../messages'; - -import type { - ColumnType, - ConditionType, - ConditionValueType, - ConnectorType, - OperatorType, - OptionType, -} from '../../flowTypes'; - -type State = { - hasUserSubmitted: boolean, - isMenuOpen: boolean, - selectedConnector: ConnectorType, - transientConditions: Array, -}; - -type Props = { - columns?: Array, - conditions: Array, - onFilterChange?: Function, -}; - -class FilterButton extends React.Component { - constructor(props: Props) { - super(props); - - this.state = { - hasUserSubmitted: false, - isMenuOpen: false, - selectedConnector: AND, - transientConditions: cloneDeep(this.props.conditions), - }; - } - - componentDidUpdate(prevProps: Props, prevState: State) { - const { columns, conditions } = this.props; - const { isMenuOpen, transientConditions } = this.state; - const { isMenuOpen: prevIsMenuOpen } = prevState; - const wasFlyoutOpened = isMenuOpen && !prevIsMenuOpen; - if (wasFlyoutOpened) { - const hasUnsavedConditions = transientConditions.length > 0; - const shouldSetInitialCondition = conditions.length === 0; - - if (!hasUnsavedConditions) { - if (shouldSetInitialCondition) { - const newConditions = columns && columns.length === 0 ? [] : [this.createCondition()]; - this.setState({ - transientConditions: newConditions, - }); - } else { - this.setState({ - transientConditions: cloneDeep(this.props.conditions), - }); - } - } - } - } - - onClose = () => { - this.setState({ - isMenuOpen: false, - }); - }; - - onOpen = () => { - this.setState({ isMenuOpen: true }); - }; - - toggleButton = () => { - this.setState({ isMenuOpen: !this.state.isMenuOpen }); - }; - - createCondition = () => { - const conditionID = uniqueId(); - const { columns } = this.props; - if (columns && columns.length > 0) { - const firstColumn = columns[0]; - const operator = COLUMN_OPERATORS[firstColumn.type][0].key; - - return { - columnId: firstColumn.id, - id: conditionID, - operator, - values: [], - }; - } - throw new Error('Columns Required'); - }; - - addFilter = () => { - const newCondition = this.createCondition(); - this.setState({ - transientConditions: [...this.state.transientConditions, newCondition], - hasUserSubmitted: false, - }); - }; - - applyFilters = () => { - const { onFilterChange } = this.props; - const { transientConditions } = this.state; - - const areAllValid = this.areAllValid(); - - if (areAllValid) { - if (onFilterChange) { - onFilterChange(transientConditions); - } - this.setState({ - isMenuOpen: false, - transientConditions: [], - hasUserSubmitted: false, - }); - } else { - this.setState({ - hasUserSubmitted: true, - }); - } - }; - - updateConditionState = (conditionId: string, updateCondition: Function) => { - const { transientConditions } = this.state; - let newConditionIndex = 0; - const conditionToUpdate = transientConditions.find((currentCondition, index) => { - newConditionIndex = index; - return currentCondition.id === conditionId; - }); - - let newCondition = { ...conditionToUpdate }; - newCondition = updateCondition(newCondition); - - const newConditions = cloneDeep(transientConditions); - newConditions[newConditionIndex] = newCondition; - - this.setState({ - transientConditions: newConditions, - }); - }; - - handleColumnChange = (condition: ConditionType, columnId: string) => { - const { columns } = this.props; - const { transientConditions } = this.state; - let newConditionIndex = 0; - const conditionToUpdate = transientConditions.find((currentCondition, index) => { - newConditionIndex = index; - return currentCondition.id === condition.id; - }); - - const column = columns && columns.find(c => c.id === columnId); - if (!column) { - throw new Error('Invalid Column.id'); - } - - const type = column && column.type; - - const operator = COLUMN_OPERATORS[type][0].key; - - const newCondition = { - ...conditionToUpdate, - columnId, - operator, - values: [], - }; - - const newConditions = cloneDeep(transientConditions); - newConditions[newConditionIndex] = newCondition; - - this.setState({ - transientConditions: newConditions, - }); - }; - - handleOperatorChange = (conditionId: string, value: OperatorType) => { - this.updateConditionState(conditionId, condition => { - condition.operator = value; - return condition; - }); - }; - - handleValueChange = (conditionId: string, values: Array) => { - this.updateConditionState(conditionId, condition => { - condition.values = values; - return condition; - }); - }; - - handleConnectorChange = (option: OptionType) => { - const convert = str => { - switch (str) { - case AND: - return AND; - case OR: - return OR; - default: - throw new Error('Invalid connector'); - } - }; - - this.setState({ - selectedConnector: convert(option.value), - }); - }; - - deleteCondition = (index: number) => { - const { transientConditions } = this.state; - - const conditionsAfterDeletion = transientConditions.filter((condition, conditionIndex) => { - return conditionIndex !== index; - }); - - this.setState({ - transientConditions: conditionsAfterDeletion, - }); - }; - - areAllValid = () => { - const { transientConditions } = this.state; - let areAllValid = true; - transientConditions.forEach(condition => { - if (condition.values.length === 0) { - areAllValid = false; - } - }); - return areAllValid; - }; - - // Should close when all the conditions have a value set and the apply button is pressed. - shouldClose = (event?: SyntheticEvent<>) => { - // The current approach assumes that the Apply button contains at most one child element. - const areAllValid = this.areAllValid(); - - if (event && event.target && areAllValid) { - if ( - (event.target: window.HTMLButtonElement).classList.contains('apply-filters-button') || - (event.target: window.HTMLSpanElement).parentNode.classList.contains('apply-filters-button') - ) { - return true; - } - } - return false; - }; - - render() { - const { columns, conditions } = this.props; - const { transientConditions, hasUserSubmitted, isMenuOpen, selectedConnector } = this.state; - - const numberOfConditions = conditions.length; - const areAllValid = this.areAllValid(); - - const buttonClasses = classNames( - 'query-bar-button', - numberOfConditions !== 0 && areAllValid ? 'is-active' : '', - ); - - const isFilterDisabled = !columns || columns.length === 0; - - return ( - - - - - {isMenuOpen ? ( -
-
- {transientConditions.length === 0 ? ( - - ) : null} - {transientConditions.map((condition, index) => { - return ( - - ); - })} -
-
- - - - - -
-
- ) : ( -
- )} - - - ); - } -} - -export default FilterButton; diff --git a/src/features/query-bar/components/filter/ValueField.js b/src/features/query-bar/components/filter/ValueField.js deleted file mode 100644 index 4189530377..0000000000 --- a/src/features/query-bar/components/filter/ValueField.js +++ /dev/null @@ -1,118 +0,0 @@ -// @flow -import * as React from 'react'; -import { FormattedMessage } from 'react-intl'; -import isNaN from 'lodash/isNaN'; - -import DatePicker from '../../../../components/date-picker'; -import SingleSelectField from '../../../../components/select-field/SingleSelectField'; -import MultiSelectField from '../../../../components/select-field/MultiSelectField'; -import TextInput from '../../../../components/text-input'; -import { DATE, ENUM, FLOAT, MULTI_SELECT, NUMBER, STRING, VALUE } from '../../constants'; -import messages from '../../messages'; -import type { ConditionValueType } from '../../flowTypes'; - -import '../../styles/Condition.scss'; - -type Props = { - error?: React.Node, - onChange: (value: Array) => void, - selectedValues: Array, - valueOptions: Array, - valueType: string, -}; - -const getDateValue = selectedValues => { - if (selectedValues.length === 0 || selectedValues[0] === null) { - return undefined; - } - - const value = selectedValues[0]; - const date = new Date(value); - if (!isNaN(date.valueOf())) { - return date; - } - - throw new Error('Expected Date'); -}; - -const getStringValue = selectedValues => { - if (selectedValues.length === 0) { - return undefined; - } - - const value = selectedValues[0]; - if (typeof value === 'string') { - return value !== '' ? value : null; - } - - throw new Error('Expected string'); -}; - -const ValueField = ({ error, onChange, selectedValues, valueOptions, valueType }: Props) => { - const value = selectedValues.length > 0 ? selectedValues[0] : ''; - const onInputChange = e => { - return e.target.value !== '' ? onChange([e.target.value]) : onChange([]); - }; - - switch (valueType) { - case STRING: - case NUMBER: - case FLOAT: - return ( -
- -
- ); - case DATE: - return ( -
- onChange([date])} - placeholder="Date" - value={getDateValue(selectedValues)} - /> -
- ); - case ENUM: - return ( - onChange([e.value])} - options={valueOptions} - placeholder={} - selectedValue={getStringValue(selectedValues)} - /> - ); - case MULTI_SELECT: - return ( - onChange(e.map(option => option.value))} - options={valueOptions} - placeholder={} - selectedValues={selectedValues} - /> - ); - default: - return null; - } -}; - -export default ValueField; diff --git a/src/features/query-bar/components/fixtures.js b/src/features/query-bar/components/fixtures.js deleted file mode 100644 index a3c8a2b968..0000000000 --- a/src/features/query-bar/components/fixtures.js +++ /dev/null @@ -1,521 +0,0 @@ -// @flow -import type { ColumnType } from '../flowTypes'; - -export const columnForItemName: ColumnType = { - displayName: 'Name', - id: '1', - isShown: true, - property: 'name', - source: 'item', - type: 'string', -}; - -export const columnForItemLastUpdated: ColumnType = { - displayName: 'Last Updated', - id: '2', - isShown: true, - property: 'lastUpdatedByName', - source: 'item', - type: 'date', -}; - -export const columnWithEnumType: ColumnType = { - displayName: 'Contract Value', - id: '3', - isShown: true, - property: 'contractValue', - source: 'metadata', - type: 'enum', - options: [ - { - id: '', - key: '$100', - }, - ], -}; - -export const columnForDateType: ColumnType = { - displayName: 'Expire Date', - id: '4', - isShown: true, - property: 'expireDate', - source: 'metadata', - type: 'date', -}; - -export const columnWithMultiEnumType: ColumnType = { - displayName: 'Offices', - id: '5', - isShown: true, - property: 'offices', - source: 'metadata', - type: 'multi-enum', - options: [ - { - id: '', - key: 'Office A', - }, - { - id: '1', - key: 'Office B', - }, - ], -}; - -export const columnWithFloatType: ColumnType = { - displayName: 'Count', - id: '6', - isShown: true, - property: 'count', - source: 'metadata', - type: 'float', -}; - -export const columnForTemplateFieldName = { - displayName: 'Name', - id: '7', - isShown: true, - property: 'name', - source: 'metadata', - type: 'string', -}; - -export const columnWithNumberType: ColumnType = { - displayName: 'Assets', - id: '8', - isShown: true, - property: 'assets', - source: 'metadata', - type: 'number', -}; - -const metadataColumns: Array = [columnWithEnumType, columnWithMultiEnumType]; - -const expectedVisibleColumns = { - visibleColumns: [ - { - displayName: 'Size', - id: 'item_27', - key: 'size', - type: 'integer', - }, - { - displayName: 'Vendor Name', - id: 'item_28', - key: 'vendor name', - type: 'string', - }, - { - displayName: 'Updated', - id: 'item_26', - key: 'updated', - type: 'enum', - }, - { - displayName: 'Contract Value', - id: 'item_29', - key: 'contract value', - type: 'enum', - }, - { - displayName: 'Expiration Month', - id: 'item_30', - key: 'expiration month', - type: 'enum', - }, - { - displayName: 'Country', - id: 'item_31', - key: 'country', - type: 'string', - }, - { - displayName: 'State', - id: 'item_32', - key: 'state', - type: 'string', - }, - { - displayName: 'Function', - id: 'item_33', - key: 'function', - type: 'string', - }, - ], -}; - -const expectedVisibleColumnsOneHidden = { - visibleColumns: [ - { - displayName: 'Size', - id: 'item_27', - key: 'size', - type: 'integer', - }, - { - displayName: 'Vendor Name', - id: 'item_28', - key: 'vendor name', - type: 'string', - }, - { - displayName: 'Updated', - id: 'item_26', - key: 'updated', - type: 'enum', - }, - { - displayName: 'Contract Value', - id: 'item_29', - key: 'contract value', - type: 'enum', - }, - { - displayName: 'Expiration Month', - id: 'item_30', - key: 'expiration month', - type: 'enum', - }, - { - displayName: 'Country', - id: 'item_31', - key: 'country', - type: 'string', - }, - { - displayName: 'State', - id: 'item_32', - key: 'state', - type: 'string', - }, - ], -}; - -const visibleColumnsOneHidden = [ - { - id: 'item_27', - isChecked: true, - label: 'Size', - key: 'size', - displayName: 'Size', - }, - { - id: 'item_28', - isChecked: true, - label: 'Vendor Name', - key: 'vendor name', - displayName: 'Vendor Name', - }, - { - id: 'item_26', - isChecked: true, - label: 'Updated', - key: 'updated', - displayName: 'Updated', - }, - { - id: 'item_29', - isChecked: true, - label: 'Contract Value', - key: 'contract value', - displayName: 'Contract Value', - }, - { - id: 'item_30', - isChecked: true, - label: 'Expiration Month', - key: 'expiration month', - displayName: 'Expiration Month', - }, - { - id: 'item_31', - isChecked: true, - label: 'Country', - key: 'country', - displayName: 'Country', - }, - { - id: 'item_32', - isChecked: true, - label: 'State', - key: 'state', - displayName: 'State', - }, - { - id: 'item_33', - isChecked: false, - label: 'Function', - key: 'function', - displayName: 'Function', - }, -]; - -const visibleColumnsAfterMount = { - visibleColumns: [ - { - displayName: 'Size', - id: 'item_27', - key: 'size', - type: 'integer', - }, - { - displayName: 'Vendor Name', - id: 'item_28', - key: 'vendor name', - type: 'string', - }, - { - displayName: 'Updated', - id: 'item_26', - key: 'updated', - type: 'enum', - }, - { - displayName: 'Contract Value', - id: 'item_29', - key: 'contract value', - type: 'enum', - }, - { - displayName: 'Expiration Month', - id: 'item_30', - key: 'expiration month', - type: 'enum', - }, - { - displayName: 'Country', - id: 'item_31', - key: 'country', - type: 'string', - }, - { - displayName: 'State', - id: 'item_32', - key: 'state', - type: 'string', - }, - ], - widths: { - size: 0.14285714285714285, - 'vendor name': 0.14285714285714285, - updated: 0.14285714285714285, - 'contract value': 0.14285714285714285, - 'expiration month': 0.14285714285714285, - country: 0.14285714285714285, - state: 0.14285714285714285, - }, -}; - -const template = { - id: 'template1', - templateKey: 'template1', - displayName: 'template1 title', - scope: 'enterprise_123', - 'Vendor Name': { - operators: ['is', 'is greater than', 'is less than', 'is not', 'is blank', 'matches any'], - values: ['Google', 'Apple', 'Facebook'], - }, - 'Expiration Month': { - operators: ['is', 'is greater than', 'is less than', 'is not'], - values: ['August 2018', 'September 2018', 'October 2018'], - }, - 'File Type': { - operators: ['is', 'is not'], - values: ['.docx', '.mp3', 'mp4'], - }, - fields: [ - { - id: 'item_27', - type: 'float', - key: 'size', - displayName: 'Size', - }, - { - id: 'item_28', - type: 'string', - key: 'vendor name', - displayName: 'Vendor Name', - }, - { - id: 'item_26', - type: 'enum', - key: 'updated', - displayName: 'Updated', - options: [{ key: 'Now' }, { key: 'Tomorrow' }, { key: 'Yesterday' }, { key: 'Never' }], - }, - { - id: 'item_29', - type: 'enum', - key: 'contract value', - displayName: 'Contract Value', - options: [{ key: '$100' }, { key: '$2000' }, { key: '$10000' }, { key: '$200000' }], - }, - { - id: 'item_30', - type: 'enum', - key: 'expiration month', - displayName: 'Expiration Month', - options: [{ key: 'January' }, { key: 'February' }, { key: 'April' }, { key: 'May' }], - }, - { - id: 'item_31', - type: 'string', - key: 'country', - displayName: 'Country', - }, - { - id: 'item_32', - type: 'date', - key: 'Submission', - displayName: 'Submission', - }, - { - id: 'item_33', - type: 'string', - key: 'function', - displayName: 'Function', - }, - ], - filesList: [{ name: '1' }, { name: '2' }, { name: '3' }], - templateName: 'Vendor Contracts', -}; - -const instances = [ - { - canEdit: true, - id: 'editor1', - data: { - contractValue: 3, - fileType: 'pdf', - name: 'google', - lastModified: '2018-06-20T00:00:00.000Z', - size: 1, - }, - cascadePolicy: { - canEdit: true, - isEnabled: false, - id: 'some cascading policy id', - }, - }, - { - canEdit: true, - id: 'editor2', - data: { - contractValue: 34, - fileType: 'powerpoint-presentation', - name: 'facebook', - lastModified: '2018-06-20T00:00:00.000Z', - size: 12, - }, - cascadePolicy: { - canEdit: true, - isEnabled: false, - id: 'some cascading policy id', - }, - }, - { - canEdit: true, - id: 'editor3', - data: { - contractValue: 5, - fileType: 'video', - name: 'amazon', - lastModified: '2018-06-20T00:00:00.000Z', - size: 45, - }, - cascadePolicy: { - canEdit: true, - isEnabled: false, - id: 'some cascading policy id', - }, - }, -]; - -const metadataViewProps = { - totalWidth: 700, - tableHeight: 300, - tableHeaderHeight: 40, - tableRowHeight: 50, - widths: { - icon: 0.1, - name: 0.4, - lastModified: 0.6, - size: 0.3, - contractValue: 0.3, - }, -}; - -const metadataTableStateAfterMount = { - visibleColumns: [ - { - displayName: 'Size', - id: 'item_27', - key: 'size', - type: 'integer', - }, - { - displayName: 'Vendor Name', - id: 'item_28', - key: 'vendor name', - type: 'string', - }, - { - displayName: 'Updated', - id: 'item_26', - key: 'updated', - type: 'enum', - }, - { - displayName: 'Contract Value', - id: 'item_29', - key: 'contract value', - type: 'enum', - }, - { - displayName: 'Expiration Month', - id: 'item_30', - key: 'expiration month', - type: 'enum', - }, - { - displayName: 'Country', - id: 'item_31', - key: 'country', - type: 'string', - }, - { - displayName: 'State', - id: 'item_32', - key: 'state', - type: 'string', - }, - { - displayName: 'Function', - id: 'item_33', - key: 'function', - type: 'string', - }, - ], - widths: { - size: 0.125, - 'vendor name': 0.125, - updated: 0.125, - 'contract value': 0.125, - 'expiration month': 0.125, - country: 0.125, - state: 0.125, - function: 0.125, - }, -}; - -export { - metadataColumns, - expectedVisibleColumns, - visibleColumnsOneHidden, - expectedVisibleColumnsOneHidden, - visibleColumnsAfterMount, - template, - instances, - metadataViewProps, - metadataTableStateAfterMount, -}; diff --git a/src/features/query-bar/constants.js b/src/features/query-bar/constants.js deleted file mode 100644 index 4f75ae139b..0000000000 --- a/src/features/query-bar/constants.js +++ /dev/null @@ -1,48 +0,0 @@ -// @flow - -export const AND: 'AND' = 'AND'; -export const OR: 'OR' = 'OR'; -export const EMPTY_CONNECTOR: 'EMPTY_CONNECTOR' = 'EMPTY_CONNECTOR'; -export const COLUMN: 'column' = 'column'; -export const COLUMN_ID: 'columnId' = 'columnId'; -export const OPERATOR: 'operator' = 'operator'; -export const OPERATOR_DISPLAY_TEXT: 'operatorDisplayText' = 'operatorDisplayText'; -export const OPERATOR_KEY: 'operatorKey' = 'operatorKey'; -export const VALUE: 'value' = 'value'; -export const VALUES: 'values' = 'values'; -export const VALUE_DISPLAY_TEXT: 'valueDisplayText' = 'valueDisplayText'; -export const VALUE_KEY: 'valueKey' = 'valueKey'; -export const WHERE: 'WHERE' = 'WHERE'; - -export const STRING: 'string' = 'string'; -export const NUMBER: 'number' = 'number'; -export const FLOAT: 'float' = 'float'; -export const ENUM: 'enum' = 'enum'; -export const MULTI_SELECT: 'multiSelect' = 'multiSelect'; -export const DATE: 'date' = 'date'; - -export const EQUALS: '=' = '='; -export const NOT_EQUALS: '<>' = '<>'; -export const GREATER_THAN: '>' = '>'; -export const LESS_THAN: '<' = '<'; - -export const SORT_ORDER_ASCENDING: 'ASC' = 'ASC'; -export const SORT_ORDER_DESCENDING: 'DESC' = 'DESC'; - -export const OPERATORS = { - EQUALS: { displayText: 'is', key: EQUALS }, - NOT_EQUALS: { displayText: 'is not', key: NOT_EQUALS }, - GREATER_THAN: { displayText: 'is greater than', key: GREATER_THAN }, - LESS_THAN: { displayText: 'is less than', key: LESS_THAN }, -}; - -export const ALL_OPERATORS = [OPERATORS.EQUALS, OPERATORS.NOT_EQUALS, OPERATORS.GREATER_THAN, OPERATORS.LESS_THAN]; - -export const COLUMN_OPERATORS = { - string: ALL_OPERATORS, - number: ALL_OPERATORS, - float: ALL_OPERATORS, - enum: ALL_OPERATORS, - date: ALL_OPERATORS, - multiSelect: ALL_OPERATORS, -}; diff --git a/src/features/query-bar/flowTypes.js b/src/features/query-bar/flowTypes.js deleted file mode 100644 index fa0c721e85..0000000000 --- a/src/features/query-bar/flowTypes.js +++ /dev/null @@ -1,51 +0,0 @@ -// @flow -import { - AND, - EQUALS, - GREATER_THAN, - LESS_THAN, - NOT_EQUALS, - OR, - EMPTY_CONNECTOR, - SORT_ORDER_ASCENDING, - SORT_ORDER_DESCENDING, -} from './constants'; - -export type ConnectorType = typeof AND | typeof OR | typeof EMPTY_CONNECTOR; - -export type OperatorType = typeof EQUALS | typeof NOT_EQUALS | typeof GREATER_THAN | typeof LESS_THAN; - -export type SortOrderType = typeof SORT_ORDER_ASCENDING | typeof SORT_ORDER_DESCENDING; - -export type OptionType = { - displayText: string, - id: string, - type?: string, - value: string, -}; - -export type OperatorOptionType = { - displayText: string, - value: OperatorType, -}; - -export type ColumnType = { - direction?: ?SortOrderType, - displayName: string, - id: string, - isShown: boolean, - options?: Array | null, // TODO: ColumnOptionsType - Array - property: string, - source: string, - templateKey?: string, - type: string, -}; - -export type ConditionValueType = string | number | Date; - -export type ConditionType = { - columnId: string, - id: string, - operator: OperatorType, - values: Array, -}; diff --git a/src/features/query-bar/index.js b/src/features/query-bar/index.js deleted file mode 100644 index bfa0be15a3..0000000000 --- a/src/features/query-bar/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './QueryBar'; diff --git a/src/features/query-bar/messages.js b/src/features/query-bar/messages.js deleted file mode 100644 index e169aa831d..0000000000 --- a/src/features/query-bar/messages.js +++ /dev/null @@ -1,112 +0,0 @@ -// @flow -import { defineMessages } from 'react-intl'; - -const messages = defineMessages({ - tooltipEnterValueError: { - defaultMessage: 'Please Enter a Value', - description: 'Text displayed on the Tooltip for an input field', - id: 'boxui.queryBar.tooltipEnterValueError', - }, - tooltipInvalidFloatError: { - defaultMessage: 'Please Enter a Decimal Number', - description: 'Text displayed on the Tooltip for an input field of type float', - id: 'boxui.queryBar.tooltipInvalidFloatError', - }, - tooltipInvalidNumberError: { - defaultMessage: 'Please Enter an Integer', - description: 'Text displayed on the Tooltip for an input field of type number', - id: 'boxui.queryBar.tooltipInvalidNumberError', - }, - tooltipSelectValueError: { - defaultMessage: 'Please Select a Value', - description: 'Text displayed on the Tooltip for a value field', - id: 'boxui.queryBar.tooltipSelectValueError', - }, - tooltipSelectDateError: { - defaultMessage: 'Please Select a Date', - description: 'Text displayed on the Tooltip for a date field', - id: 'boxui.queryBar.tooltipSelectDateError', - }, - metadataViewTemplateListHeaderTitle: { - defaultMessage: 'METADATA TEMPLATES', - description: 'Header text shown in template dropdown', - id: 'boxui.queryBar.metadataViewTemplateListHeaderTitle', - }, - selectValuePlaceholderText: { - defaultMessage: 'Select value', - description: 'Placeholder text on the value button, on click should open a dropdown', - id: 'boxui.queryBar.selectValuePlaceholderText', - }, - connectorWhereText: { - defaultMessage: 'WHERE', - description: 'Text on the label, the first condition will show WHERE', - id: 'boxui.queryBar.connectorWhereText', - }, - connectorAndText: { - defaultMessage: 'AND', - description: 'Text on the connector dropdown, on click should open a dropdown showing either AND or OR', - id: 'boxui.queryBar.connectorAndText', - }, - connectorOrText: { - defaultMessage: 'OR', - description: 'Text on the connector dropdown, on click should open a dropdown showing either AND or OR', - id: 'boxui.queryBar.connectorOrText', - }, - addFilterButtonText: { - defaultMessage: '+ Add Filter', - description: 'Text on the add filter button, on click generates another filter row', - id: 'boxui.queryBar.addFilterButtonText', - }, - applyFiltersButtonText: { - defaultMessage: 'Apply', - description: 'Text on the apply filter button, on click applies the filters', - id: 'boxui.queryBar.applyFiltersButtonText', - }, - templatesLoadingButtonText: { - defaultMessage: 'Template Name', - description: 'Text on the templates button when templates are still being loaded', - id: 'boxui.queryBar.templatesLoadingButtonText', - }, - noTemplatesText: { - defaultMessage: 'No Templates Available', - description: - 'Text on the templates button when templates have been loaded and there are no templates in the enterprise', - id: 'boxui.queryBar.noTemplatesText', - }, - templatesButtonText: { - defaultMessage: 'Select Metadata', - description: - 'Text on the templates button, on click opens a menu which allows users to select a metadata templates', - id: 'boxui.queryBar.templatesButtonText', - }, - filtersButtonText: { - defaultMessage: 'Modify Filters', - description: 'Text on the filters button, on click opens a menu which allows users to filter through the files', - id: 'boxui.queryBar.filtersButtonText', - }, - multipleFiltersButtonText: { - defaultMessage: '{number} Filters', - description: - 'Text on the filters button, will display a number in front of the filters text indicating how many filters are applied', - id: 'boxui.queryBar.multipleFiltersButtonText', - }, - noFiltersAppliedText: { - defaultMessage: 'No Filters Applied', - description: 'Text on the filters dropdown that is displayed when no filters have been inserted', - id: 'boxui.queryBar.noFiltersAppliedText', - }, - columnsButtonText: { - defaultMessage: 'Columns', - description: - 'Text on the columns button, on click opens a menu which allows users to choose which columns to render', - id: 'boxui.queryBar.columnsButtonText', - }, - columnsHiddenButtonText: { - defaultMessage: '{count, plural, one {1 Column Hidden} other {{count} Columns Hidden}}', - description: - 'Text on the columns button, if one or more columns have been hidden then it will display this text', - id: 'boxui.queryBar.columnsHiddenButtonText', - }, -}); - -export default messages; diff --git a/src/features/query-bar/styles/Condition.scss b/src/features/query-bar/styles/Condition.scss deleted file mode 100644 index 97acd8ff61..0000000000 --- a/src/features/query-bar/styles/Condition.scss +++ /dev/null @@ -1,194 +0,0 @@ -@import '../../../styles/variables'; - -@mixin dropdown-input { - position: auto; - width: 160px; - height: 34px; - margin: auto; - margin-top: auto; - padding: 8px; - border: 1px solid #d2d2d2; - border-radius: $bdl-border-radius-size-med; - box-shadow: 0 1px 1px 1px rgb(0 0 0 / 5%); -} - -@mixin error-border { - border: 1px solid $bdl-watermelon-red; -} - -.condition-container { - display: flex; - flex-direction: row; - width: 100%; - height: 100%; - padding-bottom: 10px; - - .condition-delete-button { - display: flex; - align-items: center; - width: 35px; - - .delete-button { - position: relative; - display: flex; - padding-top: 0; - padding-bottom: 0; - padding-left: 10px; - color: $bdl-gray-50; - font-weight: bold; - font-size: 11px; - background: none; - border: 0; - cursor: pointer; - } - } - - .condition-connector { - display: flex; - align-items: center; - width: 70px; - padding-right: 70px; - padding-left: 10px; - - .condition-connector-text { - position: relative; - margin: auto; - color: $black; - } - } - - .condition-column-dropdown-container { - align-items: center; - - .filter-dropdown-single-select-field-container { - flex: 1; - } - - .select-field { - .bdl-SelectButton, - .select-button { - width: 160px; - border-radius: $bdl-border-radius-size-med; - } - - .bdl-SelectButton.placeholder, - .select-button.placeholder { - color: $bdl-gray-65; - } - } - } - - .condition-operator-dropdown-container { - align-items: center; - - .filter-dropdown-single-select-field-container { - flex: 1; - } - - .select-container { - width: 110px; - padding-right: 10px; - padding-left: 10px; - - .bdl-SelectButton, - .select-button { - border-radius: $bdl-border-radius-size-med; - } - } - } - - .condition-value-dropdown-container { - align-items: center; - height: 100%; - padding-right: 5px; - - .filter-dropdown-text-field-container { - flex: 1; - - .text-input-container { - margin: auto; - } - - input { - @include dropdown-input; - } - } - - .filter-dropdown-date-field-container { - flex: 1; - - .date-picker-wrapper { - margin: auto; - } - - .date-picker-wrapper .date-picker-icon-holder { - width: 100%; - } - - .text-input-container { - margin: auto; - } - - input { - @include dropdown-input; - } - } - - .filter-dropdown-single-select-field-container { - flex: 1; - } - - .select-container { - width: 100%; - - .bdl-SelectButton, - .select-button { - width: 160px; - border-radius: $bdl-border-radius-size-med; - } - - .bdl-SelectButton.placeholder, - .select-button.placeholder { - color: $bdl-gray-65; - } - } - } - - .condition-value-dropdown-container.show-error { - .select-container { - button.bdl-SelectButton, - button.select-button { - @include error-border; - } - } - - .filter-dropdown-text-field-container { - .text-input-container input { - @include error-border; - } - } - - .date-picker-wrapper input { - @include error-border; - } - - .bdl-SelectButton.placeholder, - .select-button.placeholder { - @include error-border; - } - } - - .condition-error-icon-status { - display: flex; - align-items: center; - - .icon-alert-default { - display: block; - margin: 0 auto; - - use:nth-child(2) { - fill: $bdl-watermelon-red; - } - } - } -} diff --git a/src/features/query-bar/styles/QueryBarButtons.scss b/src/features/query-bar/styles/QueryBarButtons.scss deleted file mode 100644 index a753054a3c..0000000000 --- a/src/features/query-bar/styles/QueryBarButtons.scss +++ /dev/null @@ -1,155 +0,0 @@ -@import '../../../styles/variables'; - -$query-bar-button-width: 240px; - -@mixin activeButton { - color: $bdl-box-blue; - font-weight: bold; - border: 1px solid $bdl-box-blue; - - .fill-color { - fill: $bdl-box-blue; - } - - path { - fill: $bdl-box-blue; - } -} - -@mixin dropdownFooter { - display: flex; - padding: 15px; - border-top: 1px solid $bdl-gray-10; -} - -.metadata-view-query-bar { - display: flex; - padding: 5px; - background: $bdl-gray-02; - border: 1px solid $bdl-gray-05; - border-radius: $bdl-border-radius-size; - - .button-container { - display: flex; - flex: 1; - - .button-icon { - width: 16px; - height: 16px; - margin: 3px 10px 0 0; - } - } -} - -.query-bar-button { - width: $query-bar-button-width; - - &.is-active { - @include activeButton; - } - - .icon-caret-down { - margin-left: 4px; - } - - .button-label { - flex: 10; - padding-left: 5px; - overflow: hidden; - line-height: 20px; - letter-spacing: normal; - text-align: left; - text-overflow: ellipsis; - } - - .crawler.loading-indicator { - height: 10px; - } -} - -.flyout-overlay.query-bar-template-dropdown-flyout { - .overlay { - width: $query-bar-button-width; - } - - .metadata-instance-editor-template-message { - width: 100%; - } - - .template-dropdown-list-title { - display: flex; - padding-top: 5px; - padding-bottom: 0; - padding-left: 17px; - color: $bdl-gray-50; - font-size: 10px; - letter-spacing: 0.6px; - } - - .template-display-name { - padding-left: 5px; - } -} - -.flyout-overlay.query-bar-filter-dropdown-flyout { - &::before { - display: none; - } - - .overlay { - padding: 0; - } - - .filter-button-dropdown { - width: 625px; - - .filter-button-dropdown-header { - padding: 20px; - } - - .filter-button-dropdown-footer { - @include dropdownFooter; - - justify-content: space-between; - - .apply-filters-button { - color: $white; - background-color: $bdl-box-blue; - border: none; - border-radius: $bdl-border-radius-size-med; - } - } - } -} - -.flyout-overlay.query-bar-column-dropdown-flyout { - .overlay { - padding: 0; - } - - .column-button-dropdown { - .column-button-dropdown-header { - width: 100%; - height: 50%; - - .checkbox-container { - margin: inherit; - } - } - - .column-button-dropdown-footer { - @include dropdownFooter; - - justify-content: flex-end; - } - - .draggable-list-example { - width: $query-bar-button-width; - padding: 15px; - - .draggable-list { - padding-bottom: 10px; - } - } - } -}