EditorToolbar.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { ModelSelector } from "../ModelSelector"
  2. import { AgentSelector } from "../AgentSelector"
  3. import { VariantSelector } from "../VariantSelector"
  4. import { IconButton } from "../common"
  5. import { MessageActions } from "./MessageActions"
  6. interface EditorToolbarProps {
  7. selectedProviderId: string | undefined
  8. selectedModelId: string | undefined
  9. selectedAgent: string
  10. onModelSelect: (providerId: string, modelId: string) => void
  11. onAgentSelect: (agent: string) => void
  12. onFileSelect: () => void
  13. isDisabled: boolean
  14. modelSelectorKey: number
  15. lastFailedMessage: string | null
  16. onRetry: () => void
  17. fileInputRef: React.RefObject<HTMLInputElement | null>
  18. onFileChange: (event: React.ChangeEvent<HTMLInputElement>) => void
  19. isIdle: boolean
  20. isButtonDisabled: boolean
  21. isCompactDisabled: boolean
  22. onSubmit: () => void
  23. onAbort: () => void
  24. onCompactClick: () => void
  25. variants?: string[]
  26. selectedVariant?: string
  27. onVariantSelect: (variant: string | undefined) => void
  28. isReasoningModel?: boolean
  29. }
  30. export function EditorToolbar({
  31. selectedProviderId,
  32. selectedModelId,
  33. selectedAgent,
  34. onModelSelect,
  35. onAgentSelect,
  36. onFileSelect,
  37. isDisabled,
  38. modelSelectorKey,
  39. lastFailedMessage,
  40. onRetry,
  41. fileInputRef,
  42. onFileChange,
  43. isIdle,
  44. isButtonDisabled,
  45. isCompactDisabled,
  46. onSubmit,
  47. onAbort,
  48. onCompactClick,
  49. variants,
  50. selectedVariant,
  51. onVariantSelect,
  52. isReasoningModel,
  53. }: EditorToolbarProps) {
  54. return (
  55. <div className="h-8 px-2 flex items-center justify-between border-t border-gray-100 dark:border-gray-800">
  56. <div className="flex items-center gap-1">
  57. {lastFailedMessage && (
  58. <button
  59. onClick={onRetry}
  60. className="h-6 px-2 flex items-center gap-1 text-xs font-medium text-red-600 dark:text-red-400 hover:text-red-700 dark:hover:text-red-300 hover:bg-red-50 dark:hover:bg-red-950 rounded border border-red-200 dark:border-red-800"
  61. title="Restore failed message"
  62. data-tip="Restore failed message"
  63. >
  64. <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  65. <path
  66. strokeLinecap="round"
  67. strokeLinejoin="round"
  68. strokeWidth={2}
  69. d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
  70. />
  71. </svg>
  72. Retry
  73. </button>
  74. )}
  75. <ModelSelector
  76. key={modelSelectorKey}
  77. selectedProviderId={selectedProviderId}
  78. selectedModelId={selectedModelId}
  79. onSelect={onModelSelect}
  80. disabled={isDisabled}
  81. />
  82. <VariantSelector
  83. variants={variants}
  84. selectedVariant={selectedVariant}
  85. onSelect={onVariantSelect}
  86. disabled={isDisabled}
  87. isReasoningModel={isReasoningModel}
  88. />
  89. <AgentSelector selectedAgent={selectedAgent} onSelect={onAgentSelect} disabled={isDisabled} />
  90. <IconButton
  91. onClick={onFileSelect}
  92. size="sm"
  93. disabled={isDisabled}
  94. aria-label="Add file"
  95. title="Add file"
  96. icon={
  97. <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  98. <path
  99. strokeLinecap="round"
  100. strokeLinejoin="round"
  101. strokeWidth={2}
  102. d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"
  103. />
  104. </svg>
  105. }
  106. />
  107. <input
  108. ref={fileInputRef}
  109. type="file"
  110. accept="image/png,image/jpeg,image/jpg,image/gif,image/webp,application/pdf,text/*"
  111. multiple
  112. onChange={onFileChange}
  113. className="hidden"
  114. />
  115. </div>
  116. <MessageActions
  117. isIdle={isIdle}
  118. isButtonDisabled={isButtonDisabled}
  119. isCompactDisabled={isCompactDisabled}
  120. onSubmit={onSubmit}
  121. onAbort={onAbort}
  122. onCompactClick={onCompactClick}
  123. />
  124. </div>
  125. )
  126. }