parent
482aa5a7c4
commit
056440842a
7 changed files with 14 additions and 52 deletions
|
|
@ -322,10 +322,6 @@ async def update_flow(
|
||||||
|
|
||||||
update_data = flow.model_dump(exclude_unset=True, exclude_none=True)
|
update_data = flow.model_dump(exclude_unset=True, exclude_none=True)
|
||||||
|
|
||||||
# Specifically handle endpoint_name when it's explicitly set to null or empty string
|
|
||||||
if flow.endpoint_name is None or flow.endpoint_name == "":
|
|
||||||
update_data["endpoint_name"] = None
|
|
||||||
|
|
||||||
if settings_service.settings.remove_api_keys:
|
if settings_service.settings.remove_api_keys:
|
||||||
update_data = remove_api_keys(update_data)
|
update_data = remove_api_keys(update_data)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,8 @@ export const MenuBar = memo((): JSX.Element => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editingName) {
|
if (currentFlowName && !editingName) {
|
||||||
setFlowName(currentFlowName ?? "Untitled Flow");
|
setFlowName(currentFlowName);
|
||||||
}
|
}
|
||||||
}, [currentFlowName, editingName]);
|
}, [currentFlowName, editingName]);
|
||||||
|
|
||||||
|
|
@ -233,7 +233,7 @@ export const MenuBar = memo((): JSX.Element => {
|
||||||
: getNumberFromString(currentFlowGradient ?? currentFlowId ?? "")) %
|
: getNumberFromString(currentFlowGradient ?? currentFlowId ?? "")) %
|
||||||
swatchColors.length;
|
swatchColors.length;
|
||||||
|
|
||||||
return onFlowPage ? (
|
return currentFlowName && onFlowPage ? (
|
||||||
<div
|
<div
|
||||||
className="flex w-full items-center justify-center gap-2"
|
className="flex w-full items-center justify-center gap-2"
|
||||||
data-testid="menu_bar_wrapper"
|
data-testid="menu_bar_wrapper"
|
||||||
|
|
@ -303,7 +303,7 @@ export const MenuBar = memo((): JSX.Element => {
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
onFocus={() => {
|
onFocus={() => {
|
||||||
setEditingName(true);
|
setEditingName(true);
|
||||||
setFlowName(currentFlowName ?? "Untitled Flow");
|
setFlowName(currentFlowName);
|
||||||
const flows = useFlowsManagerStore.getState().flows;
|
const flows = useFlowsManagerStore.getState().flows;
|
||||||
setFlowNames(
|
setFlowNames(
|
||||||
flows
|
flows
|
||||||
|
|
@ -315,7 +315,6 @@ export const MenuBar = memo((): JSX.Element => {
|
||||||
value={flowName}
|
value={flowName}
|
||||||
id="input-flow-name"
|
id="input-flow-name"
|
||||||
data-testid="input-flow-name"
|
data-testid="input-flow-name"
|
||||||
placeholder="Untitled Flow"
|
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
ref={measureRef}
|
ref={measureRef}
|
||||||
|
|
@ -323,7 +322,7 @@ export const MenuBar = memo((): JSX.Element => {
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-testid="flow_name"
|
data-testid="flow_name"
|
||||||
>
|
>
|
||||||
{flowName || "Untitled Flow"}
|
{flowName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,11 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
description,
|
description,
|
||||||
endpointName,
|
endpointName,
|
||||||
maxLength = 50,
|
maxLength = 50,
|
||||||
minLength = 1,
|
|
||||||
setName,
|
setName,
|
||||||
setDescription,
|
setDescription,
|
||||||
setEndpointName,
|
setEndpointName,
|
||||||
}: InputProps): JSX.Element => {
|
}: InputProps): JSX.Element => {
|
||||||
const [isMaxLength, setIsMaxLength] = useState(false);
|
const [isMaxLength, setIsMaxLength] = useState(false);
|
||||||
const [isMinLength, setIsMinLength] = useState(false);
|
|
||||||
const [validEndpointName, setValidEndpointName] = useState(true);
|
const [validEndpointName, setValidEndpointName] = useState(true);
|
||||||
const [isInvalidName, setIsInvalidName] = useState(false);
|
const [isInvalidName, setIsInvalidName] = useState(false);
|
||||||
|
|
||||||
|
|
@ -28,11 +26,6 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
} else {
|
} else {
|
||||||
setIsMaxLength(false);
|
setIsMaxLength(false);
|
||||||
}
|
}
|
||||||
if (value.length < minLength) {
|
|
||||||
setIsMinLength(true);
|
|
||||||
} else {
|
|
||||||
setIsMinLength(false);
|
|
||||||
}
|
|
||||||
let invalid = false;
|
let invalid = false;
|
||||||
for (let i = 0; i < invalidNameList!.length; i++) {
|
for (let i = 0; i < invalidNameList!.length; i++) {
|
||||||
if (value === invalidNameList![i]) {
|
if (value === invalidNameList![i]) {
|
||||||
|
|
@ -42,15 +35,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
invalid = false;
|
invalid = false;
|
||||||
}
|
}
|
||||||
setIsInvalidName(invalid);
|
setIsInvalidName(invalid);
|
||||||
|
|
||||||
// Only update the name if it's valid (not empty and not invalid)
|
|
||||||
if (value.length >= minLength && !invalid) {
|
|
||||||
setName!(value);
|
setName!(value);
|
||||||
} else if (value.length === 0) {
|
|
||||||
// For empty string, update state but keep isMinLength true
|
|
||||||
setName!("");
|
|
||||||
setIsMinLength(true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
|
@ -58,19 +43,11 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEndpointNameChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleEndpointNameChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
const { value } = event.target;
|
|
||||||
// Validate the endpoint name
|
// Validate the endpoint name
|
||||||
// use this regex r'^[a-zA-Z0-9_-]+$'
|
// use this regex r'^[a-zA-Z0-9_-]+$'
|
||||||
const isValid = isEndpointNameValid(event.target.value, maxLength);
|
const isValid = isEndpointNameValid(event.target.value, maxLength);
|
||||||
setValidEndpointName(isValid);
|
setValidEndpointName(isValid);
|
||||||
|
setEndpointName!(event.target.value);
|
||||||
// Only update if valid and meets minimum length (if set)
|
|
||||||
if (isValid && value.length >= minLength) {
|
|
||||||
setEndpointName!(value);
|
|
||||||
} else if (value.length === 0) {
|
|
||||||
// Always allow empty endpoint name (it's optional)
|
|
||||||
setEndpointName!("");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//this function is necessary to select the text when double clicking, this was not working with the onFocus event
|
//this function is necessary to select the text when double clicking, this was not working with the onFocus event
|
||||||
|
|
@ -84,11 +61,6 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
{isMaxLength && (
|
{isMaxLength && (
|
||||||
<span className="edit-flow-span">Character limit reached</span>
|
<span className="edit-flow-span">Character limit reached</span>
|
||||||
)}
|
)}
|
||||||
{isMinLength && (
|
|
||||||
<span className="edit-flow-span">
|
|
||||||
Minimum {minLength} character(s) required
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{isInvalidName && (
|
{isInvalidName && (
|
||||||
<span className="edit-flow-span">
|
<span className="edit-flow-span">
|
||||||
Name invalid or already exists
|
Name invalid or already exists
|
||||||
|
|
@ -105,8 +77,6 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
placeholder="Flow name"
|
placeholder="Flow name"
|
||||||
id="name"
|
id="name"
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
minLength={minLength}
|
|
||||||
required={true}
|
|
||||||
onDoubleClickCapture={(event) => {
|
onDoubleClickCapture={(event) => {
|
||||||
handleFocus(event);
|
handleFocus(event);
|
||||||
}}
|
}}
|
||||||
|
|
@ -167,7 +137,6 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
value={endpointName ?? ""}
|
value={endpointName ?? ""}
|
||||||
placeholder="An alternative name to run the endpoint"
|
placeholder="An alternative name to run the endpoint"
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
minLength={minLength}
|
|
||||||
id="endpoint_name"
|
id="endpoint_name"
|
||||||
onDoubleClickCapture={(event) => {
|
onDoubleClickCapture={(event) => {
|
||||||
handleFocus(event);
|
handleFocus(event);
|
||||||
|
|
|
||||||
|
|
@ -28,19 +28,17 @@ export default function FlowSettingsModal({
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const flows = useFlowsManagerStore((state) => state.flows);
|
const flows = useFlowsManagerStore((state) => state.flows);
|
||||||
const flow = flowData ?? currentFlow;
|
const flow = flowData ?? currentFlow;
|
||||||
|
useEffect(() => {
|
||||||
|
setName(flow?.name ?? "");
|
||||||
|
setDescription(flow?.description ?? "");
|
||||||
|
}, [flow?.name, flow?.description, open]);
|
||||||
|
|
||||||
const [name, setName] = useState(flow?.name ?? "");
|
const [name, setName] = useState(flow?.name ?? "");
|
||||||
const [description, setDescription] = useState(flow?.description ?? "");
|
const [description, setDescription] = useState(flow?.description ?? "");
|
||||||
const [endpoint_name, setEndpointName] = useState(flow?.endpoint_name ?? "");
|
const [endpoint_name, setEndpointName] = useState(flow?.endpoint_name ?? "");
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
const [disableSave, setDisableSave] = useState(true);
|
const [disableSave, setDisableSave] = useState(true);
|
||||||
const autoSaving = useFlowsManagerStore((state) => state.autoSaving);
|
const autoSaving = useFlowsManagerStore((state) => state.autoSaving);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setName(flow?.name ?? "");
|
|
||||||
setDescription(flow?.description ?? "");
|
|
||||||
setEndpointName(flow?.endpoint_name ?? "");
|
|
||||||
}, [flow?.name, flow?.description, flow?.endpoint_name, open]);
|
|
||||||
|
|
||||||
function handleClick(): void {
|
function handleClick(): void {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
if (!flow) return;
|
if (!flow) return;
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
||||||
|
|
||||||
const getFlowToAddToCanvas = async (id: string) => {
|
const getFlowToAddToCanvas = async (id: string) => {
|
||||||
const flow = await getFlow({ id: id });
|
const flow = await getFlow({ id: id });
|
||||||
|
console.log(flow);
|
||||||
setCurrentFlow(flow);
|
setCurrentFlow(flow);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,6 @@ export type InputProps = {
|
||||||
description: string | null;
|
description: string | null;
|
||||||
endpointName?: string | null;
|
endpointName?: string | null;
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
minLength?: number;
|
|
||||||
setName?: (name: string) => void;
|
setName?: (name: string) => void;
|
||||||
setDescription?: (description: string) => void;
|
setDescription?: (description: string) => void;
|
||||||
setEndpointName?: (endpointName: string) => void;
|
setEndpointName?: (endpointName: string) => void;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test";
|
||||||
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
|
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
|
||||||
test(
|
test(
|
||||||
"user should be able to edit flow name by clicking on the header or on the main page",
|
"user should be able to edit flow name by clicking on the header or on the main page",
|
||||||
{ tag: ["@release", "@workspace"] },
|
{ tag: ["@release", "@workspace", "@components"] },
|
||||||
async ({ page }) => {
|
async ({ page }) => {
|
||||||
const randomName = Math.random().toString(36).substring(2, 15);
|
const randomName = Math.random().toString(36).substring(2, 15);
|
||||||
const randomName2 = Math.random().toString(36).substring(2, 15);
|
const randomName2 = Math.random().toString(36).substring(2, 15);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue