Files
xo-cli/src/tui/screens/action-wizard/hooks/useVariableInputs.ts

76 lines
2.2 KiB
TypeScript

import { useState, useCallback } from "react";
import type { XOTemplate } from "@xo-cash/types";
import type { VariableInput } from "../types.js";
/**
* Manages the variable input state for the wizard's variables step.
*
* Populates variables from the template's action/role requirements
* and provides validation + update helpers.
*/
export function useVariableInputs() {
const [variables, setVariables] = useState<VariableInput[]>([]);
/**
* Populate the variable list from the template's role requirements.
* Calling this again replaces the current variables entirely.
*/
const initFromTemplate = useCallback(
(
template: XOTemplate,
actionIdentifier: string,
roleIdentifier: string,
) => {
const action = template.actions?.[actionIdentifier];
const role = action?.roles?.[roleIdentifier];
const varIds = role?.requirements?.variables ?? [];
const varInputs: VariableInput[] = varIds.map((varId) => {
const varDef = template.variables?.[varId];
return {
id: varId,
name: varDef?.name || varId,
type: varDef?.type || "string",
hint: varDef?.hint,
value: "",
};
});
setVariables(varInputs);
},
[],
);
/** Update a single variable's value by index. */
const updateVariable = useCallback((index: number, value: string) => {
setVariables((prev) => {
const updated = [...prev];
const variable = updated[index];
if (variable) {
updated[index] = { ...variable, value };
}
return updated;
});
}, []);
/** Returns an error message if any required variable is empty, or null if valid. */
const validate = useCallback((): string | null => {
const emptyVars = variables.filter(
(v) => !v.value || v.value.trim() === "",
);
if (emptyVars.length > 0) {
return `Please enter values for: ${emptyVars.map((v) => v.name).join(", ")}`;
}
return null;
}, [variables]);
return {
variables,
setVariables,
initFromTemplate,
updateVariable,
validate,
} as const;
}
export type VariableInputsState = ReturnType<typeof useVariableInputs>;