Repository navigation
feat: wire HIDEOPTION/HIDEOPTIONGROUP/SHOWOPTIONGROUP rule actions end-to-end #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { useDataQuery } from '@dhis2/app-runtime' | ||
| import { useEffect, useMemo } from 'react' | ||
| import { | ||
| extractReferencedOptionGroupIds, | ||
| optionGroupsQuery, | ||
| resolveOptionGroups, | ||
| type OptionGroupCodeMap, | ||
| type ProgramRule, | ||
| type RawOptionGroupsResult, | ||
| } from '@dhis2-form-utils/metadata' | ||
|
|
||
| /** | ||
| * Resolves the optionGroup ids referenced by `HIDEOPTIONGROUP`/`SHOWOPTIONGROUP` rule actions | ||
| * into concrete option codes, shaped for `useEventForm`/`useTrackerForm`'s `optionGroups` option. | ||
| * | ||
| * `useDataQuery`'s `variables`/`lazy` options are only read on the hook's initial render — since | ||
| * `programRules` (and therefore `optionGroupIds`) is empty on first render and only becomes | ||
| * populated once program metadata finishes loading, the query is always mounted lazily and | ||
| * re-triggered via `refetch` once there are ids to resolve. | ||
| */ | ||
| export function useOptionGroupsSupplementaryData( | ||
| programRules: ProgramRule[] | ||
| ): OptionGroupCodeMap | undefined { | ||
| const optionGroupIds = useMemo( | ||
| () => extractReferencedOptionGroupIds(programRules), | ||
| [programRules] | ||
| ) | ||
|
|
||
| const { data, refetch } = useDataQuery<RawOptionGroupsResult>( | ||
| optionGroupsQuery, | ||
| { | ||
| lazy: true, | ||
| } | ||
| ) | ||
|
|
||
| useEffect(() => { | ||
| if (optionGroupIds.length > 0) { | ||
| refetch({ optionGroupIds }) | ||
| } | ||
| }, [optionGroupIds, refetch]) | ||
|
|
||
| return useMemo(() => (data ? resolveOptionGroups(data) : undefined), [data]) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -140,6 +140,17 @@ export type FieldState = { | |
| export type FieldStateMap = Record<string, FieldState>; | ||
| ``` | ||
|
|
||
| `hiddenOptions` holds option codes hidden directly by `HIDEOPTION`; `hiddenOptionGroups` holds | ||
| optionGroup ids hidden by `HIDEOPTIONGROUP` — group _membership_ (which option codes belong to a | ||
| group) is resolved separately, since it requires an `optionGroups` API fetch the metadata package | ||
| doesn't do on its own. Callers fetch it (e.g. via `extractReferencedOptionGroupIds` + | ||
| `optionGroupsQuery` + `resolveOptionGroups` from `@dhis2-form-utils/metadata`) and pass it as the | ||
| `optionGroups` option to `useEventForm`/`useTrackerForm`. `resolveHiddenOptionCodes` (in | ||
| `@dhis2-form-utils/rules`) unions `hiddenOptions` with the resolved group members into a single | ||
| `Set<string>` of hidden codes — `useFieldControl` uses it to compute `FieldControlReturn.visibleOptions` | ||
| for widgets to render, and `filterPayload`'s optional third argument uses it to null out a submitted | ||
| value that references a now-hidden option. | ||
|
|
||
|
Comment on lines
+143
to
+153
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 6 \
'UseTrackerFormOptions|optionGroups|filterPayload\s*\(' \
. --glob '*.ts' --glob '*.tsx' --glob '*.md'Repository: nnkogift/dhis2-form-utils Length of output: 50383 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== utils/rules/src/filterPayload.ts =="
fd -a 'filterPayload\.ts$' . | while read -r f; do
rel="${f#${PWD}/}"
echo "--- $rel"
cat -n "$rel"
done
echo "== docs/ARCHITECTURE.md relevant sections =="
sed -n '135,160p;222,233p;564,576p' docs/ARCHITECTURE.md | cat -n
echo "== docs/use-tracker-form.md relevant sections =="
sed -n '358,460p;484,496p' docs/use-tracker-form.md | cat -n
echo "== export tests/data for filterPayload optionGroups =="
rg -n -C 5 'filterPayload\(|optionGroups' utils/rules src packages --glob '*.ts' --glob '*.tsx' --glob '*.md' \
| head -220Repository: nnkogift/dhis2-form-utils Length of output: 27124 Align the option-group contract across the documentation. The implementation supports 📍 Affects 2 files
🤖 Prompt for AI Agents |
||
| **Context assembly** — the engine requires all program rule variables to be resolved before | ||
| evaluation. `@dhis2-form-utils/rules` provides `buildRuleEngineContext`, which takes fetched | ||
| program metadata and constructs the `RuleEngineContext` once, and `buildRuleEngine`, which | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: nnkogift/dhis2-form-utils
Length of output: 50381
🏁 Script executed:
Repository: nnkogift/dhis2-form-utils
Length of output: 25895
Block form rendering until option-group metadata resolves.
OptionGroupCodeMap | undefinedis passed intouseEventForm/useTrackerForm, which installs it on the form store.resolveHiddenOptionCodesandfilterPayloadskip hidden option-group members whenoptionGroupsis absent, soHIDEOPTIONGROUPrules do not hide option values or strip them from the payload. Delay the tracker/event form until the query returns data, and report explicit query failures.🤖 Prompt for AI Agents