Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import { createPortal } from "react-dom";
import { HiOutlineCog6Tooth } from "react-icons/hi2";
import { useHotkeyDisplay } from "renderer/hotkeys";
import { useDashboardSidebarState } from "renderer/routes/_authenticated/hooks/useDashboardSidebarState";
import { useLocalHostService } from "renderer/routes/_authenticated/providers/LocalHostServiceProvider";
import { DashboardSidebarHeader } from "./components/DashboardSidebarHeader";
import { DashboardSidebarHelpMenu } from "./components/DashboardSidebarHelpMenu";
import { DashboardSidebarHoverCardOverlay } from "./components/DashboardSidebarHoverCardOverlay";
import { DashboardSidebarPortsList } from "./components/DashboardSidebarPortsList";
import { DashboardSidebarProjectSection } from "./components/DashboardSidebarProjectSection";
import { DashboardSidebarSectionRenameProvider } from "./components/DashboardSidebarSectionRenameContext";
import { V2SetupScriptCard } from "./components/V2SetupScriptCard";
import { useDashboardSidebarData } from "./hooks/useDashboardSidebarData";
import { useDashboardSidebarShortcuts } from "./hooks/useDashboardSidebarShortcuts";
import { DashboardSidebarHoverProvider } from "./providers/DashboardSidebarHoverProvider";
Expand Down Expand Up @@ -101,6 +103,9 @@ export function DashboardSidebar({
const matchRoute = useMatchRoute();
const settingsHotkey = useHotkeyDisplay("OPEN_SETTINGS").text;
const isSettingsOpen = !!matchRoute({ to: "/settings", fuzzy: true });
const { activeHostUrl } = useLocalHostService();
const v2RouteMatch = matchRoute({ to: "/v2-workspace/$workspaceId" });
const activeV2WorkspaceId = v2RouteMatch ? v2RouteMatch.workspaceId : null;

const sensors = useSensors(
useSensor(MouseSensor, { activationConstraint: { distance: 8 } }),
Expand Down Expand Up @@ -130,6 +135,26 @@ export function DashboardSidebar({
.filter((g): g is DashboardSidebarProject => g != null);
}, [groups, projectOrder]);

const activeV2Project = useMemo(() => {
if (!activeV2WorkspaceId) return null;
for (const project of groups) {
for (const child of project.children) {
if (
child.type === "workspace" &&
child.workspace.id === activeV2WorkspaceId
) {
return project;
}
if (child.type === "section") {
for (const ws of child.section.workspaces) {
if (ws.id === activeV2WorkspaceId) return project;
}
}
}
}
return null;
}, [groups, activeV2WorkspaceId]);

const handleDragEnd = useCallback(
({ active, over }: DragEndEvent) => {
if (over && active.id !== over.id) {
Expand Down Expand Up @@ -204,6 +229,13 @@ export function DashboardSidebar({
</DndContext>
</div>
{!isCollapsed && <DashboardSidebarPortsList />}
{!isCollapsed && activeV2Project && activeHostUrl && (
<V2SetupScriptCard
hostUrl={activeHostUrl}
projectId={activeV2Project.id}
projectName={activeV2Project.name}
/>
)}
<div
className={cn(
"border-t border-border",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { SidebarCard } from "@superset/ui/sidebar-card";
import { useQuery } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { AnimatePresence, motion } from "framer-motion";
import { getHostServiceClientByUrl } from "renderer/lib/host-service-client";
import { useV2SetupCardDismissalsStore } from "renderer/stores/v2-setup-card-dismissals";

interface V2SetupScriptCardProps {
hostUrl: string;
projectId: string;
projectName: string;
isCollapsed?: boolean;
}

export function V2SetupScriptCard({
hostUrl,
projectId,
projectName,
isCollapsed,
}: V2SetupScriptCardProps) {
const navigate = useNavigate();
const isDismissed = useV2SetupCardDismissalsStore((s) =>
s.isDismissed(projectId),
);
const dismiss = useV2SetupCardDismissalsStore((s) => s.dismiss);

const { data: shouldShow } = useQuery({
queryKey: ["host-config", "shouldShowSetupCard", hostUrl, projectId],
queryFn: () =>
getHostServiceClientByUrl(hostUrl).config.shouldShowSetupCard.query({
projectId,
}),
refetchOnWindowFocus: true,
});

if (isCollapsed || isDismissed || !shouldShow) return null;

return (
<AnimatePresence>
<motion.div
key={projectId}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ duration: 0.2 }}
className="px-3 pb-2"
>
<SidebarCard
badge="Setup"
title="Setup scripts"
description={`Automate workspace setup for ${projectName}`}
actionLabel="Configure"
onAction={() =>
navigate({
to: "/settings/projects/$projectId",
params: { projectId },
})
}
onDismiss={() => dismiss(projectId)}
/>
</motion.div>
</AnimatePresence>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { V2SetupScriptCard } from "./V2SetupScriptCard";
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { IconUploadField } from "./components/IconUploadField";
import { NameSection } from "./components/NameSection";
import { ProjectLocationSection } from "./components/ProjectLocationSection";
import { RepositorySection } from "./components/RepositorySection";
import { V2ScriptsEditor } from "./components/V2ScriptsEditor";

interface V2ProjectSettingsProps {
projectId: string;
Expand Down Expand Up @@ -81,6 +82,15 @@ export function V2ProjectSettings({ projectId }: V2ProjectSettingsProps) {
/>
</SettingsSection>

{activeHostUrl && (
<SettingsSection
title="Scripts"
description="Runs in a terminal when workspaces are created or deleted. Saved to .superset/config.json in the main repo."
>
<V2ScriptsEditor hostUrl={activeHostUrl} projectId={projectId} />
</SettingsSection>
)}

<div className="pt-2 border-t border-border">
<DeleteProjectSection
projectId={projectId}
Expand Down
Loading
Loading