flow-card.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { ChatContext } from '@/app/chat-context';
  2. import { apiInterceptors, deleteFlowById, newDialogue } from '@/client/api';
  3. import { IFlow } from '@/types/flow';
  4. import {
  5. CopyFilled,
  6. DeleteFilled,
  7. EditFilled,
  8. ExclamationCircleOutlined,
  9. MessageFilled,
  10. WarningOutlined,
  11. } from '@ant-design/icons';
  12. import { Modal, Tooltip } from 'antd';
  13. import { useRouter } from 'next/router';
  14. import qs from 'querystring';
  15. import React, { useContext } from 'react';
  16. import { useTranslation } from 'react-i18next';
  17. import GptCard from '../common/gpt-card';
  18. import FlowPreview from './preview-flow';
  19. interface FlowCardProps {
  20. flow: IFlow;
  21. deleteCallback: (uid: string) => void;
  22. onCopy: (flow: IFlow) => void;
  23. }
  24. const FlowCard: React.FC<FlowCardProps> = ({ flow, onCopy, deleteCallback }) => {
  25. const { model } = useContext(ChatContext);
  26. const { t } = useTranslation();
  27. const [modal, contextHolder] = Modal.useModal();
  28. const router = useRouter();
  29. async function deleteFlow() {
  30. const [, , res] = await apiInterceptors(deleteFlowById(flow.uid));
  31. if (res?.success) {
  32. deleteCallback && deleteCallback(flow.uid);
  33. }
  34. }
  35. function cardClick() {
  36. router.push('/flow/canvas?id=' + flow.uid);
  37. }
  38. const handleChat = async () => {
  39. const [, res] = await apiInterceptors(newDialogue({ chat_mode: 'chat_agent' }));
  40. if (res) {
  41. const queryStr = qs.stringify({
  42. scene: 'chat_flow',
  43. id: res.conv_uid,
  44. model: model,
  45. select_param: flow.uid,
  46. });
  47. router.push(`/chat?${queryStr}`);
  48. }
  49. };
  50. const handleDel = () => {
  51. modal.confirm({
  52. title: t('Tips'),
  53. icon: <WarningOutlined />,
  54. content: t('delete_flow_confirm'),
  55. okText: 'Yes',
  56. okType: 'danger',
  57. cancelText: 'No',
  58. async onOk() {
  59. deleteFlow();
  60. },
  61. });
  62. };
  63. return (
  64. <>
  65. {contextHolder}
  66. <GptCard
  67. className='w-[26rem] max-w-full'
  68. title={flow.name}
  69. desc={flow.description}
  70. tags={[
  71. { text: flow.source, border: true, color: flow.source === 'DBGPT-WEB' ? 'green' : 'blue' },
  72. { text: flow.editable ? 'Editable' : 'Can not Edit', color: flow.editable ? 'green' : 'gray' },
  73. {
  74. text: (
  75. <>
  76. {flow.error_message ? (
  77. <Tooltip placement='bottom' title={flow.error_message}>
  78. {flow.state}
  79. <ExclamationCircleOutlined className='ml-1' />
  80. </Tooltip>
  81. ) : (
  82. flow.state
  83. )}
  84. </>
  85. ),
  86. color: flow.state === 'load_failed' ? 'red' : flow.state === 'running' ? 'green' : 'blue',
  87. border: true,
  88. },
  89. ]}
  90. operations={[
  91. {
  92. label: t('Chat'),
  93. children: <MessageFilled />,
  94. onClick: handleChat,
  95. },
  96. {
  97. label: t('Edit'),
  98. children: <EditFilled />,
  99. onClick: cardClick,
  100. },
  101. {
  102. label: t('Copy'),
  103. children: <CopyFilled />,
  104. onClick: () => {
  105. onCopy(flow);
  106. },
  107. },
  108. {
  109. label: t('Delete'),
  110. children: <DeleteFilled />,
  111. onClick: handleDel,
  112. },
  113. ]}
  114. >
  115. <div className='w-full h-[150px] shadow-[inset_0_0_16px_rgba(50,50,50,.05)]'>
  116. <FlowPreview flowData={flow.flow_data} />
  117. </div>
  118. </GptCard>
  119. </>
  120. );
  121. };
  122. export default FlowCard;