Corrección 1 — Delete de proceso restaurado + Corrección 2 — Patrón userId en repos
This commit is contained in:
@@ -10,6 +10,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { useProcessStore } from '@/store/process-store'
|
||||
import { useAuth } from '@/auth/AuthContext'
|
||||
import { formatCurrency } from '@/lib/format'
|
||||
import type { Activity } from '@/domain/types'
|
||||
|
||||
@@ -19,6 +20,7 @@ interface ActivityPanelProps {
|
||||
|
||||
export function ActivityPanel({ selectedElementId }: ActivityPanelProps) {
|
||||
const { activities, resources, updateActivity, currentProcess } = useProcessStore()
|
||||
const { user } = useAuth()
|
||||
const [localActivity, setLocalActivity] = useState<Activity | null>(null)
|
||||
const [isDirty, setIsDirty] = useState(false)
|
||||
|
||||
@@ -42,7 +44,7 @@ export function ActivityPanel({ selectedElementId }: ActivityPanelProps) {
|
||||
|
||||
async function handleSave() {
|
||||
if (!localActivity) return
|
||||
await updateActivity(localActivity)
|
||||
await updateActivity(localActivity, user!.id)
|
||||
setIsDirty(false)
|
||||
}
|
||||
|
||||
|
||||
@@ -110,12 +110,17 @@ export function BpmnCanvas({
|
||||
if (!viewer || !xml) return
|
||||
isImportedRef.current = false
|
||||
viewer.importXML(xml).then(({ warnings }) => {
|
||||
// Si el viewer fue destruido y reemplazado (p.ej. React Strict Mode), ignorar
|
||||
if (viewerRef.current !== viewer) return
|
||||
if (warnings.length) console.warn('bpmn-js warnings:', warnings)
|
||||
const canvas = viewer.get('canvas') as any
|
||||
canvas.zoom('fit-viewport', 'auto')
|
||||
isImportedRef.current = true
|
||||
syncAutomationOverlays()
|
||||
}).catch((err: Error) => console.error('Error cargando BPMN:', err))
|
||||
}).catch((err: Error) => {
|
||||
if (viewerRef.current !== viewer) return
|
||||
console.error('Error cargando BPMN:', err)
|
||||
})
|
||||
}, [xml, syncAutomationOverlays])
|
||||
|
||||
// ─── Re-sincronizar overlays cuando cambia la lista de automatizables ─────
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Slider } from '@/components/ui/slider'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { useProcessStore } from '@/store/process-store'
|
||||
import { useAuth } from '@/auth/AuthContext'
|
||||
import { parseBpmnXml } from '@/domain/bpmn-parser'
|
||||
import { formatPercent } from '@/lib/format'
|
||||
import type { GatewayConfig } from '@/domain/types'
|
||||
@@ -28,6 +29,7 @@ export function isXorSumValid(gw: GatewayConfig): boolean {
|
||||
|
||||
export function GatewayPanel({ selectedElementId }: GatewayPanelProps) {
|
||||
const { gateways, currentProcess, updateGateway, activities } = useProcessStore()
|
||||
const { user } = useAuth()
|
||||
const [localGw, setLocalGw] = useState<GatewayConfig | null>(null)
|
||||
const [isDirty, setIsDirty] = useState(false)
|
||||
|
||||
@@ -82,7 +84,7 @@ export function GatewayPanel({ selectedElementId }: GatewayPanelProps) {
|
||||
|
||||
async function handleSave() {
|
||||
if (!localGw) return
|
||||
await updateGateway(localGw)
|
||||
await updateGateway(localGw, user!.id)
|
||||
setIsDirty(false)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { useProcessStore } from '@/store/process-store'
|
||||
import { useAuth } from '@/auth/AuthContext'
|
||||
import { formatPercent } from '@/lib/format'
|
||||
|
||||
const CURRENCIES = [
|
||||
@@ -24,6 +25,7 @@ const CURRENCIES = [
|
||||
|
||||
export function GlobalSettingsPanel() {
|
||||
const { currentProcess, updateProcess } = useProcessStore()
|
||||
const { user } = useAuth()
|
||||
const [localName, setLocalName] = useState('')
|
||||
const [localClient, setLocalClient] = useState('')
|
||||
const [localCurrency, setLocalCurrency] = useState('USD')
|
||||
@@ -57,7 +59,7 @@ export function GlobalSettingsPanel() {
|
||||
annualFrequency: Math.max(1, localFrequency),
|
||||
analysisHorizonYears: clampedHorizon,
|
||||
automationInvestment: Math.max(0, localInvestment),
|
||||
})
|
||||
}, user!.id)
|
||||
setLocalHorizon(clampedHorizon)
|
||||
setIsDirty(false)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { useProcessStore } from '@/store/process-store'
|
||||
import { useAuth } from '@/auth/AuthContext'
|
||||
import { formatCurrency } from '@/lib/format'
|
||||
import type { Resource, ResourceType } from '@/domain/types'
|
||||
|
||||
@@ -36,6 +37,7 @@ const EMPTY_FORM: ResourceFormState = { name: '', type: 'role', costPerHour: ''
|
||||
|
||||
export function ResourcesPanel() {
|
||||
const { currentProcess, resources, addResource, updateResource, deleteResource } = useProcessStore()
|
||||
const { user } = useAuth()
|
||||
const [showForm, setShowForm] = useState(false)
|
||||
const [editingId, setEditingId] = useState<string | null>(null)
|
||||
const [form, setForm] = useState<ResourceFormState>(EMPTY_FORM)
|
||||
@@ -65,7 +67,7 @@ export function ResourcesPanel() {
|
||||
if (editingId) {
|
||||
const existing = resources.find((r) => r.id === editingId)
|
||||
if (!existing) return
|
||||
await updateResource({ ...existing, name: form.name.trim(), type: form.type, costPerHour })
|
||||
await updateResource({ ...existing, name: form.name.trim(), type: form.type, costPerHour }, user!.id)
|
||||
} else {
|
||||
const newResource: Resource = {
|
||||
id: uuidv4(),
|
||||
@@ -74,7 +76,7 @@ export function ResourcesPanel() {
|
||||
type: form.type,
|
||||
costPerHour,
|
||||
}
|
||||
await addResource(newResource)
|
||||
await addResource(newResource, user!.id)
|
||||
}
|
||||
cancelForm()
|
||||
}
|
||||
@@ -186,7 +188,7 @@ export function ResourcesPanel() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-6 w-6 text-slate-400 hover:text-destructive"
|
||||
onClick={() => deleteResource(resource.id)}
|
||||
onClick={() => deleteResource(resource.id, user!.id)}
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { useProcessStore } from '@/store/process-store'
|
||||
import { useSimulationStore } from '@/store/simulation-store'
|
||||
import { useSimulate } from '../simulation/useSimulate'
|
||||
import { useLibraryStore } from '@/store/library-store'
|
||||
import { useAuth } from '@/auth/AuthContext'
|
||||
import { AppHeader } from '@/components/AppHeader'
|
||||
|
||||
type SelectedCategory = 'activity' | 'gateway' | null
|
||||
@@ -30,6 +31,7 @@ export function WorkspacePage() {
|
||||
const { isRunning, resultActual, error: simError, selectActivity, loadLatestForProcess, lastPersistedExecutedAt } = useSimulationStore()
|
||||
const { simulate } = useSimulate()
|
||||
const { toast } = useToast()
|
||||
const { user } = useAuth()
|
||||
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true)
|
||||
const [selectedElementId, setSelectedElementId] = useState<string | null>(null)
|
||||
@@ -122,12 +124,12 @@ export function WorkspacePage() {
|
||||
if (field === 'name') {
|
||||
const trimmed = editValue.trim()
|
||||
if (trimmed && trimmed !== currentProcess?.name) {
|
||||
await updateProcess({ name: trimmed })
|
||||
await updateProcess({ name: trimmed }, user!.id)
|
||||
}
|
||||
} else {
|
||||
const trimmed = editValue.trim()
|
||||
if (trimmed !== (currentProcess?.clientName ?? '')) {
|
||||
await updateProcess({ clientName: trimmed })
|
||||
await updateProcess({ clientName: trimmed }, user!.id)
|
||||
}
|
||||
}
|
||||
setEditingField(null)
|
||||
@@ -141,14 +143,14 @@ export function WorkspacePage() {
|
||||
if (!normalized) return
|
||||
const current = currentProcess?.tags ?? []
|
||||
if (current.some((t) => t === normalized)) return
|
||||
updateProcess({ tags: [...current, normalized] })
|
||||
updateProcess({ tags: [...current, normalized] }, user!.id)
|
||||
setTagInput('')
|
||||
setShowTagSuggestions(false)
|
||||
}
|
||||
|
||||
function removeTag(tag: string) {
|
||||
const current = currentProcess?.tags ?? []
|
||||
updateProcess({ tags: current.filter((t) => t !== tag) })
|
||||
updateProcess({ tags: current.filter((t) => t !== tag) }, user!.id)
|
||||
}
|
||||
|
||||
function handleTagKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
|
||||
|
||||
Reference in New Issue
Block a user