diff --git a/src/routes/v2/pages/Editor/EditorV2.tsx b/src/routes/v2/pages/Editor/EditorV2.tsx index 8495b249b..f93916b0a 100644 --- a/src/routes/v2/pages/Editor/EditorV2.tsx +++ b/src/routes/v2/pages/Editor/EditorV2.tsx @@ -41,6 +41,7 @@ import { usePipelineDetailsWindow } from "./hooks/usePipelineDetailsWindow"; import { usePipelineTreeWindow } from "./hooks/usePipelineTreeWindow"; import { usePropertiesWindowPositioning } from "./hooks/usePropertiesWindowPositioning"; import { useRecentRunsWindow } from "./hooks/useRecentRunsWindow"; +import { useRunsAndSubmissionWindow } from "./hooks/useRunsAndSubmissionWindow"; import { useSelectionWindowSync } from "./hooks/useSelectionWindowSync"; import { useSpecLifecycle } from "./hooks/useSpecLifecycle"; import { useUndoRedoKeyboard } from "./hooks/useUndoRedoKeyboard"; @@ -80,6 +81,7 @@ const PipelineEditor = withSuspenseWrapper( usePipelineTreeWindow(); useHistoryWindow(); useRecentRunsWindow(); + useRunsAndSubmissionWindow(); useUndoRedoKeyboard(); useFocusMode(); useShortcutListener(); diff --git a/src/routes/v2/pages/Editor/components/RunsAndSubmissionContent.tsx b/src/routes/v2/pages/Editor/components/RunsAndSubmissionContent.tsx new file mode 100644 index 000000000..a6db0aee0 --- /dev/null +++ b/src/routes/v2/pages/Editor/components/RunsAndSubmissionContent.tsx @@ -0,0 +1,77 @@ +import { observer } from "mobx-react-lite"; + +import { useAwaitAuthorization } from "@/components/shared/Authentication/useAwaitAuthorization"; +import { HuggingFaceAuthButton } from "@/components/shared/HuggingFaceAuth/HuggingFaceAuthButton"; +import GoogleCloudSubmissionDialog from "@/components/shared/Submitters/GoogleCloud/GoogleCloudSubmissionDialog"; +import TangleSubmitter from "@/components/shared/Submitters/Tangle/TangleSubmitter"; +import { Icon } from "@/components/ui/icon"; +import { BlockStack } from "@/components/ui/layout"; +import { Text } from "@/components/ui/typography"; +import { serializeComponentSpec } from "@/models/componentSpec"; +import { useSharedStores } from "@/routes/v2/shared/store/SharedStoreContext"; +import { ENABLE_GOOGLE_CLOUD_SUBMITTER } from "@/utils/constants"; +import { deepClone } from "@/utils/deepClone"; + +export const RunsAndSubmissionContent = observer(() => { + const { isAuthorized } = useAwaitAuthorization(); + const { navigation } = useSharedStores(); + const rootSpec = navigation.rootSpec; + const allIssues = rootSpec?.allValidationIssues ?? []; + const errorCount = allIssues.filter((i) => i.severity === "error").length; + const hasErrors = errorCount > 0; + + const serializedRootPipelineSpec = rootSpec + ? deepClone(serializeComponentSpec(rootSpec)) + : undefined; + + if (!serializedRootPipelineSpec) { + return ; + } + + return ( + + + {isAuthorized ? ( + 0} + /> + ) : ( + + )} + + {ENABLE_GOOGLE_CLOUD_SUBMITTER && ( + + )} + + + ); +}); + +function EmptyState() { + return ( + + + + No pipeline loaded + + + ); +} diff --git a/src/routes/v2/pages/Editor/hooks/useRunsAndSubmissionWindow.tsx b/src/routes/v2/pages/Editor/hooks/useRunsAndSubmissionWindow.tsx new file mode 100644 index 000000000..f42c861be --- /dev/null +++ b/src/routes/v2/pages/Editor/hooks/useRunsAndSubmissionWindow.tsx @@ -0,0 +1,27 @@ +import { useEffect } from "react"; + +import { RunsAndSubmissionContent } from "@/routes/v2/pages/Editor/components/RunsAndSubmissionContent"; +import { useSharedStores } from "@/routes/v2/shared/store/SharedStoreContext"; + +const RUNS_AND_SUBMISSION_WINDOW_ID = "runs-and-submission"; + +export function useRunsAndSubmissionWindow() { + const { windows } = useSharedStores(); + useEffect(() => { + if (!windows.getWindowById(RUNS_AND_SUBMISSION_WINDOW_ID)) { + windows.openWindow(, { + id: RUNS_AND_SUBMISSION_WINDOW_ID, + title: "Runs & Submissions", + position: { x: 100, y: 460 }, + size: { width: 280, height: 50 }, + minSize: { + width: 280, + height: 50, + }, + disabledActions: ["close"], + persisted: true, + defaultDockState: "left", + }); + } + }, [windows]); +} diff --git a/src/routes/v2/shared/windows/viewPresets.ts b/src/routes/v2/shared/windows/viewPresets.ts index 6858bc208..b2bae6eec 100644 --- a/src/routes/v2/shared/windows/viewPresets.ts +++ b/src/routes/v2/shared/windows/viewPresets.ts @@ -7,6 +7,7 @@ export interface ViewPreset { } const DEFAULT_DOCK_POSITIONS: Record = { + "runs-and-submission": "left", "component-library": "left", "pipeline-tree": "left", history: "left", @@ -18,8 +19,13 @@ const DEFAULT_DOCK_POSITIONS: Record = { export const DEFAULT_VIEW_PRESET: ViewPreset = { label: "Default", - description: "Components, Recent Runs, Pipeline Details", - visible: new Set(["component-library", "recent-runs", "pipeline-details"]), + description: "Components, Runs & Submissions, Recent Runs, Pipeline Details", + visible: new Set([ + "runs-and-submission", + "recent-runs", + "component-library", + "pipeline-details", + ]), dockPositions: DEFAULT_DOCK_POSITIONS, }; @@ -27,8 +33,10 @@ export const VIEW_PRESETS: ViewPreset[] = [ DEFAULT_VIEW_PRESET, { label: "All", - description: "All windows visible", + description: + "All windows visible, including Runs & Submissions and Recent Runs", visible: new Set([ + "runs-and-submission", "component-library", "history", "pipeline-tree", diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 5f3890919..3be064c03 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -22,6 +22,9 @@ export const GIT_REPO_URL = export const GIT_COMMIT = import.meta.env.VITE_GIT_COMMIT || "master"; +export const ENABLE_GOOGLE_CLOUD_SUBMITTER = + import.meta.env.VITE_ENABLE_GOOGLE_CLOUD_SUBMITTER === "true"; + export const USER_PIPELINES_LIST_NAME = "user_pipelines"; export const defaultPipelineYamlWithName = (name: string) => `