add Use Script Cache toggle; align toggles to right-hand side (#3121)
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
import { flushSync } from "react-dom";
|
||||
import Draggable from "react-draggable";
|
||||
|
||||
import { OrgWalled } from "./Orgwalled";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -627,7 +628,11 @@ function FloatingWindow({
|
||||
onClick={toggleMaximized}
|
||||
/>
|
||||
)}
|
||||
{showPowerButton && <PowerButton onClick={() => cycle()} />}
|
||||
{showPowerButton && (
|
||||
<OrgWalled className="flex items-center justify-center">
|
||||
<PowerButton onClick={() => cycle()} />
|
||||
</OrgWalled>
|
||||
)}
|
||||
</div>
|
||||
<div className="ml-auto">{title}</div>
|
||||
{showReloadButton && (
|
||||
|
||||
46
skyvern-frontend/src/components/Orgwalled.tsx
Normal file
46
skyvern-frontend/src/components/Orgwalled.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useIsSkyvernUser } from "@/hooks/useIsSkyvernUser";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
|
||||
import { cn } from "@/util/utils";
|
||||
|
||||
function OrgWalled({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
const isSkyvernUser = useIsSkyvernUser();
|
||||
|
||||
if (!isSkyvernUser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Wrap children with visual indication for org-walled features
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
className={cn(
|
||||
"relative rounded-md border-2 border-dashed border-yellow-400 p-2",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>This feature is only available to Skyvern organization members</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export { OrgWalled };
|
||||
11
skyvern-frontend/src/hooks/useIsSkyvernUser.ts
Normal file
11
skyvern-frontend/src/hooks/useIsSkyvernUser.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useUser } from "./useUser";
|
||||
|
||||
function useIsSkyvernUser() {
|
||||
const user = useUser().get();
|
||||
const email = user?.email;
|
||||
const isSkyvernUser = email?.toLowerCase().endsWith("@skyvern.com") ?? false;
|
||||
|
||||
return isSkyvernUser;
|
||||
}
|
||||
|
||||
export { useIsSkyvernUser };
|
||||
@@ -349,6 +349,7 @@ function FlowRenderer({
|
||||
max_screenshot_scrolls: data.settings.maxScreenshotScrolls,
|
||||
totp_verification_url: workflow.totp_verification_url,
|
||||
extra_http_headers: extraHttpHeaders,
|
||||
use_cache: data.settings.useScriptCache,
|
||||
workflow_definition: {
|
||||
parameters: data.parameters,
|
||||
blocks: data.blocks,
|
||||
|
||||
@@ -24,7 +24,6 @@ import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||
import { useMountEffect } from "@/hooks/useMountEffect";
|
||||
import { useUser } from "@/hooks/useUser";
|
||||
import { statusIsFinalized } from "@/routes/tasks/types.ts";
|
||||
import { useSidebarStore } from "@/store/SidebarStore";
|
||||
import { useWorkflowHasChangesStore } from "@/store/WorkflowHasChangesStore";
|
||||
@@ -44,9 +43,6 @@ function WorkflowDebugger() {
|
||||
const credentialGetter = useCredentialGetter();
|
||||
const queryClient = useQueryClient();
|
||||
const [shouldFetchDebugSession, setShouldFetchDebugSession] = useState(false);
|
||||
const user = useUser().get();
|
||||
const email = user?.email;
|
||||
const isSkyvernUser = email?.toLowerCase().endsWith("@skyvern.com") ?? false;
|
||||
|
||||
const { data: workflowRun } = useWorkflowRunQuery();
|
||||
const { data: workflow } = useWorkflowQuery({
|
||||
@@ -157,6 +153,7 @@ function WorkflowDebugger() {
|
||||
extraHttpHeaders: workflow.extra_http_headers
|
||||
? JSON.stringify(workflow.extra_http_headers)
|
||||
: null,
|
||||
useScriptCache: workflow.use_cache,
|
||||
};
|
||||
|
||||
const elements = getElements(
|
||||
@@ -235,7 +232,7 @@ function WorkflowDebugger() {
|
||||
initialHeight={360}
|
||||
showMaximizeButton={true}
|
||||
showMinimizeButton={true}
|
||||
showPowerButton={blockLabel === undefined && isSkyvernUser}
|
||||
showPowerButton={blockLabel === undefined}
|
||||
showReloadButton={true}
|
||||
// --
|
||||
onCycle={handleOnCycle}
|
||||
|
||||
@@ -58,6 +58,7 @@ function WorkflowEditor() {
|
||||
extraHttpHeaders: workflow.extra_http_headers
|
||||
? JSON.stringify(workflow.extra_http_headers)
|
||||
: null,
|
||||
useScriptCache: workflow.use_cache,
|
||||
};
|
||||
|
||||
const elements = getElements(
|
||||
|
||||
@@ -22,6 +22,7 @@ import { ModelSelector } from "@/components/ModelSelector";
|
||||
import { WorkflowModel } from "@/routes/workflows/types/workflowTypes";
|
||||
import { MAX_SCREENSHOT_SCROLLS_DEFAULT } from "../Taskv2Node/types";
|
||||
import { KeyValueInput } from "@/components/KeyValueInput";
|
||||
import { OrgWalled } from "@/components/Orgwalled";
|
||||
import { useWorkflowSettingsStore } from "@/store/WorkflowSettingsStore";
|
||||
|
||||
function StartNode({ id, data }: NodeProps<StartNode>) {
|
||||
@@ -59,6 +60,7 @@ function StartNode({ id, data }: NodeProps<StartNode>) {
|
||||
? data.maxScreenshotScrolls
|
||||
: null,
|
||||
extraHttpHeaders: data.withWorkflowSettings ? data.extraHttpHeaders : null,
|
||||
useScriptCache: data.withWorkflowSettings ? data.useScriptCache : false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -131,11 +133,27 @@ function StartNode({ id, data }: NodeProps<StartNode>) {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<OrgWalled>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label>Use Script Cache</Label>
|
||||
<HelpTooltip content="Generate & use cached scripts for faster execution" />
|
||||
<Switch
|
||||
className="ml-auto"
|
||||
checked={inputs.useScriptCache}
|
||||
onCheckedChange={(value) => {
|
||||
handleChange("useScriptCache", value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</OrgWalled>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label>Save & Reuse Session</Label>
|
||||
<HelpTooltip content="Persist session information across workflow runs" />
|
||||
<Switch
|
||||
className="ml-auto"
|
||||
checked={inputs.persistBrowserSession}
|
||||
onCheckedChange={(value) => {
|
||||
handleChange("persistBrowserSession", value);
|
||||
|
||||
@@ -12,6 +12,7 @@ export type WorkflowStartNodeData = {
|
||||
maxScreenshotScrolls: number | null;
|
||||
extraHttpHeaders: string | null;
|
||||
editable: boolean;
|
||||
useScriptCache: boolean;
|
||||
};
|
||||
|
||||
export type OtherStartNodeData = {
|
||||
|
||||
@@ -698,6 +698,7 @@ function getElements(
|
||||
maxScreenshotScrolls: settings.maxScreenshotScrolls,
|
||||
extraHttpHeaders: settings.extraHttpHeaders,
|
||||
editable,
|
||||
useScriptCache: settings.useScriptCache,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1400,6 +1401,7 @@ function getWorkflowSettings(nodes: Array<AppNode>): WorkflowSettings {
|
||||
model: null,
|
||||
maxScreenshotScrolls: null,
|
||||
extraHttpHeaders: null,
|
||||
useScriptCache: false,
|
||||
};
|
||||
const startNodes = nodes.filter(isStartNode);
|
||||
const startNodeWithWorkflowSettings = startNodes.find(
|
||||
@@ -1417,6 +1419,7 @@ function getWorkflowSettings(nodes: Array<AppNode>): WorkflowSettings {
|
||||
model: data.model,
|
||||
maxScreenshotScrolls: data.maxScreenshotScrolls,
|
||||
extraHttpHeaders: data.extraHttpHeaders,
|
||||
useScriptCache: data.useScriptCache,
|
||||
};
|
||||
}
|
||||
return defaultSettings;
|
||||
|
||||
@@ -501,6 +501,7 @@ export type WorkflowApiResponse = {
|
||||
created_at: string;
|
||||
modified_at: string;
|
||||
deleted_at: string | null;
|
||||
use_cache: boolean;
|
||||
};
|
||||
|
||||
export type WorkflowSettings = {
|
||||
@@ -510,6 +511,7 @@ export type WorkflowSettings = {
|
||||
model: WorkflowModel | null;
|
||||
maxScreenshotScrolls: number | null;
|
||||
extraHttpHeaders: string | null;
|
||||
useScriptCache: boolean;
|
||||
};
|
||||
|
||||
export type WorkflowModel = JsonObjectExtendable<{ model_name: string }>;
|
||||
|
||||
@@ -14,6 +14,7 @@ export type WorkflowCreateYAMLRequest = {
|
||||
is_saved_task?: boolean;
|
||||
max_screenshot_scrolls?: number | null;
|
||||
extra_http_headers?: Record<string, string> | null;
|
||||
use_cache?: boolean;
|
||||
};
|
||||
|
||||
export type WorkflowDefinitionYAML = {
|
||||
|
||||
Reference in New Issue
Block a user