Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 7 additions & 1 deletion apps/docs/content/docs/en/tools/google_books.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ description: Search and retrieve book information

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
<BlockInfoCard
type="google_books"
color="#E0E0E0"
/>

{/* MANUAL-CONTENT-START:intro */}
[Google Books](https://books.google.com) is Google's comprehensive book discovery and metadata service, providing access to millions of books from publishers, libraries, and digitized collections worldwide. The Google Books API enables programmatic search and retrieval of detailed book information including titles, authors, descriptions, ratings, and publication details.

In Sim, the Google Books integration allows your agents to search for books and retrieve volume details as part of automated workflows. This enables use cases such as content research, reading list curation, bibliographic data enrichment, ISBN lookups, and knowledge gathering from published works. By connecting Sim with Google Books, your agents can discover and analyze book metadata, filter by availability or format, and incorporate literary references into their outputs—all without manual research.
{/* MANUAL-CONTENT-END */}

## Usage Instructions

Search for books using the Google Books API. Find volumes by title, author, ISBN, or keywords, and retrieve detailed information about specific books including descriptions, ratings, and publication details.
Expand Down
4 changes: 3 additions & 1 deletion apps/docs/content/docs/en/tools/table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ description: User-defined data tables for storing and querying structured data

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
<BlockInfoCard
type="table"
color="#10B981"
/>

{/* MANUAL-CONTENT-START:intro */}
Tables allow you to create and manage custom data tables directly within Sim. Store, query, and manipulate structured data within your workflows without needing external database integrations.

**Why Use Tables?**
Expand All @@ -26,6 +27,7 @@ Tables allow you to create and manage custom data tables directly within Sim. St
- Batch operations for bulk inserts
- Bulk updates and deletes by filter
- Up to 10,000 rows per table, 100 tables per workspace
{/* MANUAL-CONTENT-END */}

## Creating Tables

Expand Down
10 changes: 10 additions & 0 deletions apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2534,6 +2534,16 @@ const WorkflowContent = React.memo(() => {
window.removeEventListener('remove-from-subflow', handleRemoveFromSubflow as EventListener)
}, [blocks, edgesForDisplay, getNodeAbsolutePosition, collaborativeBatchUpdateParent])

useEffect(() => {
const handleToggleWorkflowLock = (e: CustomEvent<{ blockIds: string[] }>) => {
collaborativeBatchToggleLocked(e.detail.blockIds)
}

window.addEventListener('toggle-workflow-lock', handleToggleWorkflowLock as EventListener)
return () =>
window.removeEventListener('toggle-workflow-lock', handleToggleWorkflowLock as EventListener)
}, [collaborativeBatchToggleLocked])

/**
* Updates container dimensions in displayNodes during drag or keyboard movement.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,24 @@ interface ContextMenuProps {
* Set to true when user cannot leave (e.g., last admin)
*/
disableLeave?: boolean
/**
* Callback when lock/unlock is clicked
*/
onToggleLock?: () => void
/**
* Whether to show the lock option (default: false)
* Set to true for workflows that support locking
*/
showLock?: boolean
/**
* Whether the lock option is disabled (default: false)
* Set to true when user lacks permissions
*/
disableLock?: boolean
/**
* Whether the workflow is currently locked (all blocks locked)
*/
isLocked?: boolean
}

/**
Expand Down Expand Up @@ -321,6 +339,10 @@ export function ContextMenu({
onLeave,
showLeave = false,
disableLeave = false,
onToggleLock,
showLock = false,
disableLock = false,
isLocked = false,
}: ContextMenuProps) {
const [hexInput, setHexInput] = useState(currentColor || '#ffffff')

Expand Down Expand Up @@ -372,7 +394,8 @@ export function ContextMenu({
(showRename && onRename) ||
(showCreate && onCreate) ||
(showCreateFolder && onCreateFolder) ||
(showColorChange && onColorChange)
(showColorChange && onColorChange) ||
(showLock && onToggleLock)
const hasCopySection = (showDuplicate && onDuplicate) || (showExport && onExport)

return (
Expand Down Expand Up @@ -495,6 +518,19 @@ export function ContextMenu({
</PopoverFolder>
)}

{showLock && onToggleLock && (
<PopoverItem
rootOnly
disabled={disableLock}
onClick={() => {
onToggleLock()
onClose()
}}
>
{isLocked ? 'Unlock' : 'Lock'}
</PopoverItem>
)}

{/* Copy and export actions */}
{hasEditSection && hasCopySection && <PopoverDivider rootOnly />}
{showDuplicate && onDuplicate && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { useFolderStore } from '@/stores/folders/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'

interface WorkflowItemProps {
workflow: WorkflowMetadata
Expand Down Expand Up @@ -169,6 +170,25 @@ export function WorkflowItem({
[workflow.id, updateWorkflow]
)

const activeWorkflowId = useWorkflowRegistry((state) => state.activeWorkflowId)
const isActiveWorkflow = workflow.id === activeWorkflowId

const allBlocksLocked = useWorkflowStore(
useCallback((state) => {
const blockValues = Object.values(state.blocks)
if (blockValues.length === 0) return false
return blockValues.every((block) => block.locked)
}, [])
)
Comment thread
waleedlatif1 marked this conversation as resolved.
Outdated
const isWorkflowLocked = isActiveWorkflow && allBlocksLocked

const handleToggleLock = useCallback(() => {
if (!isActiveWorkflow) return
const blockIds = Object.keys(useWorkflowStore.getState().blocks)
if (blockIds.length === 0) return
window.dispatchEvent(new CustomEvent('toggle-workflow-lock', { detail: { blockIds } }))
Comment thread
waleedlatif1 marked this conversation as resolved.
}, [isActiveWorkflow])

const isEditingRef = useRef(false)

const {
Expand Down Expand Up @@ -461,6 +481,10 @@ export function WorkflowItem({
disableExport={!userPermissions.canEdit}
disableColorChange={!userPermissions.canEdit}
disableDelete={!userPermissions.canEdit || !canDeleteSelection}
onToggleLock={handleToggleLock}
showLock={isActiveWorkflow && !isMixedSelection && selectedWorkflows.size <= 1}
disableLock={!userPermissions.canAdmin}
isLocked={isWorkflowLocked}
/>

<DeleteModal
Expand Down