| 1 |
import { AnimateChunks } from '@agent/components/messages/AnimateChunks'; |
| 2 |
import { useEffect, useMemo, useState } from '@wordpress/element'; |
| 3 |
import { decodeEntities } from '@wordpress/html-entities'; |
| 4 |
import { __ } from '@wordpress/i18n'; |
| 5 |
import classNames from 'classnames'; |
| 6 |
|
| 7 |
export const StatusMessage = ({ status, animate }) => { |
| 8 |
const { type, label } = status.details; |
| 9 |
const [content, setContent] = useState(); |
| 10 |
const [loopIndex, setLoopIndex] = useState(0); |
| 11 |
const statusContent = useMemo( |
| 12 |
() => ({ |
| 13 |
'calling-agent': __('Thinking...', 'extendify-local'), |
| 14 |
'agent-working': [ |
| 15 |
__('Working on it...', 'extendify-local'), |
| 16 |
__('Interpreting message...', 'extendify-local'), |
| 17 |
__('Formulating a response...', 'extendify-local'), |
| 18 |
__('Reviewing logic...', 'extendify-local'), |
| 19 |
], |
| 20 |
'workflow-tool-processing': __('Processing...', 'extendify-local'), |
| 21 |
'tool-started': label || __('Gathering data...', 'extendify-local'), |
| 22 |
'tool-completed': label || __('Analyzing...', 'extendify-local'), |
| 23 |
'tool-canceled': label || __('Canceled', 'extendify-local'), |
| 24 |
'workflow-canceled': label || __('Canceled', 'extendify-local'), |
| 25 |
'credits-exhausted': __('Usage limit reached', 'extendify-local'), |
| 26 |
'credits-restored': __('Usage limit restored', 'extendify-local'), |
| 27 |
}), |
| 28 |
[label], |
| 29 |
); |
| 30 |
const canAnimate = [ |
| 31 |
'calling-agent', |
| 32 |
'agent-working', |
| 33 |
'tool-started', |
| 34 |
].includes(type); |
| 35 |
|
| 36 |
useEffect(() => { |
| 37 |
if (!Array.isArray(statusContent[type])) { |
| 38 |
setContent(statusContent[type]); |
| 39 |
return; |
| 40 |
} |
| 41 |
setContent(statusContent[type][loopIndex]); |
| 42 |
const timer = setTimeout(() => { |
| 43 |
setContent(null); |
| 44 |
setLoopIndex((prevIndex) => (prevIndex + 1) % statusContent[type].length); |
| 45 |
}, 5000); |
| 46 |
return () => { |
| 47 |
// we need to clear the content and make sure it hide the status correctly. |
| 48 |
setContent(null); |
| 49 |
clearTimeout(timer); |
| 50 |
}; |
| 51 |
}, [type, statusContent, content, loopIndex]); |
| 52 |
|
| 53 |
if (type === 'workflow-tool-completed') { |
| 54 |
return <WorkflowToolCompleted label={label} />; |
| 55 |
} |
| 56 |
if (type === 'workflow-canceled') { |
| 57 |
return <WorkflowToolCanceled label={label} />; |
| 58 |
} |
| 59 |
|
| 60 |
if (!content) return null; |
| 61 |
|
| 62 |
return ( |
| 63 |
<div |
| 64 |
className={classNames('p-2 text-center text-xs italic text-gray-700', { |
| 65 |
'status-animation': canAnimate, |
| 66 |
})} |
| 67 |
> |
| 68 |
{animate ? ( |
| 69 |
<AnimateChunks words={decodeEntities(content).split('')} delay={0.02} /> |
| 70 |
) : ( |
| 71 |
decodeEntities(content) |
| 72 |
)} |
| 73 |
</div> |
| 74 |
); |
| 75 |
}; |
| 76 |
|
| 77 |
export const WorkflowToolCompleted = ({ label }) => { |
| 78 |
return ( |
| 79 |
<div className="flex w-full items-start gap-2.5 p-2"> |
| 80 |
<div className="w-7 shrink-0" /> |
| 81 |
<div className="flex min-w-0 flex-1 flex-col gap-1"> |
| 82 |
<div className="flex items-center gap-2 rounded-lg border border-wp-alert-green bg-wp-alert-green/20 p-3 text-green-900"> |
| 83 |
<div className="h-6 w-6 leading-none"> |
| 84 |
<svg |
| 85 |
xmlns="http://www.w3.org/2000/svg" |
| 86 |
fill="none" |
| 87 |
viewBox="0 0 24 24" |
| 88 |
strokeWidth={1.5} |
| 89 |
stroke="currentColor" |
| 90 |
className="size-6" |
| 91 |
> |
| 92 |
<title>{__('Success icon', 'extendify-local')}</title> |
| 93 |
<path |
| 94 |
strokeLinecap="round" |
| 95 |
strokeLinejoin="round" |
| 96 |
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" |
| 97 |
/> |
| 98 |
</svg> |
| 99 |
</div> |
| 100 |
<div className="text-sm"> |
| 101 |
{decodeEntities(label) || |
| 102 |
__('Workflow completed successfully', 'extendify-local')} |
| 103 |
</div> |
| 104 |
</div> |
| 105 |
</div> |
| 106 |
</div> |
| 107 |
); |
| 108 |
}; |
| 109 |
|
| 110 |
export const WorkflowToolCanceled = ({ label }) => { |
| 111 |
return ( |
| 112 |
<div className="flex w-full items-start gap-2.5 p-2"> |
| 113 |
<div className="w-7 shrink-0" /> |
| 114 |
<div className="flex min-w-0 flex-1 flex-col gap-1"> |
| 115 |
<div className="flex items-center gap-2 rounded-lg border border-gray-300 bg-gray-50 p-3 text-gray-700"> |
| 116 |
<div className="text-sm"> |
| 117 |
{decodeEntities(label) || |
| 118 |
__('Workflow was canceled', 'extendify-local')} |
| 119 |
</div> |
| 120 |
</div> |
| 121 |
</div> |
| 122 |
</div> |
| 123 |
); |
| 124 |
}; |
| 125 |
|