Added Status button and fixed positioning of Node Header elements

This commit is contained in:
Lucas Oliveira 2024-06-11 12:32:58 -03:00
commit 9cde3ef1ee
3 changed files with 59 additions and 75 deletions

View file

@ -1,5 +1,6 @@
import emojiRegex from "emoji-regex"; import emojiRegex from "emoji-regex";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import Markdown from "react-markdown";
import { NodeToolbar, useUpdateNodeInternals } from "reactflow"; import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import InputComponent from "../../components/inputComponent"; import InputComponent from "../../components/inputComponent";
@ -19,6 +20,7 @@ import useAlertStore from "../../stores/alertStore";
import { useDarkStore } from "../../stores/darkStore"; import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useShortcutsStore } from "../../stores/shortcuts";
import { useTypesStore } from "../../stores/typesStore"; import { useTypesStore } from "../../stores/typesStore";
import { VertexBuildTypeAPI } from "../../types/api"; import { VertexBuildTypeAPI } from "../../types/api";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
@ -36,8 +38,6 @@ import useValidationStatusString from "../hooks/use-validation-status-string";
import getFieldTitle from "../utils/get-field-title"; import getFieldTitle from "../utils/get-field-title";
import sortFields from "../utils/sort-fields"; import sortFields from "../utils/sort-fields";
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
import { useShortcutsStore } from "../../stores/shortcuts";
import Markdown from "react-markdown";
export default function GenericNode({ export default function GenericNode({
data, data,
@ -108,11 +108,7 @@ export default function GenericNode({
}; };
const renderIconStatus = () => { const renderIconStatus = () => {
return ( return iconStatus;
<div className="generic-node-status-position flex items-center justify-center">
{iconStatus}
</div>
);
}; };
const getNodeBorderClassName = ( const getNodeBorderClassName = (
@ -349,7 +345,7 @@ export default function GenericNode({
/> />
</div> </div>
) : ( ) : (
<div className="group flex items-start gap-1.5"> <div className="group flex items-center gap-2">
<ShadTooltip content={data.node?.display_name}> <ShadTooltip content={data.node?.display_name}>
<div <div
onDoubleClick={(event) => { onDoubleClick={(event) => {
@ -366,6 +362,22 @@ export default function GenericNode({
{data.node?.display_name} {data.node?.display_name}
</div> </div>
</ShadTooltip> </ShadTooltip>
{isOutdated && (
<ShadTooltip content={TOOLTIP_OUTDATED_NODE}>
<Button
onClick={handleUpdateCode}
variant="none"
size="none"
className={"group"}
loading={loadingUpdate}
>
<IconComponent
name="AlertTriangle"
className="h-5 w-5 fill-status-yellow text-muted"
/>
</Button>
</ShadTooltip>
)}
</div> </div>
)} )}
</div> </div>
@ -482,22 +494,31 @@ export default function GenericNode({
</div> </div>
{showNode && ( {showNode && (
<> <>
<div className="flex flex-shrink-0 items-center gap-1"> <div className="flex flex-shrink-0 items-center gap-3">
{isOutdated && ( <Button
<ShadTooltip content={TOOLTIP_OUTDATED_NODE}> onClick={() => {
<Button if (buildStatus === BuildStatus.BUILDING || isBuilding)
onClick={handleUpdateCode} return;
variant="secondary" setValidationStatus(null);
className={"h-9 px-1.5"} buildFlow({ stopNodeId: data.id });
loading={loadingUpdate} }}
> variant="none"
<IconComponent size="none"
name="AlertTriangle" className="group"
className="h-5 w-5 text-status-yellow" >
/> <div
</Button> data-testid={
</ShadTooltip> `button_run_` + data?.node?.display_name.toLowerCase()
)} }
>
<IconComponent
name="Play"
className={
"h-5 w-5 fill-current stroke-2 text-muted-foreground transition-all group-hover:text-medium-indigo group-hover/node:opacity-100"
}
/>
</div>
</Button>
<ShadTooltip <ShadTooltip
content={ content={
buildStatus === BuildStatus.BUILDING ? ( buildStatus === BuildStatus.BUILDING ? (
@ -527,24 +548,7 @@ export default function GenericNode({
} }
side="bottom" side="bottom"
> >
<Button {renderIconStatus()}
onClick={() => {
if (buildStatus === BuildStatus.BUILDING || isBuilding)
return;
setValidationStatus(null);
buildFlow({ stopNodeId: data.id });
}}
variant="secondary"
className={"group h-9 px-1.5"}
>
<div
data-testid={
`button_run_` + data?.node?.display_name.toLowerCase()
}
>
{renderIconStatus()}
</div>
</Button>
</ShadTooltip> </ShadTooltip>
</div> </div>
</> </>

View file

@ -1,7 +1,4 @@
import IconComponent from "../../components/genericIconComponent";
import Checkmark from "../../components/ui/checkmark";
import Loading from "../../components/ui/loading"; import Loading from "../../components/ui/loading";
import Xmark from "../../components/ui/xmark";
import { BuildStatus } from "../../constants/enums"; import { BuildStatus } from "../../constants/enums";
import { VertexBuildTypeAPI } from "../../types/api"; import { VertexBuildTypeAPI } from "../../types/api";
import { cn } from "../../utils/utils"; import { cn } from "../../utils/utils";
@ -24,35 +21,18 @@ const useIconStatus = (
return <Loading className="text-medium-indigo" />; return <Loading className="text-medium-indigo" />;
} else { } else {
return ( return (
<> <div
<IconComponent className={cn(
name="Play" "h-4 w-4 shrink-0 rounded-full",
className={cn( conditionSuccess
!conditionSuccess && !conditionInactive && !conditionError ? "bg-status-green"
? "opacity-100" : conditionInactive
: "opacity-0", ? "bg-status-gray"
"absolute ml-0.5 h-5 fill-current stroke-2 text-muted-foreground transition-all group-hover:text-medium-indigo group-hover/node:opacity-100", : conditionError
)} ? "bg-status-red"
/> : "bg-muted-foreground/40",
{conditionSuccess ? (
<Checkmark
className="absolute ml-0.5 h-5 stroke-2 text-status-green opacity-100 transition-all group-hover/node:opacity-0"
isVisible={true}
/>
) : conditionInactive ? (
<IconComponent
name="Play"
className="absolute ml-0.5 h-5 fill-current stroke-2 text-status-gray opacity-30 transition-all group-hover/node:opacity-0"
/>
) : conditionError ? (
<Xmark
isVisible={true}
className="absolute ml-0.5 h-5 fill-current stroke-2 text-status-red opacity-100 transition-all group-hover/node:opacity-0"
/>
) : (
<></>
)} )}
</> />
); );
} }
}; };

View file

@ -333,13 +333,13 @@
@apply relative flex flex-col justify-center bg-background transition-all; @apply relative flex flex-col justify-center bg-background transition-all;
} }
.generic-node-div-title { .generic-node-div-title {
@apply flex w-full items-center gap-2 border-b bg-muted p-4; @apply flex w-full items-center gap-2 border-b bg-muted p-5;
} }
.generic-node-title-arrangement { .generic-node-title-arrangement {
@apply flex-max-width items-center truncate; @apply flex-max-width items-center truncate;
} }
.generic-node-icon { .generic-node-icon {
@apply h-10 w-10 rounded p-1; @apply h-8 w-8 rounded;
} }
.generic-node-tooltip-div { .generic-node-tooltip-div {
@apply ml-2 max-w-[220px] truncate; @apply ml-2 max-w-[220px] truncate;