You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "Ed3110 (via GitHub)" <gi...@apache.org> on 2026/07/26 14:14:36 UTC

[PR] Add password field type to FlexibleForm [airflow]

Ed3110 opened a new pull request, #70473:
URL: https://github.com/apache/airflow/pull/70473

   Extra fields that a provider declares with `format: "password"` are rendered as
   plain text in the connection form. `FieldSelector` has no branch for that format,
   so they fall through to `FieldString`, which renders an Input with no type.
   The standard `password` field has been masked with a toggle for a while;
   declared extra fields never got the same treatment.
   
   This adds a `FieldPassword` component to `FlexibleForm` and the matching branch in
   `FieldSelector`, reusing the (`FiEye`/`FiEyeOff`) toggle pattern from
   ConnectionStandardFields. `FieldSelector` is shared with the Dag trigger form, so
   params declared with `format: "password"` are masked there too.
   
   Verified on a Salesforce connection — Security Token, Consumer Secret and Private
   Key mask correctly and the toggle works, other extra fields are unaffected — and
   on a Dag param form. Tests cover the masked input, value storage, clearing, and
   the toggle.
   
   This does not cover free-form keys a provider doesn't declare, 
   such as `private_key` on an SSH connection, which is what the reporter hit.
   Those have no schema and no format, so the UI has no signal to go on; 
   masking them would need the backend to mark sensitive keys. 
   Happy to look at that separately.
   
   before:
   <img width="1288" height="936" alt="image" src="https://github.com/user-attachments/assets/1127a142-731a-4ee4-bafe-7d7c6daa63be" />
   <img width="1232" height="980" alt="image" src="https://github.com/user-attachments/assets/69d933cf-05b4-4aaa-8d78-d45a8809cb81" />
   
   
   after:
   <img width="1212" height="980" alt="image" src="https://github.com/user-attachments/assets/6c543775-efaf-48c2-9d81-b638eac20eff" />
   
   related: #53410
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5)
   
   Generated-by: Claude Code (Opus 5) following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3735723185


##########
airflow-core/src/airflow/ui/src/components/PasswordToggle.tsx:
##########
@@ -0,0 +1,45 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { IconButton } from "src/components/ui";
+
+type Props = {
+  readonly isVisible: boolean;
+  readonly onToggle: () => void;
+};
+
+export const PasswordToggle = ({ isVisible, onToggle }: Props) => {
+  const { t: translate } = useTranslation("components");
+
+  return (
+    <IconButton
+      label={isVisible ? translate("passwordToggle.hide") : translate("passwordToggle.show")}
+      onClick={onToggle}
+      position="absolute"

Review Comment:
   Done — `Props` now extends `IconButtonProps` and spreads the rest onto `IconButton`. Both call sites pass the positioning themselves now.



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "boring-cyborg[bot] (via GitHub)" <gi...@apache.org>.
boring-cyborg[bot] commented on PR #70473:
URL: https://github.com/apache/airflow/pull/70473#issuecomment-5285660656

   Awesome work, congrats on your first merged pull request! You are invited to check our [Issue Tracker](https://github.com/apache/airflow/issues) for additional contributions.
   


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3735711076


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,75 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+
+import { PasswordToggle } from "src/components/PasswordToggle";
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          autoComplete="new-password"
+          disabled={disabled}
+          id={`element_${name}`}
+          list={param.schema.examples ? `list_${name}` : undefined}
+          maxLength={param.schema.maxLength ?? undefined}
+          minLength={param.schema.minLength ?? undefined}
+          name={`element_${name}`}
+          onChange={(event) => {
+            handleChange(event.target.value);
+          }}
+          placeholder={param.schema.examples ? translate("flexibleForm.placeholderExamples") : undefined}
+          size="sm"
+          type={showPassword ? "text" : "password"}
+          value={(param.value ?? "") as string}
+        />
+        <PasswordToggle isVisible={showPassword} onToggle={() => setShowPassword(!showPassword)} />
+      </div>
+      {param.schema.examples ? (
+        <datalist id={`list_${name}`}>
+          {param.schema.examples.map((example) => (
+            <option key={example} value={example}>
+              {example}
+            </option>
+          ))}
+        </datalist>
+      ) : undefined}

Review Comment:
   Done.



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3707716441


##########
airflow-core/src/airflow/ui/src/components/PasswordToggle.tsx:
##########
@@ -0,0 +1,45 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { IconButton } from "src/components/ui";
+
+type Props = {
+  readonly isVisible: boolean;
+  readonly onToggle: () => void;
+};
+
+export const PasswordToggle = ({ isVisible, onToggle }: Props) => {
+  const { t: translate } = useTranslation("components");
+
+  return (
+    <IconButton
+      label={isVisible ? translate("passwordToggle.hide") : translate("passwordToggle.show")}
+      onClick={onToggle}
+      position="absolute"

Review Comment:
   Let's remove this absolute positioning. It should be handled by the parent comonent, via extending the icon button props `type Props {} & IconButtonProps;`



##########
airflow-core/src/airflow/ui/src/pages/Connections/ConnectionStandardFields.tsx:
##########


Review Comment:
   While we are at it. Can we also turn off autocomplete here?



##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,75 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+
+import { PasswordToggle } from "src/components/PasswordToggle";
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          autoComplete="new-password"
+          disabled={disabled}
+          id={`element_${name}`}
+          list={param.schema.examples ? `list_${name}` : undefined}
+          maxLength={param.schema.maxLength ?? undefined}
+          minLength={param.schema.minLength ?? undefined}
+          name={`element_${name}`}
+          onChange={(event) => {
+            handleChange(event.target.value);
+          }}
+          placeholder={param.schema.examples ? translate("flexibleForm.placeholderExamples") : undefined}
+          size="sm"
+          type={showPassword ? "text" : "password"}
+          value={(param.value ?? "") as string}
+        />
+        <PasswordToggle isVisible={showPassword} onToggle={() => setShowPassword(!showPassword)} />
+      </div>
+      {param.schema.examples ? (
+        <datalist id={`list_${name}`}>
+          {param.schema.examples.map((example) => (
+            <option key={example} value={example}>
+              {example}
+            </option>
+          ))}
+        </datalist>
+      ) : undefined}

Review Comment:
   Remove this.
   
   We do not need example passwords. 



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3761073171


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,67 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+
+import { PasswordToggle } from "src/components/PasswordToggle";
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <div style={{ position: "relative", width: "100%" }}>

Review Comment:
   Oh we can also use chakra's `InputGroup` here like:
   
   ```
   <InputGroup endElement={<PasswordToggle isVisible={showPassword} onToggle={…} />}>
     <Input autoComplete="new-password" type={showPassword ? "text" : "password"} … />
   </InputGroup>
   ```
   
   Then we don't need all of this styling



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3735721250


##########
airflow-core/src/airflow/ui/src/pages/Connections/ConnectionStandardFields.tsx:
##########


Review Comment:
   Done, thanks!



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3773669924


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,67 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+
+import { PasswordToggle } from "src/components/PasswordToggle";
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <div style={{ position: "relative", width: "100%" }}>

Review Comment:
   Done, thanks!



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #70473:
URL: https://github.com/apache/airflow/pull/70473#issuecomment-5285672175

   ### Backport successfully created: v3-3-test
   
   Note: As of [Merging PRs targeted for Airflow 3.X](https://github.com/apache/airflow/blob/main/dev/README_AIRFLOW3_DEV.md#merging-prs-targeted-for-airflow-3x)
   the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.
   
   In matter of doubt please ask in [#release-management](https://apache-airflow.slack.com/archives/C03G9H97MM2) Slack channel.
   
   <table>
           <tr>
           <th>Status</th>
           <th>Branch</th>
           <th>Result</th>
       </tr>
       <tr>
           <td>✅</td>
           <td>v3-3-test</td>
           <td><a href="https://github.com/apache/airflow/pull/71573"><img src="https://img.shields.io/badge/PR-71573-blue" alt="PR Link"></a></td>
       </tr>
   </table>


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3676313903


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,89 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          disabled={disabled}

Review Comment:
   
   ```suggestion
             autoComplete="new-password"
             disabled={disabled}
   ```
   
   We need to prevent browsers from trying to autofill



##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,89 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          disabled={disabled}
+          id={`element_${name}`}
+          list={param.schema.examples ? `list_${name}` : undefined}
+          maxLength={param.schema.maxLength ?? undefined}
+          minLength={param.schema.minLength ?? undefined}
+          name={`element_${name}`}
+          onChange={(event) => {
+            handleChange(event.target.value);
+          }}
+          placeholder={param.schema.examples ? translate("flexibleForm.placeholderExamples") : undefined}
+          size="sm"
+          type={showPassword ? "text" : "password"}
+          value={(param.value ?? "") as string}
+        />
+        <button
+          aria-label={
+            showPassword ? translate("flexibleForm.hidePassword") : translate("flexibleForm.showPassword")
+          }
+          onClick={() => setShowPassword(!showPassword)}
+          style={{
+            cursor: "pointer",
+            position: "absolute",
+            right: "10px",
+            top: "50%",
+            transform: "translateY(-50%)",
+          }}
+          type="button"
+        >
+          {showPassword ? <FiEye size={15} /> : <FiEyeOff size={15} />}
+        </button>

Review Comment:
   This is a copy of ConnectionStandardFields.tsx. Let's extract that out into a shared component instead of copying code. Also, we should probably move this to a chakra Button so that it can pick up our theming.



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3681036843


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,89 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          disabled={disabled}
+          id={`element_${name}`}
+          list={param.schema.examples ? `list_${name}` : undefined}
+          maxLength={param.schema.maxLength ?? undefined}
+          minLength={param.schema.minLength ?? undefined}
+          name={`element_${name}`}
+          onChange={(event) => {
+            handleChange(event.target.value);
+          }}
+          placeholder={param.schema.examples ? translate("flexibleForm.placeholderExamples") : undefined}
+          size="sm"
+          type={showPassword ? "text" : "password"}
+          value={(param.value ?? "") as string}
+        />
+        <button
+          aria-label={
+            showPassword ? translate("flexibleForm.hidePassword") : translate("flexibleForm.showPassword")
+          }
+          onClick={() => setShowPassword(!showPassword)}
+          style={{
+            cursor: "pointer",
+            position: "absolute",
+            right: "10px",
+            top: "50%",
+            transform: "translateY(-50%)",
+          }}
+          type="button"
+        >
+          {showPassword ? <FiEye size={15} /> : <FiEyeOff size={15} />}
+        </button>

Review Comment:
   I think I've got it. The toggle is now in `src/components/PasswordToggle.tsx`
   and both FieldPassword and StandardFields use it. I built it on `ui/IconButton`,
   which seemed like the right wrapper, and it also gives a tooltip and an
   aria-label.
   
   I left `showPassword` in the callers since the `Input`'s `type` needs it, but
   let me know if you'd rather it lived somewhere else.
   
   I also moved `hidePassword`/`showPassword` out of `flexibleForm` into a new
   `passwordToggle` section in `components.json`. That file looked like it's keyed
   by component, but I wasn't sure, so happy to move them.



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3680211397


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,89 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input } from "@chakra-ui/react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { FiEye, FiEyeOff } from "react-icons/fi";
+
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { t: translate } = useTranslation("components");
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <>
+      <div style={{ position: "relative", width: "100%" }}>
+        <Input
+          disabled={disabled}
+          id={`element_${name}`}
+          list={param.schema.examples ? `list_${name}` : undefined}
+          maxLength={param.schema.maxLength ?? undefined}
+          minLength={param.schema.minLength ?? undefined}
+          name={`element_${name}`}
+          onChange={(event) => {
+            handleChange(event.target.value);
+          }}
+          placeholder={param.schema.examples ? translate("flexibleForm.placeholderExamples") : undefined}
+          size="sm"
+          type={showPassword ? "text" : "password"}
+          value={(param.value ?? "") as string}
+        />
+        <button
+          aria-label={
+            showPassword ? translate("flexibleForm.hidePassword") : translate("flexibleForm.showPassword")
+          }
+          onClick={() => setShowPassword(!showPassword)}
+          style={{
+            cursor: "pointer",
+            position: "absolute",
+            right: "10px",
+            top: "50%",
+            transform: "translateY(-50%)",
+          }}
+          type="button"
+        >
+          {showPassword ? <FiEye size={15} /> : <FiEyeOff size={15} />}
+        </button>

Review Comment:
   Thanks for the review, I'll get on it.



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi commented on code in PR #70473:
URL: https://github.com/apache/airflow/pull/70473#discussion_r3777670490


##########
airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldPassword.tsx:
##########
@@ -0,0 +1,63 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Input, InputGroup } from "@chakra-ui/react";
+import { useState } from "react";
+
+import { PasswordToggle } from "src/components/PasswordToggle";
+import { paramPlaceholder, useParamStore } from "src/queries/useParamStore";
+
+import type { FlexibleFormElementProps } from ".";
+
+export const FieldPassword = ({ name, namespace = "default", onUpdate }: FlexibleFormElementProps) => {
+  const [showPassword, setShowPassword] = useState(false);
+  const { disabled, paramsDict, setParamsDict } = useParamStore(namespace);
+  const param = paramsDict[name] ?? paramPlaceholder;
+  const handleChange = (value: string) => {
+    if (paramsDict[name]) {
+      // "undefined" values are removed from params, so we set it to null to avoid falling back to DAG defaults.
+      paramsDict[name].value = value === "" ? null : value;
+    }
+
+    setParamsDict(paramsDict);
+    onUpdate(value);
+  };
+
+  return (
+    <InputGroup
+      endElement={
+        <PasswordToggle isVisible={showPassword} onToggle={() => setShowPassword(!showPassword)} />
+      }

Review Comment:
   ```suggestion
         endElement={<PasswordToggle isVisible={showPassword} onToggle={() => setShowPassword(!showPassword)} />}
   ```



-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "bbovenzi (via GitHub)" <gi...@apache.org>.
bbovenzi merged PR #70473:
URL: https://github.com/apache/airflow/pull/70473


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "potiuk (via GitHub)" <gi...@apache.org>.
potiuk commented on PR #70473:
URL: https://github.com/apache/airflow/pull/70473#issuecomment-5115970593

   > Thanks for kicking off CI @potiuk
   > 
   > The Firefox UI e2e job failed at the `Setup pnpm` step (`self-installer exits with code 1`) before any code ran. The Chromium and WebKit jobs running the same suite both passed, so it doesn't look related to this PR. Could it be re-run when convenient?
   
   Re-run it - but if this is still failing rebasing to latest main (and waiting for maintainer review when it's green) is the right next step for you


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "Ed3110 (via GitHub)" <gi...@apache.org>.
Ed3110 commented on PR #70473:
URL: https://github.com/apache/airflow/pull/70473#issuecomment-5111597223

   Thanks for kicking off CI @potiuk
   
   The Firefox UI e2e job failed at the `Setup pnpm` step (`self-installer
   exits with code 1`) before any code ran. 
   The Chromium and WebKit jobs running the same suite both passed, so it doesn't look related to this PR. 
   Could it be re-run when convenient?


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add password field type to FlexibleForm [airflow]

Posted by "boring-cyborg[bot] (via GitHub)" <gi...@apache.org>.
boring-cyborg[bot] commented on PR #70473:
URL: https://github.com/apache/airflow/pull/70473#issuecomment-5083847437

   Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our [Contributors' Guide](https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
   Here are some useful points:
   - Pay attention to the quality of your code (ruff, mypy and type annotations). Our [prek-hooks]( https://github.com/apache/airflow/blob/main/contributing-docs/08_static_code_checks.rst#prerequisites-for-prek-hooks) will help you with that.
   - In case of a new feature add useful documentation (in docstrings or in `docs/` directory). Adding a new operator? Check this short [guide](https://github.com/apache/airflow/blob/main/airflow-core/docs/howto/custom-operator.rst) Consider adding an example Dag that shows how users should use it.
   - Consider using [Breeze environment](https://github.com/apache/airflow/blob/main/dev/breeze/doc/README.rst) for testing locally, it's a heavy docker but it ships with a working Airflow and a lot of integrations.
   - Be patient and persistent. It might take some time to get a review or get the final approval from Committers.
   - Please follow [ASF Code of Conduct](https://www.apache.org/foundation/policies/conduct) for all communication including (but not limited to) comments on Pull Requests, Mailing list and Slack.
   - Be sure to read the [Airflow Coding style]( https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#coding-style-and-best-practices).
   - Always keep your Pull Requests rebased, otherwise your build might fail due to changes not related to your commits.
   Apache Airflow is a community-driven project and together we are making it better 🚀.
   In case of doubts contact the developers at:
   Mailing List: dev@airflow.apache.org
   Slack: https://s.apache.org/airflow-slack
   


-- 
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: commits-unsubscribe@airflow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org