support uiHInt property in env vars (#526)

* support uiHInt property in env vars

* wip

* remove placeholder for app envs input
This commit is contained in:
Hoan Luu Huu
2025-05-26 06:34:29 +07:00
committed by GitHub
parent 36f22e2075
commit 19620116b5
3 changed files with 92 additions and 55 deletions

View File

@@ -798,6 +798,7 @@ export interface AppEnvProperty {
required?: boolean;
default?: string | number | boolean;
obscure?: boolean;
uiHint?: "input" | "textarea" | "filepicker";
}
export interface AppEnv {

View File

@@ -10,6 +10,7 @@ import {
Passwd,
Message,
AccountSelect,
FileUpload,
} from "src/components/forms";
import {
vendors,
@@ -769,7 +770,7 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
const defaultValue = webhook.webhookEnv![key].default;
return (
<div className="inp" key={key}>
<div key={key}>
{isBoolean ? (
// Boolean input as checkbox
<label htmlFor={`env_${key}`} className="chk">
@@ -784,10 +785,10 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
: Boolean(defaultValue)
}
onChange={(e) => {
setEnvVars({
...(envVars || {}),
setEnvVars((prev) => ({
...(prev || {}),
[key]: e.target.checked,
});
}));
}}
/>
<Tooltip
@@ -812,22 +813,21 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
)}
</Tooltip>
</label>
{webhook.webhookEnv![key].obscure ? (
<ObscureInput
name={`env_${key}`}
id={`env_${key}`}
placeholder={
webhook.webhookEnv![key].description
}
required={webhook.webhookEnv![key].required}
value={
{(() => {
// Common props for both input types
const commonProps = {
id: `env_${key}`,
name: `env_${key}`,
required: webhook.webhookEnv![key].required,
value:
envVars && envVars[key] !== undefined
? String(envVars[key])
: defaultValue !== undefined
? String(defaultValue)
: ""
}
onChange={(e) => {
: "",
onChange: (
e: React.ChangeEvent<HTMLInputElement>,
) => {
// Convert to proper type based on schema
let newValue;
if (isNumber) {
@@ -839,47 +839,75 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
newValue = e.target.value;
}
setEnvVars({
...(envVars || {}),
setEnvVars((prev) => ({
...(prev || {}),
[key]: newValue,
});
}}
/>
) : (
<input
id={`env_${key}`}
type={isNumber ? "number" : "text"}
name={`env_${key}`}
placeholder={
webhook.webhookEnv![key].description
}
required={webhook.webhookEnv![key].required}
value={
envVars && envVars[key] !== undefined
? String(envVars[key])
: defaultValue !== undefined
? String(defaultValue)
: ""
}
onChange={(e) => {
// Convert to proper type based on schema
let newValue;
if (isNumber) {
newValue =
e.target.value === ""
? ""
: Number(e.target.value);
} else {
newValue = e.target.value;
}
}));
},
};
setEnvVars({
...(envVars || {}),
[key]: newValue,
});
}}
/>
)}
// Extra props only for regular input
const inputSpecificProps = {
type: isNumber ? "number" : "text",
};
const textAreaSpecificProps = {
rows: 6,
cols: 61,
};
// Choose component type based on obscure flag
const componentType = webhook.webhookEnv![key]
.obscure
? ObscureInput
: webhook.webhookEnv![key].uiHint || "input";
if (componentType === "filepicker") {
return (
<>
<FileUpload
id={`app_env_${key}`}
name={`app_env_${key}`}
handleFile={(file) => {
file
.text()
.then((content) => {
setEnvVars((prev) => ({
...(prev || {}),
[key]: content,
}));
})
.catch((err) => {
toastError(
`Failed to read file: ${err.message}`,
);
});
}}
placeholder="Choose a file"
required={
webhook.webhookEnv![key].required
}
/>
{React.createElement("textarea", {
...commonProps,
...inputSpecificProps,
...textAreaSpecificProps,
})}
</>
);
}
// Create the component with appropriate props
return React.createElement(
componentType,
webhook.webhookEnv![key].obscure
? commonProps
: {
...commonProps,
...inputSpecificProps,
...(webhook.webhookEnv![key].uiHint ===
"textarea" && textAreaSpecificProps),
},
);
})()}
</>
)}
</div>

View File

@@ -151,6 +151,14 @@ fieldset {
margin-top: ui-vars.$px01;
}
div + textarea {
margin-top: ui-vars.$px02;
}
textarea {
border-radius: ui-vars.$px01;
}
* + label {
margin-top: ui-vars.$px02;
}