/** * ObjectUI * Copyright (c) 2024-present ObjectStack Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * @object-ui/types - UI Action Schema * * ObjectStack Spec v2.0.1 compliant action schema with enhanced capabilities: * - Location-based action placement * - Parameter collection * - Conditional visibility and enablement * - Rich feedback mechanisms * * @module ui-action * @packageDocumentation */ import { z } from 'zod'; /** * Action placement locations. * * Single source of truth lives in `@objectstack/spec/ui` as * `ACTION_LOCATIONS` + `ActionLocationSchema` + `ActionLocation`. Re-export * here so existing `@object-ui/types` consumers keep working without coupling * them to a duplicated, drift-prone enum. To add a new location, edit * `packages/spec/src/ui/action.zod.ts` — every layer (spec, core, types, * Studio designer dropdowns) picks up the new value automatically. */ export type ActionLocation = 'list_toolbar' | 'list_item' | 'record_header' | 'record_more' | 'record_related' | 'record_section' | 'global_nav'; export declare const ACTION_LOCATIONS: readonly ["list_toolbar", "list_item", "record_header", "record_more", "record_related", "record_section", "global_nav"]; export declare const ActionLocationSchema: z.ZodEnum<{ list_toolbar: "list_toolbar"; list_item: "list_item"; record_header: "record_header"; record_more: "record_more"; record_related: "record_related"; record_section: "record_section"; global_nav: "global_nav"; }>; /** * Visual component type for actions * Canonical definition from @objectstack/spec/ui ActionSchema.component. */ export type ActionComponent = 'action:button' | 'action:icon' | 'action:menu' | 'action:group'; /** * Action execution type * Canonical definition from @objectstack/spec/ui ActionSchema.type. */ export type ActionType = 'script' | 'url' | 'modal' | 'flow' | 'api'; /** * Field type for action parameters * Subset of field types commonly used in action parameter collection UIs. * Aligned with the field types available in @objectstack/spec ActionParamSchema. */ export type ActionParamFieldType = 'text' | 'textarea' | 'number' | 'boolean' | 'date' | 'datetime' | 'time' | 'select' | 'email' | 'phone' | 'url' | 'password' | 'file' | 'color' | 'slider' | 'rating'; /** * Action parameter definition (ObjectStack Spec v2.0.1) */ export interface ActionParam { /** Parameter name (snake_case) */ name: string; /** Display label */ label: string; /** Field type for input */ type: ActionParamFieldType; /** Whether parameter is required */ required?: boolean; /** Options for select/picklist types */ options?: Array<{ label: string; value: string; }>; /** Default value */ defaultValue?: unknown; /** Help text */ helpText?: string; /** Placeholder text */ placeholder?: string; /** Validation expression */ validation?: string; } /** * Enhanced Action Schema (ObjectStack Spec v2.0.1) * * This is the primary action schema that should be used for all new implementations. * The legacy ActionSchema in crud.ts is maintained for backward compatibility. */ export interface ActionSchema { /** Unique action identifier (snake_case) */ name: string; /** Display label */ label: string; /** Optional icon (Lucide icon name) */ icon?: string; /** Where to show this action (defaults to ['record_header']) */ locations?: ActionLocation[]; /** Visual component type (defaults to 'action:button') */ component?: ActionComponent; /** Action execution type */ type: ActionType; /** Target for the action (URL, script name, etc.) */ target?: string; /** Script to execute (for type: 'script') */ execute?: string; /** API endpoint (for type: 'api') */ endpoint?: string; /** HTTP method (for type: 'api') */ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; /** Input parameters to collect before execution */ params?: ActionParam[]; /** Confirmation text to show before execution */ confirmText?: string; /** Success message to show after execution */ successMessage?: string; /** Error message to show on failure */ errorMessage?: string; /** Whether to refresh data after execution */ refreshAfter?: boolean; /** Toast notification configuration */ toast?: { /** Show toast on success */ showOnSuccess?: boolean; /** Show toast on error */ showOnError?: boolean; /** Toast duration in milliseconds */ duration?: number; }; /** Expression controlling visibility (e.g., "status === 'draft'") */ visible?: string; /** Expression controlling enabled state (e.g., "hasPermission('edit')") */ enabled?: string; /** Button variant */ variant?: 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost'; /** Button size */ size?: 'sm' | 'md' | 'lg'; /** Custom CSS class */ className?: string; /** Action description */ description?: string; /** Permission required to execute */ permission?: string; /** Tags for categorization */ tags?: string[]; /** * UI-local escape hatch: synchronous/async callback invoked directly by * UI action renderers (e.g., `action:menu`) instead of routing through * {@link ActionEngine}. Intended for chrome-level concerns such as * toggling inline-edit mode, opening a native Share sheet, or copying the * URL to the clipboard — UI side-effects that are not part of the domain * action protocol and therefore need not be serialized over the wire. * * When present, `onClick` takes precedence over `type` / `target` / * `execute`. Prefer {@link ActionEngine}-routed actions for anything that * could originate from server-driven metadata. */ onClick?: () => void | Promise; } /** * Action group for organizing related actions */ export interface ActionGroup { /** Group name */ name: string; /** Display label */ label: string; /** Optional icon */ icon?: string; /** Actions in this group */ actions: ActionSchema[]; /** Group visibility condition */ visible?: string; /** Display as dropdown or inline */ display?: 'dropdown' | 'inline'; } /** * Action execution context */ export interface ActionContext { /** Current record data */ record?: Record; /** Selected records (for list actions) */ selectedRecords?: Record[]; /** Current user */ user?: Record; /** Additional context data */ [key: string]: any; } /** * Action execution result */ export interface ActionResult { /** Whether action succeeded */ success: boolean; /** Result data */ data?: any; /** Error message if failed */ error?: string; /** Whether to refresh data */ refresh?: boolean; /** Whether to close dialog/modal */ close?: boolean; } /** * Action executor function type */ export type ActionExecutor = (action: ActionSchema, context: ActionContext, params?: Record) => Promise; /** Batch operation configuration */ export interface BatchOperationConfig { /** Operation name */ name: string; /** Display label */ label: string; /** Target action to execute on each record */ action: string; /** Whether to run in parallel */ parallel?: boolean; /** Maximum concurrent operations */ concurrency?: number; /** Whether to continue on error */ continueOnError?: boolean; /** Progress callback expression */ onProgress?: string; /** Completion callback expression */ onComplete?: string; } /** Batch operation result */ export interface BatchOperationResult { /** Total items processed */ total: number; /** Successfully processed count */ succeeded: number; /** Failed count */ failed: number; /** Individual results */ results: Array<{ recordId: string; success: boolean; error?: string; }>; } /** Transaction isolation level */ export type TransactionIsolationLevel = 'read-uncommitted' | 'read-committed' | 'repeatable-read' | 'serializable'; /** Transaction configuration */ export interface TransactionConfig { /** Transaction name for identification */ name?: string; /** Isolation level */ isolation?: TransactionIsolationLevel; /** Timeout in milliseconds */ timeout?: number; /** Actions to execute within the transaction */ actions: ActionSchema[]; /** Rollback action on failure */ rollbackAction?: string; /** Whether to auto-retry on conflict */ retryOnConflict?: boolean; /** Maximum retry attempts */ maxRetries?: number; } /** Transaction result */ export interface TransactionResult { /** Whether all actions succeeded */ success: boolean; /** Transaction ID */ transactionId: string; /** Individual action results */ actionResults: ActionResult[]; /** Error if transaction failed */ error?: string; /** Whether the transaction was rolled back */ rolledBack?: boolean; } /** Undo/redo operation entry */ export interface UndoRedoEntry { /** Entry identifier */ id: string; /** Action that was performed */ action: string; /** Description of the action */ description: string; /** Timestamp */ timestamp: string; /** Data before the action (for undo) */ previousState: Record; /** Data after the action (for redo) */ nextState: Record; /** Target object */ object?: string; /** Target record ID */ recordId?: string; } /** Undo/redo configuration */ export interface UndoRedoConfig { /** Enable undo/redo */ enabled: boolean; /** Maximum history size */ maxHistorySize?: number; /** Actions that support undo */ undoableActions?: string[]; /** Whether to group rapid changes */ groupChanges?: boolean; /** Group timeout in milliseconds */ groupTimeout?: number; } /** Undo/redo state */ export interface UndoRedoState { /** Whether undo is available */ canUndo: boolean; /** Whether redo is available */ canRedo: boolean; /** Undo stack */ undoStack: UndoRedoEntry[]; /** Redo stack */ redoStack: UndoRedoEntry[]; /** Current position in history */ currentIndex: number; } //# sourceMappingURL=ui-action.d.ts.map