Skip to content

Commit

Permalink
Merge pull request #508 from chicagopcdc/pcdc_dev
Browse files Browse the repository at this point in the history
Pcdc dev
  • Loading branch information
grugna authored May 30, 2023
2 parents e3657e1 + f5b8300 commit 071a31c
Show file tree
Hide file tree
Showing 9 changed files with 988 additions and 595 deletions.
1,451 changes: 886 additions & 565 deletions package-lock.json

Large diffs are not rendered by default.

46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
{
"name": "@pcdc/windmill",
"version": "1.15.0",
"version": "1.16.0",
"description": "PCDC Data Portal",
"dependencies": {
"@babel/core": "^7.21.8",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
"@babel/core": "^7.22.1",
"@babel/plugin-transform-runtime": "^7.22.4",
"@babel/preset-env": "^7.22.4",
"@babel/preset-react": "^7.22.3",
"@fontsource/raleway": "^4.5.12",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@hpcc-js/wasm": "^1.20.1",
"@reduxjs/toolkit": "^1.9.5",
"@svgr/webpack": "^6.5.1",
"ace-builds": "^1.18.0",
"ace-builds": "^1.22.0",
"acorn": "^8.8.2",
"autoprefixer": "^10.4.14",
"babel-loader": "^8.3.0",
"babel-plugin-relay": "^12.0.0",
"compression-webpack-plugin": "^10.0.0",
"core-js": "^3.30.1",
"css-loader": "^6.7.3",
"core-js": "^3.30.2",
"css-loader": "^6.8.1",
"d3-array": "^3.2.3",
"d3-ease": "^3.0.1",
"d3-force": "^3.0.0",
Expand All @@ -37,20 +37,20 @@
"fuse.js": "^6.6.2",
"graphiql": "^1.11.5",
"graphql": "^15.8.0",
"graphql-ws": "^5.12.1",
"graphql-ws": "^5.13.1",
"html-webpack-plugin": "^5.5.1",
"jszip": "^3.10.1",
"lodash.clonedeep": "^4.5.0",
"node-fetch": "^2.6.9",
"papaparse": "^5.4.1",
"pluralize": "^8.0.0",
"postcss": "^8.4.23",
"postcss-inline-svg": "^5.0.0",
"postcss-loader": "^7.3.0",
"postcss-svgo": "^5.1.0",
"postcss": "^8.4.24",
"postcss-inline-svg": "^6.0.0",
"postcss-loader": "^7.3.2",
"postcss-svgo": "^6.0.0",
"prop-types": "^15.8.1",
"rc-slider": "^10.1.1",
"rc-tooltip": "^5.3.1",
"rc-slider": "^10.2.0",
"rc-tooltip": "^6.0.1",
"react": "^17.0.2",
"react-ace": "^10.1.0",
"react-dom": "^17.0.2",
Expand All @@ -59,18 +59,18 @@
"react-redux": "^8.0.5",
"react-relay": "^12.0.0",
"react-resize-detector": "^7.1.2",
"react-router-dom": "^6.11.0",
"react-select": "^5.7.2",
"react-router-dom": "^6.11.2",
"react-select": "^5.7.3",
"react-select-async-paginate": "^0.6.2",
"react-switch": "^7.0.0",
"react-table": "^7.8.0",
"recharts": "^2.5.0",
"recharts": "^2.6.2",
"relay-compiler": "^12.0.0",
"relay-runtime": "^12.0.0",
"string-similarity": "^4.0.4",
"style-loader": "^3.3.2",
"webpack": "^5.81.0",
"webpack-cli": "^4.10.0"
"style-loader": "^3.3.3",
"webpack": "^5.84.1",
"webpack-cli": "^5.1.1"
},
"devDependencies": {
"@babel/eslint-parser": "^7.21.8",
Expand All @@ -88,7 +88,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.5.1",
"babel-jest": "^29.5.0",
"eslint": "^8.39.0",
"eslint": "^8.41.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
Expand All @@ -102,7 +102,7 @@
"react-refresh": "^0.13.0",
"react-test-renderer": "^17.0.2",
"stylelint": "^14.16.1",
"webpack-dev-server": "^4.13.3"
"webpack-dev-server": "^4.15.0"
},
"jest": {
"automock": false,
Expand Down
6 changes: 5 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ function App() {
<Route
path='explorer'
element={
<ProtectedContent preload={() => dispatch(fetchSurvivalConfig())}>
<ProtectedContent preload={() =>
Promise.all([
dispatch(fetchDictionary()),
dispatch(fetchSurvivalConfig())
])}>
<Explorer />
</ProtectedContent>
}
Expand Down
4 changes: 4 additions & 0 deletions src/GuppyComponents/ConnectedFilter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
* @property {(x: string[]) => void} [onPatientIdsChange]
* @property {string[]} [patientIds]
* @property {SimpleAggsData} tabsOptions
* @property {Array} dictionaryEntries
*/

/** @param {ConnectedFilterProps} props */
Expand All @@ -49,6 +50,7 @@ function ConnectedFilter({
onPatientIdsChange,
patientIds,
tabsOptions,
dictionaryEntries
}) {
if (
hidden ||
Expand All @@ -74,6 +76,7 @@ function ConnectedFilter({

const filterTabs = filterConfig.tabs.map(({ fields, searchFields }) =>
getFilterSections({
dictionaryEntries,
adminAppliedPreFilters,
arrayFields: arrayFields.current,
fields,
Expand Down Expand Up @@ -149,6 +152,7 @@ ConnectedFilter.propTypes = {
onPatientIdsChange: PropTypes.func,
patientIds: PropTypes.arrayOf(PropTypes.string),
tabsOptions: PropTypes.object.isRequired,
dictionaryEntries: PropTypes.array.isRequired
};

export default ConnectedFilter;
27 changes: 27 additions & 0 deletions src/GuppyComponents/Utils/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,28 @@ export const mergeTabOptions = (firstTabsOptions, secondTabsOptions) => {

/**
* @param {Object} args
* @param {string} [args.field]
* @param {Array} [args.dictionaryEntries]
*/
function findDictionaryEntryForField(field, dictionaryEntries) {
let foundEntry = dictionaryEntries.find((entry) => {
let { entryKey, sectionKey } = entry;
return field === entryKey || field === `${sectionKey}.${entryKey}`;
});
return foundEntry?.entryValue;
}

/**
* @param {Object} args
* @param {string} [args.field]
* @param {Array} [args.dictionaryEntries]
* @param {OptionFilter['selectedValues']} [args.adminAppliedPreFilterValues]
* @param {{ histogram: AggsCount[] }} args.histogramResult
* @param {{ histogram: AggsCount[] }} args.initialHistogramResult
*/
const getSingleFilterOption = ({
field,
dictionaryEntries,
adminAppliedPreFilterValues,
histogramResult,
initialHistogramResult,
Expand Down Expand Up @@ -274,7 +291,11 @@ const getSingleFilterOption = ({
count: item.count,
});
} else {
let entry = findDictionaryEntryForField(field, dictionaryEntries);
let enumDef = (entry?.enumDef || []).find((enumDefEntry) => enumDefEntry.enumeration === item.key);

options.push({
description: enumDef?.description,
text: item.key,
filterType: 'singleSelect',
count: item.count,
Expand Down Expand Up @@ -361,6 +382,7 @@ export const checkIsArrayField = (field, arrayFields) => {
* @param {SimpleAggsData} args.initialTabsOptions
* @param {string[]} args.searchFields
* @param {SimpleAggsData} args.tabsOptions
* @param {Array} args.dictionaryEntries
* @returns {import('../../gen3-ui-component/components/filters/types').FilterSectionConfig[]}
*/
export const getFilterSections = ({
Expand All @@ -372,6 +394,7 @@ export const getFilterSections = ({
initialTabsOptions,
searchFields,
tabsOptions,
dictionaryEntries
}) => {
let searchFieldSections = [];

Expand All @@ -396,6 +419,8 @@ export const getFilterSections = ({
let selectedOptions = [];
if (tabsOptionsFiltered && tabsOptionsFiltered.histogram) {
selectedOptions = getSingleFilterOption({
field,
dictionaryEntries,
adminAppliedPreFilterValues:
adminAppliedPreFilters[field]?.selectedValues,
histogramResult: tabsOptionsFiltered,
Expand Down Expand Up @@ -431,6 +456,8 @@ export const getFilterSections = ({
}

const defaultOptions = getSingleFilterOption({
field,
dictionaryEntries,
adminAppliedPreFilterValues:
adminAppliedPreFilters[field]?.selectedValues,
histogramResult: tabsOptionsFiltered,
Expand Down
2 changes: 2 additions & 0 deletions src/GuppyDataExplorer/ExplorerFilter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ DisabledExplorerFilter.propTypes = {
* @property {GuppyData['onFilterChange']} onFilterChange
* @property {GuppyData['onAnchorValueChange']} onAnchorValueChange
* @property {GuppyData['tabsOptions']} tabsOptions
* @property {Object} dictionaryEntries
*/

/** @param {ExplorerFilterProps} props */
Expand Down Expand Up @@ -96,6 +97,7 @@ ExplorerFilter.propTypes = {
onAnchorValueChange: PropTypes.func.isRequired, // from GuppyWrapper
onFilterChange: PropTypes.func.isRequired, // from GuppyWrapper
tabsOptions: PropTypes.object.isRequired, // from GuppWrapper
dictionaryEntries: PropTypes.array
};

export default ExplorerFilter;
24 changes: 21 additions & 3 deletions src/GuppyDataExplorer/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ import ExplorerVisualization from './ExplorerVisualization';
import ExplorerFilter, { DisabledExplorerFilter } from './ExplorerFilter';
import './Explorer.css';
import { FILTER_TYPE } from './ExplorerFilterSetWorkspace/utils';
import { useStore } from 'react-redux';

/** @typedef {import('../redux/types').RootState} RootState */
/** @typedef {import('./types').OptionFilter} OptionFilter */
/** @typedef {import('../redux/types').RootStore} RootStore */

/** @type {{ [x: string]: OptionFilter }} */
const emptyAdminAppliedPreFilters = {};

function ExplorerDashboard() {
/** @type {RootStore} */
const reduxStore = useStore();
const dispatch = useAppDispatch();
/** @param {RootState['explorer']['explorerFilter']} filter */
function handleFilterChange(filter) {
Expand Down Expand Up @@ -71,6 +75,19 @@ function ExplorerDashboard() {
window.removeEventListener('popstate', switchExplorerOnBrowserNavigation);
}, []);

const dict = reduxStore.getState().submission.dictionary;
const dictSections = dict ? Object.entries(dict) : [];

const dictionaryEntries = [];
for (let [sectionKey, sectionValue] of dictSections) {
if (sectionKey && !sectionKey.startsWith('_') && sectionValue?.hasOwnProperty('properties')) {
const dictEntries = Object.entries(sectionValue.properties);
for (let [entryKey, entryValue] of dictEntries) {
dictionaryEntries.push({ sectionKey, entryKey, entryValue });
}
}
}

return (
<GuppyWrapper
key={explorerId}
Expand All @@ -83,8 +100,8 @@ function ExplorerDashboard() {
rawDataFields={tableConfig.fields}
patientIds={patientIds}
>
{(data) => (
<Dashboard>
{(data) => {
return <Dashboard>
<Dashboard.Sidebar className='explorer__sidebar'>
<div>
<ExplorerSelect />
Expand All @@ -99,6 +116,7 @@ function ExplorerDashboard() {
onAnchorValueChange={data.onAnchorValueChange}
onFilterChange={data.onFilterChange}
tabsOptions={data.tabsOptions}
dictionaryEntries={dictionaryEntries}
/>
)}
</div>
Expand Down Expand Up @@ -139,7 +157,7 @@ function ExplorerDashboard() {
/>
</Dashboard.Main>
</Dashboard>
)}
}}
</GuppyWrapper>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ function FilterSection({
disabledTooltipMessage={disabledTooltipMessage}
hideZero={hideZero}
label={option.text}
optionTooltip={option.description}
lockedTooltipMessage={lockedTooltipMessage}
onSelect={handleSelectSingleSelectFilter}
selected={filterStatus[option.text]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import './SingleSelectFilter.css';
* @property {string} [disabledTooltipMessage]
* @property {number} [hideValue]
* @property {boolean} [hideZero]
* @property {string} label
* @property {string} [label]
* @property {string} [optionTooltip]
* @property {string} [lockedTooltipMessage]
* @property {(label: string) => void} onSelect
* @property {boolean} [selected]
Expand All @@ -26,6 +27,7 @@ function SingleSelectFilter({
hideValue = -1,
hideZero = true,
label,
optionTooltip,
lockedTooltipMessage = '',
onSelect,
selected,
Expand Down Expand Up @@ -103,8 +105,21 @@ function SingleSelectFilter({
onChange={handleCheck}
checked={isChecked}
disabled={inputDisabled}
/>
<span className='g3-single-select-filter__label'>{label}</span>
/>
<span className='g3-single-select-filter__label'>
{
optionTooltip ?
<Tooltip
placement='right'
overlay={<span>{optionTooltip}</span>}
arrowContent={<div className='rc-tooltip-arrow-inner' />}
trigger={['hover', 'focus']}
>
<span>{label}</span>
</Tooltip> :
label
}
</span>
{count !== null && countIconComponent}
{lockIconComponent}
</div>
Expand All @@ -119,6 +134,7 @@ SingleSelectFilter.propTypes = {
hideValue: PropTypes.number,
hideZero: PropTypes.bool,
label: PropTypes.string.isRequired,
optionTooltip: PropTypes.string,
lockedTooltipMessage: PropTypes.string,
onSelect: PropTypes.func.isRequired,
selected: PropTypes.bool,
Expand Down

0 comments on commit 071a31c

Please sign in to comment.