devYRPauli commented on code in PR #74885:
URL: https://github.com/apache/airflow/pull/74885#discussion_r4490872358


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldDropdown.tsx:
##########
@@ -58,6 +79,18 @@ export const FieldDropdown = ({ name, namespace = "default", 
onUpdate }: Flexibl
         ? (options.find((opt) => opt.value === String(param.value)) ?? null)
         : null;
 
+  // A parent change can leave the value outside the new options, so clear it
+  const isStale = dependsOn !== undefined && param.value !== null && 
currentValue === null;
+
+  useEffect(() => {

Review Comment:
   Done, and the `useEffect` is gone. `getParamOptions` is in 
`src/utils/paramOptions.ts`, and `FieldDropdown` and the param store both call 
it. The store clears stale children in `setParamsDict` and in `setConf`, and it 
repeats until nothing changes, so a chain clears in one write.
   
   One difference from the pseudocode: I use `(params[parent] ?? 
defaults[parent]).value`, not `params[parent].value ?? defaults[parent].value`. 
With the second form, a parent cleared to null takes its default value again, 
so its children are not cleared. The default applies only when the conf omits 
the parent.
   
   The FlexibleForm and store tests pass, 105 of 105.



##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldDropdown.tsx:
##########
@@ -40,13 +42,32 @@ const labelLookup = (
 
 const enumTypes = ["string", "number", "integer"];
 
+// Python str() of a string, integer, boolean or null parent value, because 
the serialized Dag
+// stores the keys of options_map with str()
+const getOptionKey = (value: unknown): string => {
+  if (value === null || value === undefined) {
+    return "None";
+  }
+  if (typeof value === "boolean") {
+    return value ? "True" : "False";
+  }
+
+  return typeof value === "number" || typeof value === "string" ? 
String(value) : JSON.stringify(value);
+};
+
 export const FieldDropdown = ({ name, namespace = "default", onUpdate }: 
FlexibleFormElementProps) => {
   const { t: translate } = useTranslation("components");
   const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
   const param = paramsDict[name] ?? paramPlaceholder;
 
+  const { depends_on: dependsOn, options_map: optionsMap } = param.schema;
+  const enumValues =
+    dependsOn === undefined
+      ? param.schema.enum
+      : (optionsMap?.[getOptionKey(paramsDict[dependsOn]?.value)] ?? []);

Review Comment:
   Done. An empty dependent dropdown now shows "Select Country first" when the 
parent has no value. It shows "No options for this Country" when the parent 
value has no entry in `options_map`. The label uses the parent `title`, or the 
param name when there is no title.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to