mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 22:25:19 +00:00
[feature](webapp) add script command to accommodate different Node.js versions and change lerna + npm to pnpm workspaces (#61)
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { UpOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import { CLS_PREFIX } from '../../../common/constants';
|
||||
import { ColumnType } from '../../../common/type';
|
||||
|
||||
type Props = {
|
||||
columns: ColumnType[];
|
||||
referenceColumn?: ColumnType;
|
||||
dataSource: any[];
|
||||
};
|
||||
|
||||
const Text: React.FC<Props> = ({ columns, referenceColumn, dataSource }) => {
|
||||
const [text, setText] = useState<string>();
|
||||
const [htmlCode, setHtmlCode] = useState<string>();
|
||||
const [referenceExpanded, setRederenceExpanded] = useState(false);
|
||||
const [referenceData, setReferenceData] = useState<any[]>([]);
|
||||
|
||||
const prefixCls = `${CLS_PREFIX}-text`;
|
||||
|
||||
const initData = () => {
|
||||
let textValue = dataSource[0][columns[0].nameEn];
|
||||
let htmlCodeValue: string;
|
||||
const match = textValue.match(/```html([\s\S]*?)```/);
|
||||
htmlCodeValue = match && match[1].trim();
|
||||
if (htmlCodeValue) {
|
||||
textValue = textValue.replace(/```html([\s\S]*?)```/, '');
|
||||
}
|
||||
let scriptCode: string;
|
||||
let scriptSrc: string;
|
||||
if (htmlCodeValue) {
|
||||
scriptSrc = htmlCodeValue.match(/<script src="([\s\S]*?)"><\/script>/)?.[1] || '';
|
||||
scriptCode =
|
||||
htmlCodeValue.match(/<script type="text\/javascript">([\s\S]*?)<\/script>/)?.[1] || '';
|
||||
if (scriptSrc) {
|
||||
const script = document.createElement('script');
|
||||
script.src = scriptSrc;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
if (scriptCode) {
|
||||
const script = document.createElement('script');
|
||||
script.innerHTML = scriptCode;
|
||||
setTimeout(() => {
|
||||
document.body.appendChild(script);
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
setText(textValue);
|
||||
setHtmlCode(htmlCodeValue);
|
||||
if (referenceColumn) {
|
||||
const referenceDataValue = dataSource[0][referenceColumn.nameEn];
|
||||
setReferenceData(referenceDataValue || []);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initData();
|
||||
}, []);
|
||||
|
||||
const onToggleMore = () => {
|
||||
setRederenceExpanded(!referenceExpanded);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
lineHeight: '24px',
|
||||
width: 'fit-content',
|
||||
maxWidth: '100%',
|
||||
overflowX: 'hidden',
|
||||
}}
|
||||
>
|
||||
{htmlCode ? <pre>{text}</pre> : text}
|
||||
{referenceData.length > 0 && (
|
||||
<span className={`${prefixCls}-check-more`} onClick={onToggleMore}>
|
||||
{referenceExpanded ? '收起' : '查看'}更多
|
||||
{referenceExpanded ? (
|
||||
<UpOutlined className={`${prefixCls}-arrow-icon`} />
|
||||
) : (
|
||||
<DownOutlined className={`${prefixCls}-arrow-icon`} />
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
{referenceData.length > 0 && referenceExpanded && (
|
||||
<div className={`${prefixCls}-reference-data`}>
|
||||
{referenceData.map(item => (
|
||||
<div className={`${prefixCls}-reference-item`} key={item.doc_title}>
|
||||
<div className={`${prefixCls}-reference-item-title`}>{item.doc_title}</div>
|
||||
<div className={`${prefixCls}-reference-item-value`}>{item.doc_chunk}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!!htmlCode && <div dangerouslySetInnerHTML={{ __html: htmlCode }} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Text;
|
||||
@@ -0,0 +1,38 @@
|
||||
@import '../../../styles/index.less';
|
||||
|
||||
@text-prefix-cls: ~'@{supersonic-chat-prefix}-text';
|
||||
|
||||
.@{text-prefix-cls} {
|
||||
&-check-more {
|
||||
margin-left: 12px;
|
||||
font-size: 13px;
|
||||
color: var(--chat-blue);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-arrow-icon {
|
||||
margin-left: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-reference-data {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&-reference-item {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&-reference-item-title {
|
||||
color: var(--text-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&-reference-item-value {
|
||||
color: var(--text-color-secondary);
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { useEffect, useState } from 'react';
|
||||
import { queryData } from '../../service';
|
||||
import classNames from 'classnames';
|
||||
import { PREFIX_CLS } from '../../common/constants';
|
||||
import Text from './Text';
|
||||
|
||||
type Props = {
|
||||
data: MsgDataType;
|
||||
@@ -17,7 +18,8 @@ type Props = {
|
||||
const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
|
||||
const { queryColumns, queryResults, chatContext, queryMode } = data;
|
||||
|
||||
const [columns, setColumns] = useState<ColumnType[]>(queryColumns);
|
||||
const [columns, setColumns] = useState<ColumnType[]>();
|
||||
const [referenceColumn, setReferenceColumn] = useState<ColumnType>();
|
||||
const [dataSource, setDataSource] = useState<any[]>(queryResults);
|
||||
|
||||
const [drillDownDimension, setDrillDownDimension] = useState<DrillDownDimensionType>();
|
||||
@@ -25,12 +27,18 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
|
||||
|
||||
const prefixCls = `${PREFIX_CLS}-chat-msg`;
|
||||
|
||||
const updateColummns = (queryColumnsValue: ColumnType[]) => {
|
||||
const referenceColumn = queryColumnsValue.find(item => item.showType === 'more');
|
||||
setReferenceColumn(referenceColumn);
|
||||
setColumns(queryColumnsValue.filter(item => item.showType !== 'more'));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setColumns(queryColumns);
|
||||
updateColummns(queryColumns);
|
||||
setDataSource(queryResults);
|
||||
}, [queryColumns, queryResults]);
|
||||
|
||||
if (!queryColumns || !queryResults) {
|
||||
if (!queryColumns || !queryResults || !columns) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -69,7 +77,7 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
|
||||
});
|
||||
setLoading(false);
|
||||
if (data.code === 200) {
|
||||
setColumns(data.data?.queryColumns || []);
|
||||
updateColummns(data.data?.queryColumns || []);
|
||||
setDataSource(data.data?.queryResults || []);
|
||||
}
|
||||
};
|
||||
@@ -82,51 +90,9 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
|
||||
});
|
||||
};
|
||||
|
||||
const getTextContent = () => {
|
||||
let text = dataSource[0][columns[0].nameEn];
|
||||
let htmlCode: string;
|
||||
const match = text.match(/```html([\s\S]*?)```/);
|
||||
htmlCode = match && match[1].trim();
|
||||
if (htmlCode) {
|
||||
text = text.replace(/```html([\s\S]*?)```/, '');
|
||||
}
|
||||
let scriptCode: string;
|
||||
let scriptSrc: string;
|
||||
if (htmlCode) {
|
||||
scriptSrc = htmlCode.match(/<script src="([\s\S]*?)"><\/script>/)?.[1] || '';
|
||||
scriptCode =
|
||||
htmlCode.match(/<script type="text\/javascript">([\s\S]*?)<\/script>/)?.[1] || '';
|
||||
if (scriptSrc) {
|
||||
const script = document.createElement('script');
|
||||
script.src = scriptSrc;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
if (scriptCode) {
|
||||
const script = document.createElement('script');
|
||||
script.innerHTML = scriptCode;
|
||||
setTimeout(() => {
|
||||
document.body.appendChild(script);
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
lineHeight: '24px',
|
||||
width: 'fit-content',
|
||||
maxWidth: '100%',
|
||||
overflowX: 'hidden',
|
||||
}}
|
||||
>
|
||||
{htmlCode ? <pre>{text}</pre> : text}
|
||||
{!!htmlCode && <div dangerouslySetInnerHTML={{ __html: htmlCode }} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getMsgContent = () => {
|
||||
if (isText) {
|
||||
return getTextContent();
|
||||
return <Text columns={columns} referenceColumn={referenceColumn} dataSource={dataSource} />;
|
||||
}
|
||||
if (isMetricCard) {
|
||||
return (
|
||||
@@ -168,7 +134,11 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
|
||||
|
||||
const chartMsgClass = classNames({ [prefixCls]: !isTable });
|
||||
|
||||
return <div className={chartMsgClass}>{getMsgContent()}</div>;
|
||||
return (
|
||||
<div className={chartMsgClass}>
|
||||
{dataSource?.length === 0 ? <div>暂无数据,如有疑问请联系管理员</div> : getMsgContent()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatMsg;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@chat-msg-prefix-cls: ~'@{supersonic-chat-prefix}-chat-msg';
|
||||
|
||||
.@{chat-msg-prefix-cls} {
|
||||
padding: 6px 14px 12px;
|
||||
padding: 6px 14px 8px;
|
||||
border: 1px solid var(--border-color-base);
|
||||
border-radius: 4px;
|
||||
background: #f5f8fb;
|
||||
|
||||
Reference in New Issue
Block a user