diff --git a/src/components/machine/machine-schema.tsx b/src/components/machine/machine-schema.tsx index e834ebc0..23c80412 100644 --- a/src/components/machine/machine-schema.tsx +++ b/src/components/machine/machine-schema.tsx @@ -166,6 +166,11 @@ export const serverlessFormSchema = z.object({ .default(true) .optional() .describe("Disable metadata"), + hide_community_uploads: z + .boolean() + .default(false) + .optional() + .describe("Hide community uploads"), cpu_request: z.number().describe("CPU request").nullable().optional(), cpu_limit: z.number().describe("CPU limit").nullable().optional(), memory_request: z.number().describe("Memory request").nullable().optional(), diff --git a/src/components/machine/machine-settings.tsx b/src/components/machine/machine-settings.tsx index 40b93d24..96fd9d54 100644 --- a/src/components/machine/machine-settings.tsx +++ b/src/components/machine/machine-settings.tsx @@ -389,6 +389,7 @@ function ServerlessSettings({ extra_args: machine.extra_args, disable_metadata: machine.disable_metadata, prestart_command: machine.prestart_command, + hide_community_uploads: machine.hide_community_uploads ?? false, optimized_runner: machine.optimized_runner, models_to_cache: machine.models_to_cache || [], @@ -984,6 +985,26 @@ function ServerlessSettings({ )} /> + + ( + + Hide Community Uploads + + Hide community models and uploads from view + + + + + + )} + /> diff --git a/src/components/models/folder-tree.tsx b/src/components/models/folder-tree.tsx index 1330911a..583191f1 100644 --- a/src/components/models/folder-tree.tsx +++ b/src/components/models/folder-tree.tsx @@ -47,7 +47,7 @@ import { } from "lucide-react"; import { useQueryState } from "nuqs"; import type React from "react"; -import { useMemo, useState } from "react"; +import { useMemo, useState, useEffect } from "react"; import { toast } from "sonner"; // Format file size to human-readable format (KB, MB, GB) @@ -71,6 +71,7 @@ interface FileEntry { interface FolderTreeProps { className?: string; onAddModel: (folderPath: string) => void; + machine?: any; // Optional machine prop to access settings } interface TreeNode { @@ -903,7 +904,7 @@ function mergeNodes( return result; } -export function FolderTree({ className, onAddModel }: FolderTreeProps) { +export function FolderTree({ className, onAddModel, machine }: FolderTreeProps) { const queryClient = useQueryClient(); const [search, setSearch] = useState(""); const [filter, setFilter] = useQueryState("model_view", { @@ -922,6 +923,16 @@ export function FolderTree({ className, onAddModel }: FolderTreeProps) { const [sortBy, setSortBy] = useState<"name" | "size">("name"); const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc"); + // Check if community uploads should be hidden based on machine setting + const shouldHideCommunityUploads = machine?.hide_community_uploads ?? false; + + // Auto-set filter to private if community uploads are hidden and current filter is public/all + useEffect(() => { + if (shouldHideCommunityUploads && (filter === "public" || filter === "all")) { + setFilter("private"); + } + }, [shouldHideCommunityUploads, filter, setFilter]); + const { data: privateFiles, isLoading: isLoadingPrivate } = useQuery< FileEntry[] >({ @@ -929,14 +940,16 @@ export function FolderTree({ className, onAddModel }: FolderTreeProps) { refetchInterval: 5000, }); + // Only load public files if community uploads are not hidden const { data: publicFiles, isLoading: isLoadingPublic } = useQuery< FileEntry[] >({ queryKey: ["volume", "public-models"], + enabled: !shouldHideCommunityUploads, }); const privateTree = privateFiles ? buildTree(privateFiles, true) : []; - const publicTree = publicFiles ? buildTree(publicFiles, false) : []; + const publicTree = publicFiles && !shouldHideCommunityUploads ? buildTree(publicFiles, false) : []; const injectFrontendFolders = ( tree: TreeNode[], @@ -1013,7 +1026,7 @@ export function FolderTree({ className, onAddModel }: FolderTreeProps) { injectedPrivateTree, publicTree, filter === "private" || filter === "all", - filter === "public" || filter === "all", + (filter === "public" || filter === "all") && !shouldHideCommunityUploads, ); // Apply sorting to the merged tree @@ -1268,32 +1281,36 @@ export function FolderTree({ className, onAddModel }: FolderTreeProps) { Private - - - Public - - - - - All - - + {!shouldHideCommunityUploads && ( + <> + + + Public + + + + + All + + + + )} @@ -1338,7 +1355,9 @@ export function FolderTree({ className, onAddModel }: FolderTreeProps) { {filter === "all" ? "No models available. Upload models to your folders or create a new folder." : filter === "private" - ? "No private models found. Upload models to your folders or create a new folder." + ? shouldHideCommunityUploads + ? "No private models found. Community uploads are hidden for this machine. Upload models to your folders or create a new folder." + : "No private models found. Upload models to your folders or create a new folder." : "No public models available at the moment."}

{/* Allow upload even for public filter */} diff --git a/src/routes/models.tsx b/src/routes/models.tsx index 18b06865..960ab4cb 100644 --- a/src/routes/models.tsx +++ b/src/routes/models.tsx @@ -12,7 +12,11 @@ export const Route = createFileRoute("/models")({ export function StoragePage({ isWorkflowPage = false, -}: { isWorkflowPage?: boolean }) { + machine, +}: { + isWorkflowPage?: boolean; + machine?: any; +}) { const [showAddModel, setShowAddModel] = useState(false); const [selectedFolderPath, setSelectedFolderPath] = useState(""); @@ -41,7 +45,7 @@ export function StoragePage({ } > - + diff --git a/src/routes/workflows/$workflowId/$view.lazy.tsx b/src/routes/workflows/$workflowId/$view.lazy.tsx index 71e1405f..f65d1d54 100644 --- a/src/routes/workflows/$workflowId/$view.lazy.tsx +++ b/src/routes/workflows/$workflowId/$view.lazy.tsx @@ -190,7 +190,7 @@ function WorkflowPageComponent() { ); break; case "model": - view = ; + view = ; break; } diff --git a/src/types/machine.ts b/src/types/machine.ts index bec2ca33..fa1d156e 100644 --- a/src/types/machine.ts +++ b/src/types/machine.ts @@ -33,6 +33,7 @@ export interface Machine { install_custom_node_with_gpu?: boolean; optimized_runner?: boolean; disable_metadata?: boolean; + hide_community_uploads?: boolean; // Resource settings cpu_request?: number | null; @@ -79,6 +80,7 @@ export interface MachineVersion { prestart_command?: string; keep_warm: number; disable_metadata?: boolean; + hide_community_uploads?: boolean; allow_concurrent_inputs?: number; machine_builder_version?: string; cpu_request?: number | null;