-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Settings: Metric Configuration: Refactor & Clean Up (5/n) (#91)
* Major clean up - separate components into their own files * Fix dimension bug * Fix switch agency bug * Minor clean up * Merge types with existing types and update all connected components * Clean up * Handle cases when settings array is empty or non-existent * Handle cases when settings array is empty or non-existent * Styling adjustments per prev feedback * Recreate MetricsView Component for Data Visualization (#101) * Recreate old MetricsView component Update route and add to menu Update styling Remove unnecessary code - minor refactor Clean up * Fix styling issue * Add spacing between header and data viz * Add border top to data viz dropdown * Update tooltip and link to direct users to Settings to change metric config Co-authored-by: Mahmoud <mahmoud@Mahmouds-MBP.cable.rcn.com> Co-authored-by: Mahmoud <mahmoud@Mahmouds-MBP.cable.rcn.com>
- Loading branch information
Showing
16 changed files
with
946 additions
and
584 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
257 changes: 257 additions & 0 deletions
257
publisher/src/components/MetricConfiguration/Configuration.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,257 @@ | ||
// Recidiviz - a data platform for criminal justice reform | ||
// Copyright (C) 2022 Recidiviz, Inc. | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
// ============================================================================= | ||
|
||
import React, { useEffect, useState } from "react"; | ||
|
||
import { Metric, MetricDisaggregationDimensions } from "../../shared/types"; | ||
import { removeSnakeCase } from "../../utils"; | ||
import blueCheck from "../assets/status-check-icon.png"; | ||
import { BinaryRadioButton } from "../Forms"; | ||
import { TabbedBar, TabbedItem, TabbedOptions } from "../Reports"; | ||
import { | ||
BlueCheckIcon, | ||
BreakdownHeader, | ||
Checkbox, | ||
CheckboxWrapper, | ||
Dimension, | ||
DimensionTitle, | ||
DimensionTitleWrapper, | ||
Disaggregation, | ||
DisaggregationTab, | ||
Header, | ||
MetricConfigurationContainer, | ||
MetricDisaggregations, | ||
MetricOnOffWrapper, | ||
MetricSettings, | ||
RadioButtonGroupWrapper, | ||
Subheader, | ||
} from "."; | ||
|
||
type MetricConfigurationProps = { | ||
activeMetricKey: string; | ||
filteredMetricSettings: { [key: string]: Metric }; | ||
saveAndUpdateMetricSettings: ( | ||
typeOfUpdate: "METRIC" | "DISAGGREGATION" | "DIMENSION" | "CONTEXT", | ||
updatedSetting: MetricSettings, | ||
debounce?: boolean | ||
) => void; | ||
setActiveDimension: React.Dispatch< | ||
React.SetStateAction<MetricDisaggregationDimensions | undefined> | ||
>; | ||
}; | ||
|
||
export const Configuration: React.FC<MetricConfigurationProps> = ({ | ||
activeMetricKey, | ||
filteredMetricSettings, | ||
saveAndUpdateMetricSettings, | ||
setActiveDimension, | ||
}): JSX.Element => { | ||
const [activeDisaggregation, setActiveDisaggregation] = useState( | ||
filteredMetricSettings[activeMetricKey]?.disaggregations?.[0] | ||
); | ||
const metricDisplayName = | ||
filteredMetricSettings[activeMetricKey]?.display_name; | ||
const metricEnabled = Boolean( | ||
filteredMetricSettings[activeMetricKey]?.enabled | ||
); | ||
|
||
useEffect( | ||
() => { | ||
const updatedDisaggregation = | ||
activeDisaggregation && | ||
filteredMetricSettings[activeMetricKey]?.disaggregations?.find( | ||
(disaggregation) => disaggregation.key === activeDisaggregation.key | ||
); | ||
|
||
if (updatedDisaggregation) | ||
return setActiveDisaggregation(updatedDisaggregation); | ||
setActiveDisaggregation( | ||
filteredMetricSettings[activeMetricKey]?.disaggregations?.[0] | ||
); | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[filteredMetricSettings] | ||
); | ||
|
||
useEffect( | ||
() => setActiveDimension(undefined), | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[activeMetricKey] | ||
); | ||
|
||
return ( | ||
<MetricConfigurationContainer> | ||
<MetricOnOffWrapper> | ||
<Header> | ||
Are you currently able to report any part of this metric? | ||
</Header> | ||
<Subheader> | ||
Answering “No” means that {metricDisplayName} will not appear on | ||
automatically generated reports from here on out. You can change this | ||
later. | ||
</Subheader> | ||
<RadioButtonGroupWrapper> | ||
<BinaryRadioButton | ||
type="radio" | ||
id="yes" | ||
name="metric-config" | ||
label="Yes" | ||
value="yes" | ||
checked={metricEnabled} | ||
onChange={() => | ||
saveAndUpdateMetricSettings("METRIC", { | ||
key: activeMetricKey, | ||
enabled: true, | ||
}) | ||
} | ||
/> | ||
<BinaryRadioButton | ||
type="radio" | ||
id="no" | ||
name="metric-config" | ||
label="No" | ||
value="no" | ||
checked={!metricEnabled} | ||
onChange={() => | ||
saveAndUpdateMetricSettings("METRIC", { | ||
key: activeMetricKey, | ||
enabled: false, | ||
}) | ||
} | ||
/> | ||
</RadioButtonGroupWrapper> | ||
</MetricOnOffWrapper> | ||
|
||
{filteredMetricSettings[activeMetricKey]?.disaggregations.length > 0 && ( | ||
<MetricDisaggregations enabled={metricEnabled}> | ||
<BreakdownHeader>Breakdowns</BreakdownHeader> | ||
<Subheader> | ||
Mark (using the checkmark) each of the breakdowns below that your | ||
agency will be able to report. Click the arrow to edit the | ||
definition for each metric. | ||
</Subheader> | ||
|
||
<TabbedBar noPadding> | ||
<TabbedOptions> | ||
{activeDisaggregation && | ||
filteredMetricSettings[activeMetricKey]?.disaggregations?.map( | ||
(disaggregation) => ( | ||
<TabbedItem | ||
key={disaggregation.key} | ||
onClick={() => { | ||
setActiveDimension(disaggregation.dimensions[0]); | ||
setActiveDisaggregation(disaggregation); | ||
}} | ||
selected={disaggregation.key === activeDisaggregation.key} | ||
capitalize | ||
> | ||
<DisaggregationTab> | ||
<span> | ||
{removeSnakeCase( | ||
disaggregation.display_name.toLowerCase() | ||
)} | ||
</span> | ||
|
||
<CheckboxWrapper> | ||
<Checkbox | ||
type="checkbox" | ||
checked={disaggregation.enabled} | ||
onChange={() => | ||
saveAndUpdateMetricSettings("DISAGGREGATION", { | ||
key: activeMetricKey, | ||
disaggregations: [ | ||
{ | ||
key: disaggregation.key, | ||
enabled: !disaggregation.enabled, | ||
}, | ||
], | ||
}) | ||
} | ||
/> | ||
<BlueCheckIcon | ||
src={blueCheck} | ||
alt="" | ||
enabled={disaggregation.enabled} | ||
/> | ||
</CheckboxWrapper> | ||
</DisaggregationTab> | ||
</TabbedItem> | ||
) | ||
)} | ||
</TabbedOptions> | ||
</TabbedBar> | ||
|
||
<Disaggregation> | ||
{activeDisaggregation?.dimensions.map((dimension) => { | ||
return ( | ||
<Dimension | ||
key={dimension.key} | ||
enabled={!metricEnabled || activeDisaggregation.enabled} | ||
onClick={() => setActiveDimension(dimension)} | ||
> | ||
<CheckboxWrapper> | ||
<Checkbox | ||
type="checkbox" | ||
checked={ | ||
activeDisaggregation.enabled && dimension.enabled | ||
} | ||
onChange={() => { | ||
if (activeDisaggregation.enabled) { | ||
saveAndUpdateMetricSettings("DIMENSION", { | ||
key: activeMetricKey, | ||
disaggregations: [ | ||
{ | ||
key: activeDisaggregation.key, | ||
dimensions: [ | ||
{ | ||
key: dimension.key, | ||
enabled: !dimension.enabled, | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
} | ||
}} | ||
/> | ||
<BlueCheckIcon | ||
src={blueCheck} | ||
alt="" | ||
enabled={ | ||
activeDisaggregation.enabled && dimension.enabled | ||
} | ||
/> | ||
</CheckboxWrapper> | ||
|
||
<DimensionTitleWrapper> | ||
<DimensionTitle | ||
enabled={ | ||
activeDisaggregation.enabled && dimension.enabled | ||
} | ||
> | ||
{dimension.label} | ||
</DimensionTitle> | ||
</DimensionTitleWrapper> | ||
</Dimension> | ||
); | ||
})} | ||
</Disaggregation> | ||
</MetricDisaggregations> | ||
)} | ||
</MetricConfigurationContainer> | ||
); | ||
}; |
Oops, something went wrong.