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 && (
<ShadTooltip content={TOOLTIP_OUTDATED_NODE}>
<Button <Button
onClick={handleUpdateCode} onClick={() => {
variant="secondary" if (buildStatus === BuildStatus.BUILDING || isBuilding)
className={"h-9 px-1.5"} return;
loading={loadingUpdate} setValidationStatus(null);
buildFlow({ stopNodeId: data.id });
}}
variant="none"
size="none"
className="group"
>
<div
data-testid={
`button_run_` + data?.node?.display_name.toLowerCase()
}
> >
<IconComponent <IconComponent
name="AlertTriangle" name="Play"
className="h-5 w-5 text-status-yellow" 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> </Button>
</ShadTooltip>
)}
<ShadTooltip <ShadTooltip
content={ content={
buildStatus === BuildStatus.BUILDING ? ( buildStatus === BuildStatus.BUILDING ? (
@ -526,25 +547,8 @@ export default function GenericNode({
) )
} }
side="bottom" side="bottom"
>
<Button
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()} {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
name="Play"
className={cn( className={cn(
!conditionSuccess && !conditionInactive && !conditionError "h-4 w-4 shrink-0 rounded-full",
? "opacity-100" conditionSuccess
: "opacity-0", ? "bg-status-green"
"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", : conditionInactive
? "bg-status-gray"
: 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;