Skip to content

Commit

Permalink
measurements: Add URL query param m_groupBy
Browse files Browse the repository at this point in the history
Use query param `m_groupBy` to specify which group by field to use
in the measurements panel. If it is not one of the collection's
groupings, then the query param will be ignored and removed.
  • Loading branch information
joverlee521 committed Sep 9, 2024
1 parent 6d99b29 commit 1ad12c4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 45 deletions.
91 changes: 57 additions & 34 deletions src/actions/measurements.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
APPLY_MEASUREMENTS_FILTER,
CHANGE_MEASUREMENTS_COLLECTION,
CHANGE_MEASUREMENTS_DISPLAY,
CHANGE_MEASUREMENTS_GROUP_BY,
LOAD_MEASUREMENTS,
TOGGLE_MEASUREMENTS_OVERALL_MEAN,
TOGGLE_MEASUREMENTS_THRESHOLD,
Expand Down Expand Up @@ -48,30 +49,32 @@ function getCollectionDefaultControl(controlKey, collection) {
}
const collectionDefaults = collection["display_defaults"] || {};
const displayDefaultKey = collectionControlToDisplayDefaults[controlKey];
const defaultControl = collectionDefaults[displayDefaultKey];
let defaultControl = collectionDefaults[displayDefaultKey];
// Check default is a valid value for the control key
if (defaultControl !== undefined) {
switch (controlKey) {
case 'measurementsGroupBy':
if (!collection.fields.has(defaultControl)) {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be one of collection's fields`)
defaultControl = undefined;
}
break;
case 'measurementsDisplay':
const expectedValues = ["mean", "raw"];
if (!expectedValues.includes(defaultControl)) {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be one of ${expectedValues}`)
defaultControl = undefined;
switch (controlKey) {
case 'measurementsGroupBy':
if (defaultControl === undefined || !collection.groupings.has(defaultControl)) {
if (defaultControl !== undefined) {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be one of collection's groupings. Using first grouping as default`)
}
break;
case 'measurementsShowOverallMean':
if (typeof defaultControl !== "boolean") {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be a boolean`)
defaultControl = undefined;
}
break;
case 'measurementsShowThreshold':
defaultControl = collection.groupings.keys().next().value;
}
break;
case 'measurementsDisplay':
const expectedValues = ["mean", "raw"];
if (defaultControl !== undefined && !expectedValues.includes(defaultControl)) {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be one of ${expectedValues}`)
defaultControl = undefined;
}
break;
case 'measurementsShowOverallMean':
if (defaultControl !== undefined && typeof defaultControl !== "boolean") {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be a boolean`)
defaultControl = undefined;
}
break;
case 'measurementsShowThreshold':
if (defaultControl !== undefined) {
if (!Array.isArray(collection.thresholds) ||
!collection.thresholds.some((threshold) => typeof threshold === "number")) {
console.error(`Ignoring ${displayDefaultKey} value because collection does not have valid thresholds`)
Expand All @@ -80,13 +83,13 @@ function getCollectionDefaultControl(controlKey, collection) {
console.error(`Ignoring invalid ${displayDefaultKey} value ${defaultControl}, must be a boolean`)
defaultControl = undefined;
}
break;
case 'measurementsFilters':
console.debug(`Skipping control key ${controlKey} because it does not have default controls`);
break;
default:
console.error(`Skipping unknown control key ${controlKey}`);
}
}
break;
case 'measurementsFilters':
console.debug(`Skipping control key ${controlKey} because it does not have default controls`);
break;
default:
console.error(`Skipping unknown control key ${controlKey}`);
}
return defaultControl;
}
Expand All @@ -104,10 +107,10 @@ function getCollectionDefaultControl(controlKey, collection) {
const getCollectionDisplayControls = (controls, collection) => {
// Copy current control options for measurements
const newControls = pick(controls, Object.keys(defaultMeasurementsControlState));
// Checks the current group by is available as a field in collection
if (!collection.fields.has(newControls.measurementsGroupBy)) {
// If current group by is not available as a field, then default to the first grouping option.
[newControls.measurementsGroupBy] = collection.groupings.keys();
// Checks the current group by is available as a grouping in collection
// If it doesn't exist, set to undefined so it will get filled in with collection's default
if (!collection.groupings.has(newControls.measurementsGroupBy)) {
newControls.measurementsGroupBy = undefined
}

// Verify that current filters are valid for the new collection
Expand Down Expand Up @@ -364,8 +367,21 @@ export const changeMeasurementsDisplay = (newDisplay) => (dispatch, getState) =>
});
}

export const changeMeasurementsGroupBy = (newGroupBy) => (dispatch, getState) => {
const { controls, measurements } = getState();
const controlKey = "measurementsGroupBy";
const newControls = { [controlKey]: newGroupBy };

dispatch({
type: CHANGE_MEASUREMENTS_GROUP_BY,
controls: newControls,
queryParams: createMeasurementsQueryFromControls(newControls, measurements.collectionToDisplay)
});
}

const controlToQueryParamMap = {
measurementsDisplay: "m_display",
measurementsGroupBy: "m_groupBy",
measurementsShowOverallMean: "m_overallMean",
measurementsShowThreshold: "m_threshold",
};
Expand All @@ -381,7 +397,8 @@ function createMeasurementsQueryFromControls(measurementControls, collection) {
newQuery[queryKey] = "";
} else {
switch(controlKey) {
case "measurementsDisplay":
case "measurementsDisplay": // fallthrough
case "measurementsGroupBy":
newQuery[queryKey] = controlValue;
break;
case "measurementsShowOverallMean":
Expand Down Expand Up @@ -414,6 +431,12 @@ export function createMeasurementsControlsFromQuery(query){
expectedValues = ["mean", "raw"];
conversionFn = () => queryValue;
break;
case "m_groupBy":
// Accept any value here because we cannot validate the query before
// the measurements JSON is loaded
expectedValues = [queryValue];
conversionFn = () => queryValue;
break;
case "m_overallMean": // fallthrough
case "m_threshold":
expectedValues = ["show", "hide"];
Expand Down
16 changes: 7 additions & 9 deletions src/components/controls/measurementsOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import React from "react";
import { useSelector } from "react-redux";
import { useAppDispatch } from "../../hooks";
import { isEqual } from "lodash";
import { changeMeasurementsCollection,changeMeasurementsDisplay, toggleOverallMean, toggleThreshold } from "../../actions/measurements";
import {
CHANGE_MEASUREMENTS_GROUP_BY
} from "../../actions/types";
changeMeasurementsCollection,
changeMeasurementsDisplay,
changeMeasurementsGroupBy,
toggleOverallMean,
toggleThreshold
} from "../../actions/measurements";
import { controlsWidth } from "../../util/globals";
import { SidebarSubtitle, SidebarButton } from "./styles";
import Toggle from "./toggle";
Expand Down Expand Up @@ -78,12 +81,7 @@ const MeasurementsOptions = () => {
isClearable={false}
isSearchable={false}
isMulti={false}
onChange={(opt) => {
dispatch({
type: CHANGE_MEASUREMENTS_GROUP_BY,
data: opt.value
});
}}
onChange={(opt) => {dispatch(changeMeasurementsGroupBy(opt.value));}}
/>
</div>
<SidebarSubtitle>
Expand Down
1 change: 1 addition & 0 deletions src/middleware/changeURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ export const changeURLMiddleware = (store) => (next) => (action) => {
case types.LOAD_MEASUREMENTS: // fallthrough
case types.CHANGE_MEASUREMENTS_COLLECTION: // fallthrough
case types.CHANGE_MEASUREMENTS_DISPLAY: // fallthrough
case types.CHANGE_MEASUREMENTS_GROUP_BY: // fallthrough
case types.TOGGLE_MEASUREMENTS_OVERALL_MEAN: // fallthrough
case types.TOGGLE_MEASUREMENTS_THRESHOLD:
query = {...query, ...action.queryParams};
Expand Down
3 changes: 1 addition & 2 deletions src/reducers/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,10 @@ const Controls = (state: ControlsState = getDefaultControlsState(), action): Con
case types.LOAD_MEASUREMENTS: // fallthrough
case types.CHANGE_MEASUREMENTS_COLLECTION: // fallthrough
case types.CHANGE_MEASUREMENTS_DISPLAY: // fallthrough
case types.CHANGE_MEASUREMENTS_GROUP_BY: // fallthrough
case types.TOGGLE_MEASUREMENTS_OVERALL_MEAN: // fallthrough
case types.TOGGLE_MEASUREMENTS_THRESHOLD:
return {...state, ...action.controls};
case types.CHANGE_MEASUREMENTS_GROUP_BY:
return {...state, measurementsGroupBy: action.data};
case types.APPLY_MEASUREMENTS_FILTER:
return {...state, measurementsFilters: action.data};
/**
Expand Down

0 comments on commit 1ad12c4

Please sign in to comment.