Skip to content

Commit

Permalink
Edit values for individual items in entity group criteria
Browse files Browse the repository at this point in the history
Add more criteria to the AoU test underlay to avoid changing the actual
underlays but still publish config changes.
  • Loading branch information
tjennison-work committed Sep 24, 2024
1 parent 13b3c9e commit 658af6d
Show file tree
Hide file tree
Showing 21 changed files with 761 additions and 251 deletions.
6 changes: 4 additions & 2 deletions docs/generated/PROTOCOL_BUFFERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ Data for an entity group criteria is a list of selected values.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| selected | [EntityGroup.Selection](#tanagra-dataschema-EntityGroup-Selection) | repeated | |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for an additional categorical or numeric value associated with the selection (e.g. a measurement value). |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for an additional categorical or numeric value associated with the selection (e.g. a measurement value). Deprecated in favor of per-selection value_data. |



Expand All @@ -643,6 +643,7 @@ Data for an entity group criteria is a list of selected values.
| key | [tanagra.Key](#tanagra-Key) | | The key of the selected value, which references a related entity (e.g. condition for a condition_occurrence). |
| name | [string](#string) | | The visible name for the selection. This is stored to avoid extra lookups when rendering. |
| entityGroup | [string](#string) | | The entity group is stored to differentiate between them when multiple are configured within a single criteria. |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for additional categorical or numeric values associated with the selection (e.g. a measurement value). |



Expand Down Expand Up @@ -737,7 +738,7 @@ Data for an entity group criteria is a list of selected values.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| selected | [Survey.Selection](#tanagra-dataschema-Survey-Selection) | repeated | |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for an additional categorical or numeric value associated with the selection (e.g. a numeric answer). |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for an additional categorical or numeric value associated with the selection (e.g. a numeric answer). Temporarily unused in favor of per-selection value_data but will potentially be used in future to support criteria wide values (e.g. survey version or date). |



Expand All @@ -757,6 +758,7 @@ Data for an entity group criteria is a list of selected values.
| entityGroup | [string](#string) | | The entity group is stored to differentiate between them when multiple are configured within a single criteria. |
| question_key | [tanagra.Key](#tanagra-Key) | | If the selected item is an answer, the key of the question it belongs to. |
| question_name | [string](#string) | | If the selected item is an answer, the visible name of the question it belongs to. |
| value_data | [tanagra.ValueData](#tanagra-ValueData) | | Data for additional categorical or numeric values associated with the selection (e.g. a numeric answer). |



Expand Down
9 changes: 6 additions & 3 deletions ui/src/components/loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Props = {
showProgressOnMutate?: boolean;
disableReloadButton?: boolean;
immediate?: boolean;
noProgress?: boolean;
};

export default function Loading(props: Props) {
Expand Down Expand Up @@ -68,7 +69,8 @@ export default function Loading(props: Props) {
isLoading,
props.status,
props.size ?? "large",
props.disableReloadButton
props.disableReloadButton,
props.noProgress
)}
</Box>
);
Expand All @@ -80,7 +82,8 @@ function showStatus(
isLoading?: boolean,
status?: Status,
size?: string,
disableReloadButton?: boolean
disableReloadButton?: boolean,
noProgress?: boolean
): ReactNode {
if (status?.error && !status?.isLoading) {
const defaultMessage = "Something went wrong";
Expand Down Expand Up @@ -121,7 +124,7 @@ function showStatus(
</GridLayout>
);
}
return visible ? (
return !noProgress && visible ? (
<CircularProgress
size={size === "small" ? theme.typography.body2.fontSize : undefined}
sx={
Expand Down
52 changes: 31 additions & 21 deletions ui/src/criteria/classification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {
} from "components/treegrid";
import {
ANY_VALUE_DATA,
decodeValueData,
encodeValueData,
decodeValueDataOptional,
encodeValueDataOptional,
ValueData,
ValueDataEdit,
} from "criteria/valueData";
Expand Down Expand Up @@ -61,6 +61,7 @@ type Selection = {
key: DataKey;
name: string;
entityGroup: string;
valueData?: ValueData;
};

// A custom TreeGridItem allows us to store the EntityNode along with
Expand All @@ -74,7 +75,7 @@ type EntityNodeItem = TreeGridItem & {
// Exported for testing purposes.
export interface Data {
selected: Selection[];
valueData: ValueData;
valueData?: ValueData;
}

// "entityGroup" plugins selects occurrences based on the configuration of one
Expand Down Expand Up @@ -140,7 +141,7 @@ class _ implements CriteriaPlugin<string> {
}

renderInline(groupId: string) {
if (this.config.multiSelect || !this.config.valueConfigs.length) {
if (!this.config.valueConfigs.length) {
return null;
}

Expand Down Expand Up @@ -871,21 +872,27 @@ function ClassificationInline(props: ClassificationInlineProps) {
);

return (
<ValueDataEdit
hintEntity={entityGroup.occurrenceEntityIds[0]}
relatedEntity={entityGroup.selectionEntity.name}
hintKey={decodedData.selected[0].key}
singleValue
valueConfigs={props.config.valueConfigs}
valueData={[decodedData.valueData]}
update={(valueData) =>
updateCriteria(
produce(decodedData, (data) => {
data.valueData = valueData[0];
})
)
}
/>
<GridLayout rows height="auto">
{decodedData.selected.map((s, i) => (
<ValueDataEdit
key={s.key}
hintEntity={entityGroup.occurrenceEntityIds[0]}
relatedEntity={entityGroup.selectionEntity.name}
hintKey={s.key}
singleValue
title={s.name}
valueConfigs={props.config.valueConfigs}
valueData={s.valueData ? [s.valueData] : undefined}
update={(valueData) =>
updateCriteria(
produce(decodedData, (data) => {
data.selected[i].valueData = valueData?.[0];
})
)
}
/>
))}
</GridLayout>
);
}

Expand Down Expand Up @@ -986,8 +993,10 @@ function decodeData(data: string): Data {
key: dataKeyFromProto(s.key),
name: s.name,
entityGroup: s.entityGroup,
valueData:
decodeValueDataOptional(s.valueData) ??
decodeValueDataOptional(message.valueData),
})) ?? [],
valueData: decodeValueData(message.valueData),
};
}

Expand All @@ -997,8 +1006,9 @@ function encodeData(data: Data): string {
key: protoFromDataKey(s.key),
name: s.name,
entityGroup: s.entityGroup,
valueData: encodeValueDataOptional(s.valueData),
})),
valueData: encodeValueData(data.valueData),
valueData: undefined,
};
return JSON.stringify(dataProto.EntityGroup.toJSON(message));
}
Expand Down
4 changes: 3 additions & 1 deletion ui/src/criteria/multiAttribute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ function MultiAttributeInline(props: MultiAttributeInlineProps) {
update={(valueData) =>
updateCriteria(
produce(decodedData, (data) => {
data.valueData = valueData;
if (valueData) {
data.valueData = valueData;
}
})
)
}
Expand Down
86 changes: 63 additions & 23 deletions ui/src/criteria/survey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
} from "components/treegrid";
import {
ANY_VALUE_DATA,
decodeValueData,
encodeValueData,
decodeValueDataOptional,
encodeValueDataOptional,
ValueData,
ValueDataEdit,
} from "criteria/valueData";
Expand Down Expand Up @@ -61,6 +61,7 @@ type Selection = {
entityGroup: string;
questionKey?: DataKey;
questionName: string;
valueData?: ValueData;
};

enum EntityNodeItemType {
Expand All @@ -83,7 +84,7 @@ type EntityTreeGridData = TreeGridData<EntityNodeItem>;
// Exported for testing purposes.
export interface Data {
selected: Selection[];
valueData: ValueData;
valueData?: ValueData;
}

// "survey" plugins are designed to handle medium sized (~<100k rows) amount of
Expand Down Expand Up @@ -154,9 +155,7 @@ class _ implements CriteriaPlugin<string> {
}

renderInline(groupId: string) {
const decodedData = decodeData(this.data);

if (!this.config.valueConfigs.length || decodedData.selected.length) {
if (!this.config.valueConfigs.length) {
return null;
}

Expand Down Expand Up @@ -682,6 +681,10 @@ function SurveyInline(props: SurveyInlineProps) {
);

const decodedData = useMemo(() => decodeData(props.data), [props.data]);
const groupedSelection = useMemo(
() => groupSelection(decodedData.selected),
[decodedData]
);

if (!props.config.valueConfigs.length || !decodedData.selected.length) {
return null;
Expand All @@ -691,22 +694,56 @@ function SurveyInline(props: SurveyInlineProps) {
decodedData.selected[0].entityGroup
);

const contentForItem = (item: GroupedSelectionItem) => {
if (item.index < 0) {
return <Typography variant="body2">{item.name}</Typography>;
}

const sel = decodedData.selected[item.index];
return (
<GridBox sx={{ pb: 1, height: "auto" }}>
<ValueDataEdit
key={sel.key}
hintEntity={entityGroup.occurrenceEntityIds[0]}
relatedEntity={entityGroup.selectionEntity.name}
hintKey={sel.key}
singleValue
title={sel.name}
valueConfigs={props.config.valueConfigs}
valueData={sel.valueData ? [sel.valueData] : undefined}
update={(valueData) =>
updateCriteria(
produce(decodedData, (data) => {
data.selected[item.index].valueData = valueData?.[0];
})
)
}
/>
</GridBox>
);
};

return (
<ValueDataEdit
hintEntity={entityGroup.occurrenceEntityIds[0]}
relatedEntity={entityGroup.selectionEntity.name}
hintKey={decodedData.selected[0].key}
singleValue
valueConfigs={props.config.valueConfigs}
valueData={[decodedData.valueData]}
update={(valueData) =>
updateCriteria(
produce(decodedData, (data) => {
data.valueData = valueData[0];
})
)
}
/>
<GridLayout rows height="auto">
{groupedSelection.map((s, i) => (
<GridLayout key={s.key} rows height="auto">
<GridBox
sx={{
height: "auto",
boxShadow:
i !== 0
? (theme) => `0 -1px 0 ${theme.palette.divider}`
: undefined,
}}
>
{contentForItem(s)}
</GridBox>
<GridLayout rows height="auto" sx={{ pl: 2 }}>
{s.children.map((child) => contentForItem(child))}
</GridLayout>
</GridLayout>
))}
</GridLayout>
);
}

Expand Down Expand Up @@ -770,8 +807,10 @@ function decodeData(data: string): Data {
? dataKeyFromProto(s.questionKey)
: undefined,
questionName: s.questionName,
valueData:
decodeValueDataOptional(s.valueData) ??
decodeValueDataOptional(message.valueData),
})) ?? [],
valueData: decodeValueData(message.valueData),
};
}

Expand All @@ -783,8 +822,9 @@ function encodeData(data: Data): string {
entityGroup: s.entityGroup,
questionKey: s.questionKey ? protoFromDataKey(s.questionKey) : undefined,
questionName: s.questionName,
valueData: encodeValueDataOptional(s.valueData),
})),
valueData: encodeValueData(data.valueData),
valueData: undefined,
};
return JSON.stringify(dataProto.Survey.toJSON(message));
}
Expand Down
Loading

0 comments on commit 658af6d

Please sign in to comment.