@bento-core/query-bar 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +32 -0
- package/README.md +139 -0
- package/babel.config.json +21 -0
- package/dist/components/CheckboxFilter.js +40 -0
- package/dist/components/FilterMap.js +46 -0
- package/dist/components/SliderFilter.js +34 -0
- package/dist/generators/QueryBarGenerator.js +117 -0
- package/dist/generators/config.js +68 -0
- package/dist/generators/styles.js +114 -0
- package/dist/index.js +27 -0
- package/package.json +28 -0
- package/src/components/CheckboxFilter.js +46 -0
- package/src/components/FilterMap.js +34 -0
- package/src/components/SliderFilter.js +38 -0
- package/src/generators/QueryBarGenerator.js +178 -0
- package/src/generators/config.js +68 -0
- package/src/generators/styles.js +107 -0
- package/src/index.js +3 -0
package/DESIGN.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
This document describes the technical design behind this component. For actual usage, please see the [README.md](./README.md) in this folder.
|
|
4
|
+
|
|
5
|
+
# Details
|
|
6
|
+
|
|
7
|
+
## Bases
|
|
8
|
+
|
|
9
|
+
This component is based on the following:
|
|
10
|
+
|
|
11
|
+
- N/A – This is a custom component not based on a specific Material-UI component
|
|
12
|
+
|
|
13
|
+
## States
|
|
14
|
+
|
|
15
|
+
This component uses **local** states for:
|
|
16
|
+
|
|
17
|
+
- N/A – The component does not use local states
|
|
18
|
+
|
|
19
|
+
This component watches the **global** state for:
|
|
20
|
+
|
|
21
|
+
- The Dashboard Facet Sidebar State (`state->statusReducer->filterState`)
|
|
22
|
+
- The Local Find State (`state->localFind`) (`->upload` and `->autocomplete`)
|
|
23
|
+
|
|
24
|
+
> **Note**: This component does not modify the global state or the property mentioned above.
|
|
25
|
+
|
|
26
|
+
## Retrieval
|
|
27
|
+
|
|
28
|
+
The main component, `<QueryBar>` is generated through the `QueryBarGenerator()` function. See the main [README.md](./README.md) for more information. The sub-components found in [components](./src/components/) are not designed to be used outside of this component, but are retrieved via importing them directly. No documentation on using them directly is provided.
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
The default configuration object is defined in [config.js](./src/Generators/config.js). To override and customize the component, you must provide the new configuration object to the `QueryBarGenerator()` function. **You do not need to override every option** only overriden options will be used.
|
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
|
|
3
|
+
This package provides the Query Bar component that displays the current Facet Search and Local Find filters on the Dashboard/Explore page. It also provides the direct ability to reset all or some of the filters with the click of a button. It is designed to be implemented directly with the:
|
|
4
|
+
|
|
5
|
+
- `@bento-core/local-find`
|
|
6
|
+
- `@bento-core/facet-filter`
|
|
7
|
+
|
|
8
|
+
packages. For the component's technical details, please see [DESIGN.md](./DESIGN.md).
|
|
9
|
+
|
|
10
|
+
See below for usage instructions.
|
|
11
|
+
|
|
12
|
+
# Usage
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
<details>
|
|
17
|
+
<summary>Basic Usage</summary>
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
import { QueryBarGenerator } from '@bento-core/query-bar';
|
|
21
|
+
|
|
22
|
+
// Generate the component
|
|
23
|
+
const { QueryBar } = QueryBarGenerator({
|
|
24
|
+
/** See Generator Options **/
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Use the component (e.g. In dashTemplateView.js)
|
|
28
|
+
const Layout = (props) => {
|
|
29
|
+
return (
|
|
30
|
+
{/* other components */}
|
|
31
|
+
<div className={classes.rightContent}>
|
|
32
|
+
<div className={classes.widgetsContainer}>
|
|
33
|
+
{/* other components */}
|
|
34
|
+
|
|
35
|
+
<QueryBar />
|
|
36
|
+
|
|
37
|
+
{/* other components */}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
{/* other components */}
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</details>
|
|
46
|
+
|
|
47
|
+
## Generator Configuration
|
|
48
|
+
|
|
49
|
+
See the available `DEFAULT_CONFIG_QUERYBAR` object to understand the component generator options. You can choose to override `config`, and/or `functions`. You DO NOT need to override all of the options if you don't want to. The component generator will only use the options you provide.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
const CONFIG = {
|
|
53
|
+
/* General Component Configuration */
|
|
54
|
+
config: {
|
|
55
|
+
/**
|
|
56
|
+
* The maximum number of items to display in a query bar facet section
|
|
57
|
+
* @var {number}
|
|
58
|
+
*/
|
|
59
|
+
maxItems: 2,
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/* Component Helper Functions */
|
|
63
|
+
functions: {
|
|
64
|
+
/**
|
|
65
|
+
* Clear all active facet/local find filters
|
|
66
|
+
*
|
|
67
|
+
* @returns {void}
|
|
68
|
+
*/
|
|
69
|
+
clearAll: () => {},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Clear all active Local Find file upload filters
|
|
73
|
+
*
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
76
|
+
clearUpload: () => {},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Clear all active Local Find searchbox filters
|
|
80
|
+
*
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
clearAutocomplete: () => {},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Delete a specific Local Find searchbox filter (case)
|
|
87
|
+
*
|
|
88
|
+
* @param {string} title
|
|
89
|
+
* @returns {void}
|
|
90
|
+
*/
|
|
91
|
+
deleteAutocompleteItem: (title) => {},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Reset a specific facet section (e.g. Program)
|
|
95
|
+
*
|
|
96
|
+
* @param {object} section the configuration object for the section
|
|
97
|
+
* @returns {void}
|
|
98
|
+
*/
|
|
99
|
+
resetFacetSection: (section) => {},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Reset a specific facet checkbox (e.g. Program > TAILORx)
|
|
103
|
+
*
|
|
104
|
+
* @param {object} section the configuration object for the section
|
|
105
|
+
* @param {string} checkbox the name of the checkbox
|
|
106
|
+
* @returns {void}
|
|
107
|
+
*/
|
|
108
|
+
resetFacetCheckbox: (section, checkbox) => {},
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Reset a specific slider section (e.g. Age)
|
|
112
|
+
*
|
|
113
|
+
* @param {object} section the configuration object for the section
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
resetFacetSlider: (section) => {},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
# Exports
|
|
122
|
+
|
|
123
|
+
This component exports the following components and objects by default. You may use them as necessary.
|
|
124
|
+
|
|
125
|
+
- `QueryBarGenerator` - The component generator function
|
|
126
|
+
- `DEFAULT_CONFIG_QUERYBAR` - The default configuration object
|
|
127
|
+
- `DEFAULT_STYLES_QUERYBAR` – The default Material UI styles
|
|
128
|
+
|
|
129
|
+
# Props
|
|
130
|
+
|
|
131
|
+
This component, which is generated by the provided generator, accepts the following props directly. The default value is specified, along with the possible values. The `classes` prop will override the default styling for any provided classes.
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
<QueryBar
|
|
135
|
+
statusReducer={undefined} // {object} - The status reducer object with the section `facetsConfig` combined
|
|
136
|
+
localFind={undefined} // {object} - The local find reducer object (Not modified)
|
|
137
|
+
classes={undefined} // {object} - The Material UI classes object. Overrides default styling for provided classes.
|
|
138
|
+
/>
|
|
139
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
[
|
|
4
|
+
"@babel/env",
|
|
5
|
+
{
|
|
6
|
+
"targets": {
|
|
7
|
+
"edge": "17",
|
|
8
|
+
"firefox": "60",
|
|
9
|
+
"chrome": "67",
|
|
10
|
+
"safari": "11.1"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"@babel/preset-react"
|
|
15
|
+
],
|
|
16
|
+
"plugins": [
|
|
17
|
+
"@babel/plugin-transform-react-jsx",
|
|
18
|
+
"@babel/plugin-syntax-jsx",
|
|
19
|
+
"@babel/plugin-proposal-class-properties"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _clsx = _interopRequireDefault(require("clsx"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
var _default = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
index,
|
|
13
|
+
data,
|
|
14
|
+
classes,
|
|
15
|
+
maxItems,
|
|
16
|
+
onSectionClick,
|
|
17
|
+
onItemClick
|
|
18
|
+
} = _ref;
|
|
19
|
+
const {
|
|
20
|
+
items,
|
|
21
|
+
section
|
|
22
|
+
} = data;
|
|
23
|
+
return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement("span", null, ' ', index !== 0 ? /*#__PURE__*/_react.default.createElement("span", {
|
|
24
|
+
className: classes.operators
|
|
25
|
+
}, " AND ") : '', /*#__PURE__*/_react.default.createElement("span", {
|
|
26
|
+
className: (0, _clsx.default)(classes.filterName, classes["facetSection".concat(section, "Background")]),
|
|
27
|
+
onClick: () => onSectionClick(data)
|
|
28
|
+
}, data.label), ' '), /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
29
|
+
className: classes.operators
|
|
30
|
+
}, items.length === 1 ? 'IS ' : 'IN '), items.length > 1 && /*#__PURE__*/_react.default.createElement("span", {
|
|
31
|
+
className: classes.bracketsOpen
|
|
32
|
+
}, "("), items.slice(0, maxItems).map((d, idx) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
33
|
+
className: (0, _clsx.default)(classes.filterCheckboxes, classes["facetSection".concat(section)]),
|
|
34
|
+
key: idx,
|
|
35
|
+
onClick: () => onItemClick(data, d)
|
|
36
|
+
}, d), idx === maxItems - 1 ? null : ' ')), items.length > maxItems && '...', items.length > 1 && /*#__PURE__*/_react.default.createElement("span", {
|
|
37
|
+
className: classes.bracketsClose
|
|
38
|
+
}, ")")));
|
|
39
|
+
};
|
|
40
|
+
exports.default = _default;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Filter = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _CheckboxFilter = _interopRequireDefault(require("./CheckboxFilter"));
|
|
9
|
+
var _SliderFilter = _interopRequireDefault(require("./SliderFilter"));
|
|
10
|
+
const _excluded = ["type"];
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
13
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
14
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
15
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
16
|
+
const DEFAULT_FILTER_MAP = {
|
|
17
|
+
checkbox: _CheckboxFilter.default,
|
|
18
|
+
slider: _SliderFilter.default
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This is a helper component to wrap the Filter component
|
|
23
|
+
*
|
|
24
|
+
* Note: If the filter component type is unknown,
|
|
25
|
+
* a placeholder component will be rendered instead
|
|
26
|
+
*
|
|
27
|
+
* @param {object} props
|
|
28
|
+
* @param {string} props.type - The type of component to render
|
|
29
|
+
* @returns {JSX.Element} - The component to render
|
|
30
|
+
*/
|
|
31
|
+
const Filter = _ref => {
|
|
32
|
+
let {
|
|
33
|
+
type
|
|
34
|
+
} = _ref,
|
|
35
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
36
|
+
// Default to the default card map
|
|
37
|
+
if (typeof DEFAULT_FILTER_MAP[type] !== 'undefined') {
|
|
38
|
+
return /*#__PURE__*/(0, _react.createElement)(DEFAULT_FILTER_MAP[type], props);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Render a placeholder component
|
|
42
|
+
return /*#__PURE__*/(0, _react.createElement)(() => /*#__PURE__*/_react.default.createElement("div", null, "The component for ".concat(type, " was not found.")));
|
|
43
|
+
};
|
|
44
|
+
exports.Filter = Filter;
|
|
45
|
+
var _default = Filter;
|
|
46
|
+
exports.default = _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _clsx = _interopRequireDefault(require("clsx"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
var _default = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
index,
|
|
13
|
+
data,
|
|
14
|
+
classes,
|
|
15
|
+
onSectionClick,
|
|
16
|
+
onItemClick
|
|
17
|
+
} = _ref;
|
|
18
|
+
const {
|
|
19
|
+
items,
|
|
20
|
+
section
|
|
21
|
+
} = data;
|
|
22
|
+
return /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement("span", null, ' ', index !== 0 ? /*#__PURE__*/_react.default.createElement("span", {
|
|
23
|
+
className: classes.operators
|
|
24
|
+
}, " AND ") : '', /*#__PURE__*/_react.default.createElement("span", {
|
|
25
|
+
className: (0, _clsx.default)(classes.filterName, classes["facetSection".concat(section, "Background")]),
|
|
26
|
+
onClick: () => onSectionClick(data)
|
|
27
|
+
}, data.label), ' '), /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
28
|
+
className: classes.operators
|
|
29
|
+
}, "IS BETWEEN", ' '), /*#__PURE__*/_react.default.createElement("span", {
|
|
30
|
+
className: (0, _clsx.default)(classes.filterCheckboxes, classes["facetSection".concat(section)]),
|
|
31
|
+
onClick: () => onItemClick(data, items[0])
|
|
32
|
+
}, "".concat(items[0], " \u2013 ").concat(items[1]))));
|
|
33
|
+
};
|
|
34
|
+
exports.default = _default;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.QueryBarGenerator = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _core = require("@material-ui/core");
|
|
9
|
+
var _facetFilter = require("@bento-core/facet-filter");
|
|
10
|
+
var _clsx = _interopRequireDefault(require("clsx"));
|
|
11
|
+
var _FilterMap = require("../components/FilterMap");
|
|
12
|
+
var _styles = _interopRequireDefault(require("./styles"));
|
|
13
|
+
var _config = _interopRequireDefault(require("./config"));
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
16
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
19
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
+
/**
|
|
21
|
+
* Generate a pre-configured Explore Query Bar component
|
|
22
|
+
*
|
|
23
|
+
* @param {object} uiConfig the component configuration object
|
|
24
|
+
* @returns {object} { QueryBar }
|
|
25
|
+
*/
|
|
26
|
+
const QueryBarGenerator = function QueryBarGenerator() {
|
|
27
|
+
let uiConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _config.default;
|
|
28
|
+
const {
|
|
29
|
+
config,
|
|
30
|
+
functions
|
|
31
|
+
} = uiConfig;
|
|
32
|
+
const {
|
|
33
|
+
CHECKBOX
|
|
34
|
+
} = _facetFilter.InputTypes;
|
|
35
|
+
const maxItems = config && typeof config.maxItems === 'number' ? config.maxItems : _config.default.config.maxItems;
|
|
36
|
+
const clearAll = functions && typeof functions.clearAll === 'function' ? functions.clearAll : _config.default.functions.clearAll;
|
|
37
|
+
const clearUpload = functions && typeof functions.clearUpload === 'function' ? functions.clearUpload : _config.default.functions.clearUpload;
|
|
38
|
+
const clearAutocomplete = functions && typeof functions.clearAutocomplete === 'function' ? functions.clearAutocomplete : _config.default.functions.clearAutocomplete;
|
|
39
|
+
const deleteAutocompleteItem = functions && typeof functions.deleteAutocompleteItem === 'function' ? functions.deleteAutocompleteItem : _config.default.functions.deleteAutocompleteItem;
|
|
40
|
+
const resetFacetSection = functions && typeof functions.resetFacetSection === 'function' ? functions.resetFacetSection : _config.default.functions.resetFacetSection;
|
|
41
|
+
const resetFacetCheckbox = functions && typeof functions.resetFacetCheckbox === 'function' ? functions.resetFacetCheckbox : _config.default.functions.resetFacetCheckbox;
|
|
42
|
+
const resetFacetSlider = functions && typeof functions.resetFacetSlider === 'function' ? functions.resetFacetSlider : _config.default.functions.resetFacetSlider;
|
|
43
|
+
return {
|
|
44
|
+
QueryBar: (0, _core.withStyles)(_styles.default, {
|
|
45
|
+
withTheme: true
|
|
46
|
+
})(props => {
|
|
47
|
+
const {
|
|
48
|
+
statusReducer,
|
|
49
|
+
localFind,
|
|
50
|
+
classes
|
|
51
|
+
} = props;
|
|
52
|
+
const {
|
|
53
|
+
autocomplete,
|
|
54
|
+
upload
|
|
55
|
+
} = localFind;
|
|
56
|
+
|
|
57
|
+
// Remove any sections without checkboxes selected
|
|
58
|
+
const mappedInputs = statusReducer.filter(facet => facet.section && facet.type).map(facet => {
|
|
59
|
+
if (facet.type !== CHECKBOX) {
|
|
60
|
+
return facet;
|
|
61
|
+
}
|
|
62
|
+
const items = Object.keys(facet.items);
|
|
63
|
+
items.sort((a, b) => a.localeCompare(b));
|
|
64
|
+
return _objectSpread(_objectSpread({}, facet), {}, {
|
|
65
|
+
items
|
|
66
|
+
});
|
|
67
|
+
}).filter(facet => facet.items.length > 0);
|
|
68
|
+
if ((mappedInputs.length || autocomplete.length || upload.length) <= 0) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
72
|
+
className: classes.queryWrapper
|
|
73
|
+
}, /*#__PURE__*/_react.default.createElement(_core.Button, {
|
|
74
|
+
className: classes.clearQueryButton,
|
|
75
|
+
color: "primary",
|
|
76
|
+
variant: "outlined",
|
|
77
|
+
onClick: clearAll
|
|
78
|
+
}, "Clear Query"), /*#__PURE__*/_react.default.createElement("span", {
|
|
79
|
+
className: classes.divider
|
|
80
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
81
|
+
className: classes.queryContainer
|
|
82
|
+
}, autocomplete.length || upload.length ? /*#__PURE__*/_react.default.createElement("span", null, upload.length && !autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", {
|
|
83
|
+
className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFindBackground),
|
|
84
|
+
onClick: clearUpload
|
|
85
|
+
}, "INPUT CASE SET") : null, autocomplete.length ? /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
86
|
+
className: (0, _clsx.default)(classes.filterName, classes.localFindBackground),
|
|
87
|
+
onClick: clearAutocomplete
|
|
88
|
+
}, "Case IDs"), ' ', ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
89
|
+
className: classes.operators
|
|
90
|
+
}, autocomplete.length === 1 && !upload.length ? 'IS ' : 'IN ')) : null, /*#__PURE__*/_react.default.createElement("span", null, (upload.length > 0 ? 1 : 0) + autocomplete.length > 1 ? /*#__PURE__*/_react.default.createElement("span", {
|
|
91
|
+
className: classes.bracketsOpen
|
|
92
|
+
}, "(") : null, upload.length && autocomplete.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
93
|
+
className: (0, _clsx.default)(classes.filterCheckboxes, classes.localFind),
|
|
94
|
+
onClick: clearUpload
|
|
95
|
+
}, "INPUT CASE SET"), ' ') : null, autocomplete.slice(0, maxItems).map((d, idx) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
96
|
+
className: (0, _clsx.default)(classes.filterCheckboxes, classes.facetSectionCases),
|
|
97
|
+
key: idx,
|
|
98
|
+
onClick: () => deleteAutocompleteItem(d.title)
|
|
99
|
+
}, d.title), idx === maxItems - 1 ? null : ' ')), autocomplete.length > maxItems && '...', (upload.length > 0 ? 1 : 0) + autocomplete.length > 1 ? /*#__PURE__*/_react.default.createElement("span", {
|
|
100
|
+
className: classes.bracketsClose
|
|
101
|
+
}, ")") : null)) : null, (autocomplete.length || upload.length) && mappedInputs.length ? /*#__PURE__*/_react.default.createElement("span", {
|
|
102
|
+
className: classes.operators
|
|
103
|
+
}, " AND ") : null, mappedInputs.map((filter, index) => /*#__PURE__*/_react.default.createElement(_FilterMap.Filter, {
|
|
104
|
+
index: index,
|
|
105
|
+
type: filter.type,
|
|
106
|
+
data: filter,
|
|
107
|
+
maxItems: maxItems,
|
|
108
|
+
classes: classes,
|
|
109
|
+
onSectionClick: filter.type === CHECKBOX ? resetFacetSection : resetFacetSlider,
|
|
110
|
+
onItemClick: filter.type === CHECKBOX ? resetFacetCheckbox : resetFacetSlider
|
|
111
|
+
}))));
|
|
112
|
+
})
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
exports.QueryBarGenerator = QueryBarGenerator;
|
|
116
|
+
var _default = QueryBarGenerator;
|
|
117
|
+
exports.default = _default;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
/* eslint-disable no-unused-vars */
|
|
8
|
+
var _default = {
|
|
9
|
+
/* General Component Configuration */
|
|
10
|
+
config: {
|
|
11
|
+
/**
|
|
12
|
+
* The maximum number of items to display in a query bar facet section
|
|
13
|
+
* @var {number}
|
|
14
|
+
*/
|
|
15
|
+
maxItems: 2
|
|
16
|
+
},
|
|
17
|
+
/* Component Helper Functions */
|
|
18
|
+
functions: {
|
|
19
|
+
/**
|
|
20
|
+
* Clear all active facet/local find filters
|
|
21
|
+
*
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
clearAll: () => {},
|
|
25
|
+
/**
|
|
26
|
+
* Clear all active Local Find file upload filters
|
|
27
|
+
*
|
|
28
|
+
* @returns {void}
|
|
29
|
+
*/
|
|
30
|
+
clearUpload: () => {},
|
|
31
|
+
/**
|
|
32
|
+
* Clear all active Local Find searchbox filters
|
|
33
|
+
*
|
|
34
|
+
* @returns {void}
|
|
35
|
+
*/
|
|
36
|
+
clearAutocomplete: () => {},
|
|
37
|
+
/**
|
|
38
|
+
* Delete a specific Local Find searchbox filter (case)
|
|
39
|
+
*
|
|
40
|
+
* @param {string} title
|
|
41
|
+
* @returns {void}
|
|
42
|
+
*/
|
|
43
|
+
deleteAutocompleteItem: title => {},
|
|
44
|
+
/**
|
|
45
|
+
* Reset a specific facet section (e.g. Program)
|
|
46
|
+
*
|
|
47
|
+
* @param {object} section the configuration object for the section
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
resetFacetSection: section => {},
|
|
51
|
+
/**
|
|
52
|
+
* Reset a specific facet checkbox (e.g. Program > TAILORx)
|
|
53
|
+
*
|
|
54
|
+
* @param {object} section the configuration object for the section
|
|
55
|
+
* @param {string} checkbox the name of the checkbox
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
resetFacetCheckbox: (section, checkbox) => {},
|
|
59
|
+
/**
|
|
60
|
+
* Reset a specific slider section (e.g. Age)
|
|
61
|
+
*
|
|
62
|
+
* @param {object} section the configuration object for the section
|
|
63
|
+
* @returns {void}
|
|
64
|
+
*/
|
|
65
|
+
resetFacetSlider: section => {}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
exports.default = _default;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Generate the default styling for the component
|
|
9
|
+
*/
|
|
10
|
+
var _default = () => ({
|
|
11
|
+
queryWrapper: {
|
|
12
|
+
height: '120px',
|
|
13
|
+
backgroundColor: '#f1f1f1',
|
|
14
|
+
padding: '14px 14px 0px 35px',
|
|
15
|
+
overflowY: 'auto'
|
|
16
|
+
},
|
|
17
|
+
queryContainer: {
|
|
18
|
+
marginLeft: 7,
|
|
19
|
+
position: 'relative',
|
|
20
|
+
lineHeight: '2.4em',
|
|
21
|
+
letterSpacing: '0.5px',
|
|
22
|
+
fontFamily: 'Nunito',
|
|
23
|
+
fontSize: '14px',
|
|
24
|
+
color: '#0e3151'
|
|
25
|
+
},
|
|
26
|
+
filterName: {
|
|
27
|
+
textTransform: 'uppercase',
|
|
28
|
+
padding: '5px 6px 5px 7px',
|
|
29
|
+
borderRadius: 4,
|
|
30
|
+
fontSize: 12,
|
|
31
|
+
fontWeight: 600,
|
|
32
|
+
cursor: 'pointer'
|
|
33
|
+
},
|
|
34
|
+
filterCheckboxes: {
|
|
35
|
+
padding: '4px 7px 3px 6px',
|
|
36
|
+
borderRadius: 4,
|
|
37
|
+
fontSize: 12,
|
|
38
|
+
fontWeight: 600,
|
|
39
|
+
border: '0.75px solid #898989',
|
|
40
|
+
width: 'fit-content',
|
|
41
|
+
backgroundColor: '#fff',
|
|
42
|
+
cursor: 'pointer'
|
|
43
|
+
},
|
|
44
|
+
bracketsOpen: {
|
|
45
|
+
fontSize: 18,
|
|
46
|
+
fontFamily: 'Nunito Sans Semibold',
|
|
47
|
+
color: '#787878',
|
|
48
|
+
marginRight: 3,
|
|
49
|
+
fontWeight: 600
|
|
50
|
+
},
|
|
51
|
+
bracketsClose: {
|
|
52
|
+
fontSize: 18,
|
|
53
|
+
fontFamily: 'Nunito Sans Semibold',
|
|
54
|
+
color: '#787878',
|
|
55
|
+
marginLeft: 3,
|
|
56
|
+
fontWeight: 600
|
|
57
|
+
},
|
|
58
|
+
operators: {
|
|
59
|
+
color: '#646464',
|
|
60
|
+
marginLeft: '3px',
|
|
61
|
+
marginRight: '3px',
|
|
62
|
+
borderBottom: 'none',
|
|
63
|
+
textDecoration: 'none',
|
|
64
|
+
fontSize: 10,
|
|
65
|
+
fontWeight: 'bold'
|
|
66
|
+
},
|
|
67
|
+
clearQueryButton: {
|
|
68
|
+
margin: '1px',
|
|
69
|
+
marginLeft: -6,
|
|
70
|
+
fontWeight: 600,
|
|
71
|
+
fontSize: '13px',
|
|
72
|
+
color: '#fff',
|
|
73
|
+
borderRadius: '15px',
|
|
74
|
+
fontFamily: 'Nunito',
|
|
75
|
+
boxSizing: 'border-box',
|
|
76
|
+
backgroundColor: '#969696',
|
|
77
|
+
textTransform: 'capitalize',
|
|
78
|
+
border: '1px solid #B4B4B4',
|
|
79
|
+
padding: '1px 5px 0px 6px',
|
|
80
|
+
'&:hover': {
|
|
81
|
+
backgroundColor: '#969696'
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
divider: {
|
|
85
|
+
borderRight: '2px solid #969696',
|
|
86
|
+
marginLeft: 7
|
|
87
|
+
},
|
|
88
|
+
/* Custom Styling by Project */
|
|
89
|
+
localFind: {
|
|
90
|
+
color: '#10A075'
|
|
91
|
+
},
|
|
92
|
+
localFindBackground: {
|
|
93
|
+
backgroundColor: '#C0E9D7'
|
|
94
|
+
},
|
|
95
|
+
facetSectionCases: {
|
|
96
|
+
color: '#10A075'
|
|
97
|
+
},
|
|
98
|
+
facetSectionCasesBackground: {
|
|
99
|
+
backgroundColor: '#C0E9D7'
|
|
100
|
+
},
|
|
101
|
+
facetSectionFiles: {
|
|
102
|
+
color: '#E636E4'
|
|
103
|
+
},
|
|
104
|
+
facetSectionFilesBackground: {
|
|
105
|
+
backgroundColor: '#F5C3F1'
|
|
106
|
+
},
|
|
107
|
+
facetSectionSamples: {
|
|
108
|
+
color: '#10BEFF'
|
|
109
|
+
},
|
|
110
|
+
facetSectionSamplesBackground: {
|
|
111
|
+
backgroundColor: '#C3EAF5'
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
exports.default = _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "DEFAULT_CONFIG_QUERYBAR", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _config.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "DEFAULT_STYLES_QUERYBAR", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _styles.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "QueryBarGenerator", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _QueryBarGenerator.QueryBarGenerator;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
var _QueryBarGenerator = require("./generators/QueryBarGenerator");
|
|
25
|
+
var _styles = _interopRequireDefault(require("./generators/styles"));
|
|
26
|
+
var _config = _interopRequireDefault(require("./generators/config"));
|
|
27
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bento-core/query-bar",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "cross-env-shell rm -rf dist && NODE_ENV=production BABEL_ENV=es babel src --out-dir dist --copy-files",
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
+
},
|
|
10
|
+
"repository": "https://github.com/CBIIT/bento-frontend",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"@bento-core/facet-filter": "*",
|
|
16
|
+
"@material-ui/core": "^4.10.0",
|
|
17
|
+
"clsx": "*",
|
|
18
|
+
"react": "^17.0.2",
|
|
19
|
+
"react-dom": "^17.0.0",
|
|
20
|
+
"react-redux": "^7.2.1"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"lodash": "^4.17.20"
|
|
24
|
+
},
|
|
25
|
+
"author": "CTOS Bento Team",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"gitHead": "10ee9deeae6dd0f139ecb7a70afc4c96a4e33d74"
|
|
28
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
|
|
4
|
+
export default ({
|
|
5
|
+
index, data, classes, maxItems,
|
|
6
|
+
onSectionClick, onItemClick,
|
|
7
|
+
}) => {
|
|
8
|
+
const { items, section } = data;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<span>
|
|
12
|
+
<span>
|
|
13
|
+
{' '}
|
|
14
|
+
{index !== 0 ? <span className={classes.operators}> AND </span> : ''}
|
|
15
|
+
<span
|
|
16
|
+
className={clsx(classes.filterName, classes[`facetSection${section}Background`])}
|
|
17
|
+
onClick={() => onSectionClick(data)}
|
|
18
|
+
>
|
|
19
|
+
{data.label}
|
|
20
|
+
</span>
|
|
21
|
+
{' '}
|
|
22
|
+
</span>
|
|
23
|
+
<span>
|
|
24
|
+
{' '}
|
|
25
|
+
<span className={classes.operators}>
|
|
26
|
+
{items.length === 1 ? 'IS ' : 'IN '}
|
|
27
|
+
</span>
|
|
28
|
+
{items.length > 1 && <span className={classes.bracketsOpen}>(</span>}
|
|
29
|
+
{items.slice(0, maxItems).map((d, idx) => (
|
|
30
|
+
<>
|
|
31
|
+
<span
|
|
32
|
+
className={clsx(classes.filterCheckboxes, classes[`facetSection${section}`])}
|
|
33
|
+
key={idx}
|
|
34
|
+
onClick={() => onItemClick(data, d)}
|
|
35
|
+
>
|
|
36
|
+
{d}
|
|
37
|
+
</span>
|
|
38
|
+
{idx === (maxItems - 1) ? null : ' '}
|
|
39
|
+
</>
|
|
40
|
+
))}
|
|
41
|
+
{items.length > maxItems && '...'}
|
|
42
|
+
{items.length > 1 && <span className={classes.bracketsClose}>)</span>}
|
|
43
|
+
</span>
|
|
44
|
+
</span>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { createElement } from 'react';
|
|
2
|
+
import Checkbox from './CheckboxFilter';
|
|
3
|
+
import Slider from './SliderFilter';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_FILTER_MAP = {
|
|
6
|
+
checkbox: Checkbox,
|
|
7
|
+
slider: Slider,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This is a helper component to wrap the Filter component
|
|
12
|
+
*
|
|
13
|
+
* Note: If the filter component type is unknown,
|
|
14
|
+
* a placeholder component will be rendered instead
|
|
15
|
+
*
|
|
16
|
+
* @param {object} props
|
|
17
|
+
* @param {string} props.type - The type of component to render
|
|
18
|
+
* @returns {JSX.Element} - The component to render
|
|
19
|
+
*/
|
|
20
|
+
export const Filter = ({ type, ...props }) => {
|
|
21
|
+
// Default to the default card map
|
|
22
|
+
if (typeof DEFAULT_FILTER_MAP[type] !== 'undefined') {
|
|
23
|
+
return createElement(DEFAULT_FILTER_MAP[type], props);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Render a placeholder component
|
|
27
|
+
return createElement(() => (
|
|
28
|
+
<div>
|
|
29
|
+
{`The component for ${type} was not found.`}
|
|
30
|
+
</div>
|
|
31
|
+
));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default Filter;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
|
|
4
|
+
export default ({
|
|
5
|
+
index, data, classes,
|
|
6
|
+
onSectionClick, onItemClick,
|
|
7
|
+
}) => {
|
|
8
|
+
const { items, section } = data;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<span>
|
|
12
|
+
<span>
|
|
13
|
+
{' '}
|
|
14
|
+
{index !== 0 ? <span className={classes.operators}> AND </span> : ''}
|
|
15
|
+
<span
|
|
16
|
+
className={clsx(classes.filterName, classes[`facetSection${section}Background`])}
|
|
17
|
+
onClick={() => onSectionClick(data)}
|
|
18
|
+
>
|
|
19
|
+
{data.label}
|
|
20
|
+
</span>
|
|
21
|
+
{' '}
|
|
22
|
+
</span>
|
|
23
|
+
<span>
|
|
24
|
+
{' '}
|
|
25
|
+
<span className={classes.operators}>
|
|
26
|
+
IS BETWEEN
|
|
27
|
+
{' '}
|
|
28
|
+
</span>
|
|
29
|
+
<span
|
|
30
|
+
className={clsx(classes.filterCheckboxes, classes[`facetSection${section}`])}
|
|
31
|
+
onClick={() => onItemClick(data, items[0])}
|
|
32
|
+
>
|
|
33
|
+
{`${items[0]} – ${items[1]}`}
|
|
34
|
+
</span>
|
|
35
|
+
</span>
|
|
36
|
+
</span>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { withStyles, Button } from '@material-ui/core';
|
|
3
|
+
import { InputTypes } from '@bento-core/facet-filter';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import { Filter } from '../components/FilterMap';
|
|
6
|
+
import DEFAULT_STYLES from './styles';
|
|
7
|
+
import DEFAULT_CONFIG from './config';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generate a pre-configured Explore Query Bar component
|
|
11
|
+
*
|
|
12
|
+
* @param {object} uiConfig the component configuration object
|
|
13
|
+
* @returns {object} { QueryBar }
|
|
14
|
+
*/
|
|
15
|
+
export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => {
|
|
16
|
+
const { config, functions } = uiConfig;
|
|
17
|
+
const { CHECKBOX } = InputTypes;
|
|
18
|
+
|
|
19
|
+
const maxItems = config && typeof config.maxItems === 'number'
|
|
20
|
+
? config.maxItems
|
|
21
|
+
: DEFAULT_CONFIG.config.maxItems;
|
|
22
|
+
|
|
23
|
+
const clearAll = functions && typeof functions.clearAll === 'function'
|
|
24
|
+
? functions.clearAll
|
|
25
|
+
: DEFAULT_CONFIG.functions.clearAll;
|
|
26
|
+
|
|
27
|
+
const clearUpload = functions && typeof functions.clearUpload === 'function'
|
|
28
|
+
? functions.clearUpload
|
|
29
|
+
: DEFAULT_CONFIG.functions.clearUpload;
|
|
30
|
+
|
|
31
|
+
const clearAutocomplete = functions && typeof functions.clearAutocomplete === 'function'
|
|
32
|
+
? functions.clearAutocomplete
|
|
33
|
+
: DEFAULT_CONFIG.functions.clearAutocomplete;
|
|
34
|
+
|
|
35
|
+
const deleteAutocompleteItem = functions && typeof functions.deleteAutocompleteItem === 'function'
|
|
36
|
+
? functions.deleteAutocompleteItem
|
|
37
|
+
: DEFAULT_CONFIG.functions.deleteAutocompleteItem;
|
|
38
|
+
|
|
39
|
+
const resetFacetSection = functions && typeof functions.resetFacetSection === 'function'
|
|
40
|
+
? functions.resetFacetSection
|
|
41
|
+
: DEFAULT_CONFIG.functions.resetFacetSection;
|
|
42
|
+
|
|
43
|
+
const resetFacetCheckbox = functions && typeof functions.resetFacetCheckbox === 'function'
|
|
44
|
+
? functions.resetFacetCheckbox
|
|
45
|
+
: DEFAULT_CONFIG.functions.resetFacetCheckbox;
|
|
46
|
+
|
|
47
|
+
const resetFacetSlider = functions && typeof functions.resetFacetSlider === 'function'
|
|
48
|
+
? functions.resetFacetSlider
|
|
49
|
+
: DEFAULT_CONFIG.functions.resetFacetSlider;
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
QueryBar: withStyles(DEFAULT_STYLES, { withTheme: true })((props) => {
|
|
53
|
+
const { statusReducer, localFind, classes } = props;
|
|
54
|
+
|
|
55
|
+
const { autocomplete, upload } = localFind;
|
|
56
|
+
|
|
57
|
+
// Remove any sections without checkboxes selected
|
|
58
|
+
const mappedInputs = statusReducer.filter((facet) => facet.section && facet.type)
|
|
59
|
+
.map((facet) => {
|
|
60
|
+
if (facet.type !== CHECKBOX) { return facet; }
|
|
61
|
+
|
|
62
|
+
const items = Object.keys(facet.items);
|
|
63
|
+
items.sort((a, b) => a.localeCompare(b));
|
|
64
|
+
|
|
65
|
+
return { ...facet, items };
|
|
66
|
+
})
|
|
67
|
+
.filter((facet) => facet.items.length > 0);
|
|
68
|
+
|
|
69
|
+
if ((mappedInputs.length || autocomplete.length || upload.length) <= 0) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className={classes.queryWrapper}>
|
|
75
|
+
<Button
|
|
76
|
+
className={classes.clearQueryButton}
|
|
77
|
+
color="primary"
|
|
78
|
+
variant="outlined"
|
|
79
|
+
onClick={clearAll}
|
|
80
|
+
>
|
|
81
|
+
Clear Query
|
|
82
|
+
</Button>
|
|
83
|
+
<span className={classes.divider} />
|
|
84
|
+
<span className={classes.queryContainer}>
|
|
85
|
+
{/* Local Find Selections */}
|
|
86
|
+
{/* TODO: Refactor this into a separate component */}
|
|
87
|
+
{(autocomplete.length || upload.length) ? (
|
|
88
|
+
<span>
|
|
89
|
+
{/* Standalone case set button */}
|
|
90
|
+
{(upload.length && !autocomplete.length)
|
|
91
|
+
? (
|
|
92
|
+
<span
|
|
93
|
+
className={clsx(classes.filterCheckboxes, classes.localFindBackground)}
|
|
94
|
+
onClick={clearUpload}
|
|
95
|
+
>
|
|
96
|
+
INPUT CASE SET
|
|
97
|
+
</span>
|
|
98
|
+
) : null}
|
|
99
|
+
{autocomplete.length
|
|
100
|
+
? (
|
|
101
|
+
<span>
|
|
102
|
+
{' '}
|
|
103
|
+
<span
|
|
104
|
+
className={clsx(classes.filterName, classes.localFindBackground)}
|
|
105
|
+
onClick={clearAutocomplete}
|
|
106
|
+
>
|
|
107
|
+
Case IDs
|
|
108
|
+
</span>
|
|
109
|
+
{' '}
|
|
110
|
+
{' '}
|
|
111
|
+
<span className={classes.operators}>
|
|
112
|
+
{(autocomplete.length === 1 && !upload.length) ? 'IS ' : 'IN '}
|
|
113
|
+
</span>
|
|
114
|
+
</span>
|
|
115
|
+
) : null}
|
|
116
|
+
<span>
|
|
117
|
+
{(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
|
|
118
|
+
? <span className={classes.bracketsOpen}>(</span>
|
|
119
|
+
: null}
|
|
120
|
+
{upload.length && autocomplete.length ? (
|
|
121
|
+
<>
|
|
122
|
+
{' '}
|
|
123
|
+
<span
|
|
124
|
+
className={clsx(classes.filterCheckboxes, classes.localFind)}
|
|
125
|
+
onClick={clearUpload}
|
|
126
|
+
>
|
|
127
|
+
INPUT CASE SET
|
|
128
|
+
</span>
|
|
129
|
+
{' '}
|
|
130
|
+
</>
|
|
131
|
+
) : null}
|
|
132
|
+
{autocomplete.slice(0, maxItems).map((d, idx) => (
|
|
133
|
+
<>
|
|
134
|
+
<span
|
|
135
|
+
className={clsx(classes.filterCheckboxes, classes.facetSectionCases)}
|
|
136
|
+
key={idx}
|
|
137
|
+
onClick={() => deleteAutocompleteItem(d.title)}
|
|
138
|
+
>
|
|
139
|
+
{d.title}
|
|
140
|
+
</span>
|
|
141
|
+
{idx === (maxItems - 1) ? null : ' '}
|
|
142
|
+
</>
|
|
143
|
+
))}
|
|
144
|
+
{autocomplete.length > maxItems && '...'}
|
|
145
|
+
{(((upload.length > 0 ? 1 : 0) + autocomplete.length) > 1)
|
|
146
|
+
? <span className={classes.bracketsClose}>)</span>
|
|
147
|
+
: null}
|
|
148
|
+
</span>
|
|
149
|
+
</span>
|
|
150
|
+
) : null}
|
|
151
|
+
|
|
152
|
+
{/* Facet Sidebar Selections */}
|
|
153
|
+
{((autocomplete.length || upload.length) && mappedInputs.length)
|
|
154
|
+
? <span className={classes.operators}> AND </span>
|
|
155
|
+
: null}
|
|
156
|
+
{mappedInputs.map((filter, index) => (
|
|
157
|
+
<Filter
|
|
158
|
+
index={index}
|
|
159
|
+
type={filter.type}
|
|
160
|
+
data={filter}
|
|
161
|
+
maxItems={maxItems}
|
|
162
|
+
classes={classes}
|
|
163
|
+
onSectionClick={filter.type === CHECKBOX
|
|
164
|
+
? resetFacetSection
|
|
165
|
+
: resetFacetSlider}
|
|
166
|
+
onItemClick={filter.type === CHECKBOX
|
|
167
|
+
? resetFacetCheckbox
|
|
168
|
+
: resetFacetSlider}
|
|
169
|
+
/>
|
|
170
|
+
))}
|
|
171
|
+
</span>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
}),
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export default QueryBarGenerator;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
export default {
|
|
3
|
+
/* General Component Configuration */
|
|
4
|
+
config: {
|
|
5
|
+
/**
|
|
6
|
+
* The maximum number of items to display in a query bar facet section
|
|
7
|
+
* @var {number}
|
|
8
|
+
*/
|
|
9
|
+
maxItems: 2,
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
/* Component Helper Functions */
|
|
13
|
+
functions: {
|
|
14
|
+
/**
|
|
15
|
+
* Clear all active facet/local find filters
|
|
16
|
+
*
|
|
17
|
+
* @returns {void}
|
|
18
|
+
*/
|
|
19
|
+
clearAll: () => {},
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Clear all active Local Find file upload filters
|
|
23
|
+
*
|
|
24
|
+
* @returns {void}
|
|
25
|
+
*/
|
|
26
|
+
clearUpload: () => {},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Clear all active Local Find searchbox filters
|
|
30
|
+
*
|
|
31
|
+
* @returns {void}
|
|
32
|
+
*/
|
|
33
|
+
clearAutocomplete: () => {},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Delete a specific Local Find searchbox filter (case)
|
|
37
|
+
*
|
|
38
|
+
* @param {string} title
|
|
39
|
+
* @returns {void}
|
|
40
|
+
*/
|
|
41
|
+
deleteAutocompleteItem: (title) => {},
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Reset a specific facet section (e.g. Program)
|
|
45
|
+
*
|
|
46
|
+
* @param {object} section the configuration object for the section
|
|
47
|
+
* @returns {void}
|
|
48
|
+
*/
|
|
49
|
+
resetFacetSection: (section) => {},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Reset a specific facet checkbox (e.g. Program > TAILORx)
|
|
53
|
+
*
|
|
54
|
+
* @param {object} section the configuration object for the section
|
|
55
|
+
* @param {string} checkbox the name of the checkbox
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
resetFacetCheckbox: (section, checkbox) => {},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Reset a specific slider section (e.g. Age)
|
|
62
|
+
*
|
|
63
|
+
* @param {object} section the configuration object for the section
|
|
64
|
+
* @returns {void}
|
|
65
|
+
*/
|
|
66
|
+
resetFacetSlider: (section) => {},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate the default styling for the component
|
|
3
|
+
*/
|
|
4
|
+
export default () => ({
|
|
5
|
+
queryWrapper: {
|
|
6
|
+
height: '120px',
|
|
7
|
+
backgroundColor: '#f1f1f1',
|
|
8
|
+
padding: '14px 14px 0px 35px',
|
|
9
|
+
overflowY: 'auto',
|
|
10
|
+
},
|
|
11
|
+
queryContainer: {
|
|
12
|
+
marginLeft: 7,
|
|
13
|
+
position: 'relative',
|
|
14
|
+
lineHeight: '2.4em',
|
|
15
|
+
letterSpacing: '0.5px',
|
|
16
|
+
fontFamily: 'Nunito',
|
|
17
|
+
fontSize: '14px',
|
|
18
|
+
color: '#0e3151',
|
|
19
|
+
},
|
|
20
|
+
filterName: {
|
|
21
|
+
textTransform: 'uppercase',
|
|
22
|
+
padding: '5px 6px 5px 7px',
|
|
23
|
+
borderRadius: 4,
|
|
24
|
+
fontSize: 12,
|
|
25
|
+
fontWeight: 600,
|
|
26
|
+
cursor: 'pointer',
|
|
27
|
+
},
|
|
28
|
+
filterCheckboxes: {
|
|
29
|
+
padding: '4px 7px 3px 6px',
|
|
30
|
+
borderRadius: 4,
|
|
31
|
+
fontSize: 12,
|
|
32
|
+
fontWeight: 600,
|
|
33
|
+
border: '0.75px solid #898989',
|
|
34
|
+
width: 'fit-content',
|
|
35
|
+
backgroundColor: '#fff',
|
|
36
|
+
cursor: 'pointer',
|
|
37
|
+
},
|
|
38
|
+
bracketsOpen: {
|
|
39
|
+
fontSize: 18,
|
|
40
|
+
fontFamily: 'Nunito Sans Semibold',
|
|
41
|
+
color: '#787878',
|
|
42
|
+
marginRight: 3,
|
|
43
|
+
fontWeight: 600,
|
|
44
|
+
},
|
|
45
|
+
bracketsClose: {
|
|
46
|
+
fontSize: 18,
|
|
47
|
+
fontFamily: 'Nunito Sans Semibold',
|
|
48
|
+
color: '#787878',
|
|
49
|
+
marginLeft: 3,
|
|
50
|
+
fontWeight: 600,
|
|
51
|
+
},
|
|
52
|
+
operators: {
|
|
53
|
+
color: '#646464',
|
|
54
|
+
marginLeft: '3px',
|
|
55
|
+
marginRight: '3px',
|
|
56
|
+
borderBottom: 'none',
|
|
57
|
+
textDecoration: 'none',
|
|
58
|
+
fontSize: 10,
|
|
59
|
+
fontWeight: 'bold',
|
|
60
|
+
},
|
|
61
|
+
clearQueryButton: {
|
|
62
|
+
margin: '1px',
|
|
63
|
+
marginLeft: -6,
|
|
64
|
+
fontWeight: 600,
|
|
65
|
+
fontSize: '13px',
|
|
66
|
+
color: '#fff',
|
|
67
|
+
borderRadius: '15px',
|
|
68
|
+
fontFamily: 'Nunito',
|
|
69
|
+
boxSizing: 'border-box',
|
|
70
|
+
backgroundColor: '#969696',
|
|
71
|
+
textTransform: 'capitalize',
|
|
72
|
+
border: '1px solid #B4B4B4',
|
|
73
|
+
padding: '1px 5px 0px 6px',
|
|
74
|
+
'&:hover': {
|
|
75
|
+
backgroundColor: '#969696',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
divider: {
|
|
79
|
+
borderRight: '2px solid #969696',
|
|
80
|
+
marginLeft: 7,
|
|
81
|
+
},
|
|
82
|
+
/* Custom Styling by Project */
|
|
83
|
+
localFind: {
|
|
84
|
+
color: '#10A075',
|
|
85
|
+
},
|
|
86
|
+
localFindBackground: {
|
|
87
|
+
backgroundColor: '#C0E9D7',
|
|
88
|
+
},
|
|
89
|
+
facetSectionCases: {
|
|
90
|
+
color: '#10A075',
|
|
91
|
+
},
|
|
92
|
+
facetSectionCasesBackground: {
|
|
93
|
+
backgroundColor: '#C0E9D7',
|
|
94
|
+
},
|
|
95
|
+
facetSectionFiles: {
|
|
96
|
+
color: '#E636E4',
|
|
97
|
+
},
|
|
98
|
+
facetSectionFilesBackground: {
|
|
99
|
+
backgroundColor: '#F5C3F1',
|
|
100
|
+
},
|
|
101
|
+
facetSectionSamples: {
|
|
102
|
+
color: '#10BEFF',
|
|
103
|
+
},
|
|
104
|
+
facetSectionSamplesBackground: {
|
|
105
|
+
backgroundColor: '#C3EAF5',
|
|
106
|
+
},
|
|
107
|
+
});
|
package/src/index.js
ADDED