mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
improvement(ux): manual run opens console
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
Bug,
|
||||
ChevronDown,
|
||||
Copy,
|
||||
CreditCard,
|
||||
History,
|
||||
Loader2,
|
||||
Play,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
Store,
|
||||
Trash2,
|
||||
X,
|
||||
CreditCard,
|
||||
} from 'lucide-react'
|
||||
import {
|
||||
AlertDialog,
|
||||
@@ -38,10 +38,12 @@ import {
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { useSession } from '@/lib/auth-client'
|
||||
import { createLogger } from '@/lib/logs/console-logger'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useExecutionStore } from '@/stores/execution/store'
|
||||
import { useNotificationStore } from '@/stores/notifications/store'
|
||||
import { usePanelStore } from '@/stores/panel/store'
|
||||
import { useGeneralStore } from '@/stores/settings/general/store'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
|
||||
@@ -52,7 +54,6 @@ import { DeploymentControls } from './components/deployment-controls/deployment-
|
||||
import { HistoryDropdownItem } from './components/history-dropdown-item/history-dropdown-item'
|
||||
import { MarketplaceModal } from './components/marketplace-modal/marketplace-modal'
|
||||
import { NotificationDropdownItem } from './components/notification-dropdown-item/notification-dropdown-item'
|
||||
import { useSession } from '@/lib/auth-client'
|
||||
|
||||
const logger = createLogger('ControlBar')
|
||||
|
||||
@@ -61,7 +62,7 @@ let usageDataCache = {
|
||||
data: null,
|
||||
timestamp: 0,
|
||||
// Cache expires after 1 minute
|
||||
expirationMs: 60 * 1000
|
||||
expirationMs: 60 * 1000,
|
||||
}
|
||||
|
||||
// Predefined run count options
|
||||
@@ -88,6 +89,7 @@ export function ControlBar() {
|
||||
const { workflows, updateWorkflow, activeWorkflowId, removeWorkflow, duplicateWorkflow } =
|
||||
useWorkflowRegistry()
|
||||
const { isExecuting, handleRunWorkflow } = useWorkflowExecution()
|
||||
const { setActiveTab } = usePanelStore()
|
||||
|
||||
// Debug mode state
|
||||
const { isDebugModeEnabled, toggleDebugMode } = useGeneralStore()
|
||||
@@ -361,7 +363,7 @@ export function ControlBar() {
|
||||
// Check usage limits when component mounts and when user executes a workflow
|
||||
useEffect(() => {
|
||||
if (session?.user?.id) {
|
||||
checkUserUsage(session.user.id).then(usage => {
|
||||
checkUserUsage(session.user.id).then((usage) => {
|
||||
if (usage) {
|
||||
setUsageExceeded(usage.isExceeded)
|
||||
setUsageData(usage)
|
||||
@@ -379,28 +381,28 @@ export function ControlBar() {
|
||||
async function checkUserUsage(userId: string, forceRefresh = false): Promise<any | null> {
|
||||
const now = Date.now()
|
||||
const cacheAge = now - usageDataCache.timestamp
|
||||
|
||||
|
||||
// Use cache if available and not expired
|
||||
if (!forceRefresh && usageDataCache.data && cacheAge < usageDataCache.expirationMs) {
|
||||
logger.info('Using cached usage data', { cacheAge: `${Math.round(cacheAge/1000)}s` })
|
||||
logger.info('Using cached usage data', { cacheAge: `${Math.round(cacheAge / 1000)}s` })
|
||||
return usageDataCache.data
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/user/usage')
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch usage data')
|
||||
}
|
||||
|
||||
|
||||
const usage = await response.json()
|
||||
|
||||
|
||||
// Update cache
|
||||
usageDataCache = {
|
||||
data: usage,
|
||||
timestamp: now,
|
||||
expirationMs: usageDataCache.expirationMs
|
||||
expirationMs: usageDataCache.expirationMs,
|
||||
}
|
||||
|
||||
|
||||
return usage
|
||||
} catch (error) {
|
||||
logger.error('Error checking usage limits:', { error })
|
||||
@@ -478,13 +480,16 @@ export function ControlBar() {
|
||||
*/
|
||||
const handleMultipleRuns = async () => {
|
||||
if (isExecuting || isMultiRunning || runCount <= 0) return
|
||||
|
||||
|
||||
// Check if usage is exceeded before allowing execution
|
||||
if (usageExceeded) {
|
||||
openSubscriptionSettings()
|
||||
return
|
||||
}
|
||||
|
||||
// Switch panel tab to console
|
||||
setActiveTab('console')
|
||||
|
||||
// Reset state and ref for a new batch of runs
|
||||
setCompletedRuns(0)
|
||||
setIsMultiRunning(true)
|
||||
@@ -511,22 +516,22 @@ export function ControlBar() {
|
||||
await handleRunWorkflow()
|
||||
runCounter = i + 1
|
||||
setCompletedRuns(runCounter)
|
||||
|
||||
|
||||
// Only check usage periodically to avoid excessive API calls
|
||||
// Check on first run, every 5 runs, and on last run
|
||||
shouldCheckUsage = i === 0 || (i + 1) % 5 === 0 || i === runCount - 1
|
||||
|
||||
|
||||
// Check usage if needed
|
||||
if (shouldCheckUsage && session?.user?.id) {
|
||||
const usage = await checkUserUsage(session.user.id, i === 0)
|
||||
|
||||
|
||||
if (usage?.isExceeded) {
|
||||
setUsageExceeded(true)
|
||||
setUsageData(usage)
|
||||
// Stop execution if we've exceeded the limit during this batch
|
||||
if (i < runCount - 1) {
|
||||
addNotification(
|
||||
'info',
|
||||
'info',
|
||||
`Usage limit reached after ${runCounter} runs. Execution stopped.`,
|
||||
activeWorkflowId
|
||||
)
|
||||
@@ -949,12 +954,14 @@ export function ControlBar() {
|
||||
}
|
||||
|
||||
// Helper function to open subscription settings
|
||||
const openSubscriptionSettings = () => {
|
||||
const openSubscriptionSettings = () => {
|
||||
// Dispatch custom event to open settings modal with subscription tab
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new CustomEvent('open-settings', {
|
||||
detail: { tab: 'subscription' }
|
||||
}))
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('open-settings', {
|
||||
detail: { tab: 'subscription' },
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1001,7 +1008,13 @@ export function ControlBar() {
|
||||
? 'rounded py-2 px-4 h-10'
|
||||
: 'rounded-r-none border-r border-r-[#6420cc] py-2 px-4 h-10'
|
||||
)}
|
||||
onClick={usageExceeded ? openSubscriptionSettings : (isDebugModeEnabled ? handleRunWorkflow : handleMultipleRuns)}
|
||||
onClick={
|
||||
usageExceeded
|
||||
? openSubscriptionSettings
|
||||
: isDebugModeEnabled
|
||||
? handleRunWorkflow
|
||||
: handleMultipleRuns
|
||||
}
|
||||
disabled={isExecuting || isMultiRunning || isCancelling}
|
||||
>
|
||||
{isCancelling ? (
|
||||
@@ -1031,8 +1044,8 @@ export function ControlBar() {
|
||||
<div className="text-center">
|
||||
<p className="font-medium text-destructive">Usage Limit Exceeded</p>
|
||||
<p className="text-xs">
|
||||
You've used {usageData?.currentUsage.toFixed(2)}$ of {usageData?.limit}$.
|
||||
Upgrade your plan to continue.
|
||||
You've used {usageData?.currentUsage.toFixed(2)}$ of {usageData?.limit}$. Upgrade
|
||||
your plan to continue.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user