chore: images create
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { WarningOutlined } from '@ant-design/icons';
|
||||
import { Typography } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
interface AlertInfoProps {
|
||||
type: 'danger' | 'warning';
|
||||
message: string;
|
||||
rows?: number;
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
const AlertInfo: React.FC<AlertInfoProps> = (props) => {
|
||||
const { message, type, rows = 1 } = props;
|
||||
if (!message) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Typography.Paragraph
|
||||
type={type}
|
||||
ellipsis={{
|
||||
rows: rows,
|
||||
tooltip: message
|
||||
}}
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
padding: '2px 5px',
|
||||
borderRadius: 'var(--border-radius-base)',
|
||||
margin: 0,
|
||||
backgroundColor: 'var(--ant-color-error-bg)'
|
||||
}}
|
||||
>
|
||||
<WarningOutlined className="m-r-8" />
|
||||
{message}
|
||||
</Typography.Paragraph>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(AlertInfo);
|
||||
@@ -61,7 +61,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
|
||||
setPlayOn(false);
|
||||
setAudioState((prestate: any) => {
|
||||
return {
|
||||
currentTime: 0,
|
||||
currentTime: audioRef.current?.ended ? 0 : prestate.currentTime,
|
||||
duration: prestate.duration
|
||||
};
|
||||
});
|
||||
@@ -87,6 +87,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
|
||||
|
||||
const handleLoadedMetadata = useCallback(
|
||||
(data: any) => {
|
||||
console.log('loadmetadata++++++++');
|
||||
const duration = Math.ceil(audioRef.current?.duration || 0);
|
||||
setAudioState({
|
||||
currentTime: 0,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import fallbackImg from '@/assets/images/img_fallback.png';
|
||||
import {
|
||||
DownloadOutlined,
|
||||
EyeOutlined,
|
||||
@@ -13,9 +14,16 @@ import { round } from 'lodash';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import './index.less';
|
||||
|
||||
const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
|
||||
const { height = 100, ...rest } = props;
|
||||
const [width, setWidth] = useState(0);
|
||||
const AutoImage: React.FC<
|
||||
ImageProps & {
|
||||
height: number | string;
|
||||
width?: number | string;
|
||||
autoSize?: boolean;
|
||||
}
|
||||
> = (props) => {
|
||||
const { height = 100, width: w, autoSize, ...rest } = props;
|
||||
const [width, setWidth] = useState(w || 0);
|
||||
const [isError, setIsError] = useState(false);
|
||||
|
||||
const getImgRatio = useCallback((url: string): Promise<{ ratio: number }> => {
|
||||
return new Promise((resolve) => {
|
||||
@@ -31,8 +39,15 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
|
||||
}, []);
|
||||
|
||||
const handleOnLoad = useCallback(async () => {
|
||||
if (autoSize) {
|
||||
return;
|
||||
}
|
||||
const { ratio } = await getImgRatio(props.src || '');
|
||||
setWidth(height * ratio);
|
||||
if (typeof height === 'number') {
|
||||
setWidth(height * ratio);
|
||||
} else {
|
||||
throw new Error('Height must be a number');
|
||||
}
|
||||
}, [getImgRatio, height, props.src]);
|
||||
|
||||
const onDownload = () => {
|
||||
@@ -47,6 +62,10 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
|
||||
link.remove();
|
||||
};
|
||||
|
||||
const handleOnError = () => {
|
||||
setIsError(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleOnLoad();
|
||||
}, [handleOnLoad]);
|
||||
@@ -54,8 +73,10 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
|
||||
return (
|
||||
<AntImage
|
||||
{...rest}
|
||||
height={height}
|
||||
width={width}
|
||||
height={isError ? 'auto' : height}
|
||||
width={isError ? '100%' : width}
|
||||
onError={handleOnError}
|
||||
fallback={fallbackImg}
|
||||
preview={{
|
||||
mask: <EyeOutlined />,
|
||||
toolbarRender: (
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
TooltipComponentOption
|
||||
} from 'echarts/components';
|
||||
import {
|
||||
DataZoomComponent,
|
||||
DatasetComponent,
|
||||
GridComponent,
|
||||
LegendComponent,
|
||||
@@ -44,6 +45,7 @@ echarts.use([
|
||||
GridComponent,
|
||||
DatasetComponent,
|
||||
TransformComponent,
|
||||
DataZoomComponent,
|
||||
BarChart,
|
||||
LineChart,
|
||||
ScatterChart,
|
||||
|
||||
@@ -17,35 +17,47 @@ const options: any = {
|
||||
borderRadius: 4
|
||||
},
|
||||
xAxis: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
scale: false,
|
||||
slient: true,
|
||||
splitNumber: 15,
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(5,5,5,0.06)'
|
||||
color: '#F2F2F2'
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#F2F2F2'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
boundaryGap: [0.05, 0.05]
|
||||
},
|
||||
yAxis: {
|
||||
min: -1,
|
||||
max: 1,
|
||||
scale: false,
|
||||
slient: true,
|
||||
splitNumber: 10,
|
||||
boundaryGap: [0.05, 0.05],
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(5,5,5,0.06)'
|
||||
color: '#F2F2F2'
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#F2F2F2'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
@@ -54,6 +66,7 @@ const options: any = {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
|
||||
symbol: 'roundRect',
|
||||
label: {
|
||||
show: true,
|
||||
@@ -67,16 +80,7 @@ const options: any = {
|
||||
};
|
||||
|
||||
const Scatter: React.FC<ChartProps> = (props) => {
|
||||
const {
|
||||
seriesData,
|
||||
xAxisData,
|
||||
height,
|
||||
width,
|
||||
showEmpty,
|
||||
labelFormatter,
|
||||
legendData,
|
||||
title
|
||||
} = props;
|
||||
const { seriesData, xAxisData, height, width, showEmpty, title } = props;
|
||||
|
||||
const chart = useRef<any>(null);
|
||||
|
||||
@@ -118,18 +122,21 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
||||
[]
|
||||
);
|
||||
|
||||
const dataOptions = useMemo((): any => {
|
||||
if (!seriesData.length) {
|
||||
options.xAxis.min = 0;
|
||||
options.xAxis.max = 1;
|
||||
options.yAxis.min = 0;
|
||||
options.yAxis.max = 1;
|
||||
} else {
|
||||
options.xAxis.min = null;
|
||||
options.xAxis.max = null;
|
||||
options.yAxis.min = null;
|
||||
options.yAxis.max = null;
|
||||
const renderNameInTooltip = useCallback((dataList: any[]) => {
|
||||
if (!dataList.length || dataList.length < 2) {
|
||||
return null;
|
||||
}
|
||||
const renderText = (item: any) => {
|
||||
return `<span class="tooltip-item-name">
|
||||
<span style="display:flex;justify-content:center;align-items: center;color:#fff;
|
||||
margin-right:0;border-radius:4px;width:14px;
|
||||
height:14px;background-color:${item?.itemStyle?.color};"
|
||||
>${item.name}</span>
|
||||
</span>`;
|
||||
};
|
||||
return renderText;
|
||||
}, []);
|
||||
const dataOptions = useMemo((): any => {
|
||||
const seriseDataList = seriesData.map((item: any, index: number) => {
|
||||
return {
|
||||
...item,
|
||||
@@ -147,15 +154,11 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
||||
formatter(params: any, callback?: (val: any) => any) {
|
||||
const dataList = findOverlappingPoints(seriseDataList, params.data);
|
||||
let result = '';
|
||||
const renderText: any = renderNameInTooltip(dataList);
|
||||
dataList.forEach((item: any) => {
|
||||
result += `
|
||||
<span class="tooltip-item" style="justify-content: flex-start;">
|
||||
<span class="tooltip-item-name">
|
||||
<span style="display:flex;justify-content:center;align-items: center;color:#fff;
|
||||
margin-right:0;border-radius:4px;width:14px;
|
||||
height:14px;background-color:${item.itemStyle?.color};"
|
||||
>${item.name}</span>
|
||||
</span>
|
||||
${renderText ? renderText(item) : ''}
|
||||
<span class="tooltip-value">${item.text}</span>
|
||||
</span>`;
|
||||
});
|
||||
@@ -168,6 +171,9 @@ const Scatter: React.FC<ChartProps> = (props) => {
|
||||
},
|
||||
series: {
|
||||
type: 'scatter',
|
||||
labelLayout: {
|
||||
hideOverlap: true
|
||||
},
|
||||
data: seriseDataList
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ interface CodeViewerProps {
|
||||
ignoreIllegals?: boolean;
|
||||
copyable?: boolean;
|
||||
height?: string | number;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
const DarkViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
const {
|
||||
@@ -22,6 +23,7 @@ const DarkViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
|
||||
return (
|
||||
<CodeViewer
|
||||
style={props.style}
|
||||
height={height}
|
||||
code={code}
|
||||
lang={lang}
|
||||
|
||||
@@ -9,6 +9,7 @@ interface CodeViewerProps {
|
||||
ignoreIllegals?: boolean;
|
||||
copyable?: boolean;
|
||||
height?: string | number;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
const LightViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
const {
|
||||
@@ -17,11 +18,13 @@ const LightViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
autodetect,
|
||||
ignoreIllegals,
|
||||
copyable,
|
||||
style,
|
||||
height = 'auto'
|
||||
} = props || {};
|
||||
|
||||
return (
|
||||
<CodeViewer
|
||||
style={style}
|
||||
height={height}
|
||||
code={code}
|
||||
lang={lang}
|
||||
|
||||
@@ -12,6 +12,7 @@ interface CodeViewerProps {
|
||||
copyable?: boolean;
|
||||
height?: string | number;
|
||||
theme?: 'light' | 'dark';
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
const CodeViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
const {
|
||||
@@ -20,7 +21,8 @@ const CodeViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
autodetect = true,
|
||||
ignoreIllegals = true,
|
||||
copyable = true,
|
||||
height = 'auto'
|
||||
height = 'auto',
|
||||
style
|
||||
} = props || {};
|
||||
|
||||
const highlightedCode = useMemo(() => {
|
||||
@@ -69,7 +71,8 @@ const CodeViewer: React.FC<CodeViewerProps> = (props) => {
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
height: height
|
||||
height: height,
|
||||
...style
|
||||
}}
|
||||
>
|
||||
<code
|
||||
|
||||
@@ -9,8 +9,10 @@ const HighlightCode: React.FC<{
|
||||
copyable?: boolean;
|
||||
theme?: 'light' | 'dark';
|
||||
height?: string | number;
|
||||
style?: React.CSSProperties;
|
||||
}> = (props) => {
|
||||
const {
|
||||
style,
|
||||
code,
|
||||
lang = 'bash',
|
||||
copyable = true,
|
||||
@@ -26,9 +28,11 @@ const HighlightCode: React.FC<{
|
||||
code={code}
|
||||
copyable={copyable}
|
||||
height={height}
|
||||
style={style}
|
||||
/>
|
||||
) : (
|
||||
<CodeViewerLight
|
||||
style={style}
|
||||
lang={lang}
|
||||
code={code}
|
||||
copyable={copyable}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
border-radius: @borderRadius;
|
||||
background-color: var(--color-white-1);
|
||||
|
||||
&.seal-input-number {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&.borderless {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
@@ -97,6 +101,12 @@
|
||||
padding-block: 20px 0;
|
||||
max-width: 100%;
|
||||
|
||||
&:hover {
|
||||
:global(.ant-input-number-handler-wrap) {
|
||||
width: 34px !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-wrapper-style {
|
||||
padding-block: 0;
|
||||
}
|
||||
@@ -201,6 +211,7 @@
|
||||
height: @inputheight !important;
|
||||
}
|
||||
// ==================== input ====================
|
||||
|
||||
:global(.ant-input),
|
||||
:global(.ant-input-password) {
|
||||
// width: 100%;
|
||||
@@ -221,6 +232,7 @@
|
||||
}
|
||||
|
||||
:global(.ant-input-number) {
|
||||
position: static;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: none;
|
||||
@@ -228,6 +240,15 @@
|
||||
padding: 0;
|
||||
height: @inputheight !important;
|
||||
background-color: @bgColor;
|
||||
|
||||
&:hover .ant-input-number-handler-wrap,
|
||||
&-focused .ant-input-number-handler-wrap {
|
||||
width: 34px !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.ant-input-outlined) {
|
||||
@@ -293,13 +314,7 @@
|
||||
}
|
||||
|
||||
:global(.ant-input-number-handler-wrap) {
|
||||
top: -20px;
|
||||
top: 0;
|
||||
height: @wrapheight - 2px;
|
||||
}
|
||||
|
||||
// :global(.ant-input-prefix) {
|
||||
// position: absolute;
|
||||
// top: 1px;
|
||||
// left: -4px;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
|
||||
description={description}
|
||||
disabled={props.disabled}
|
||||
onClick={handleClickWrapper}
|
||||
className="seal-input-number"
|
||||
>
|
||||
<InputNumber
|
||||
{...rest}
|
||||
|
||||
@@ -10,11 +10,12 @@ interface SystemMessageProps {
|
||||
value: string;
|
||||
placeholder?: string;
|
||||
label?: React.ReactNode;
|
||||
height?: number;
|
||||
onChange: (e: any) => void;
|
||||
}
|
||||
|
||||
const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
||||
const { value, onChange, style, label, placeholder } = props;
|
||||
const { value, onChange, style, label, placeholder, height = 46 } = props;
|
||||
const intl = useIntl();
|
||||
const rowTextAreaRef = React.useRef<any>(null);
|
||||
const [autoSize, setAutoSize] = useState<{
|
||||
@@ -64,7 +65,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
||||
style={{ display: autoSize.focus ? 'block' : 'none' }}
|
||||
className="textarea-wrapper"
|
||||
>
|
||||
<span className="textarea-label">{label}</span>
|
||||
{label && <span className="textarea-label">{label}</span>}
|
||||
<Input.TextArea
|
||||
className="custome-scrollbar"
|
||||
ref={rowTextAreaRef}
|
||||
@@ -87,8 +88,8 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
||||
}
|
||||
{!autoSize.focus && (
|
||||
<div className="content-wrap" onClick={handleFocus}>
|
||||
<div className="content">
|
||||
<span className="title">{label}</span>
|
||||
<div className="content" style={{ height: height }}>
|
||||
{label && <span className="title">{label}</span>}
|
||||
{value || (
|
||||
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
||||
{placeholder}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { isNotEmptyValue } from '@/utils/index';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import type { SelectProps } from 'antd';
|
||||
import { Form, Select } from 'antd';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import Wrapper from './components/wrapper';
|
||||
import { SealFormItemProps } from './types';
|
||||
|
||||
@@ -12,9 +14,11 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
|
||||
children,
|
||||
required,
|
||||
description,
|
||||
options,
|
||||
isInFormItems = true,
|
||||
...rest
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const [isFocus, setIsFocus] = useState(false);
|
||||
const inputRef = useRef<any>(null);
|
||||
let status = '';
|
||||
@@ -23,6 +27,19 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
|
||||
status = statusData?.status || '';
|
||||
}
|
||||
|
||||
const _options = useMemo(() => {
|
||||
if (!options?.length) {
|
||||
return [];
|
||||
}
|
||||
const list = cloneDeep(options);
|
||||
return list.map((item: any) => {
|
||||
if (item.locale) {
|
||||
item.label = intl.formatMessage({ id: item.label as string });
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}, [options, intl]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isNotEmptyValue(props.value)) {
|
||||
setIsFocus(true);
|
||||
@@ -70,6 +87,7 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
|
||||
<Select
|
||||
{...rest}
|
||||
ref={inputRef}
|
||||
options={_options}
|
||||
onFocus={handleOnFocus}
|
||||
onBlur={handleOnBlur}
|
||||
onChange={handleChange}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
position: relative;
|
||||
|
||||
&.focus {
|
||||
padding-top: 9px;
|
||||
// padding-top: 9px;
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
&:hover {
|
||||
.clear-btn {
|
||||
display: block;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,8 @@
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.textarea-label {
|
||||
@@ -41,8 +42,8 @@
|
||||
.content {
|
||||
flex: 1;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 24px;
|
||||
height: 46px;
|
||||
line-height: 30px;
|
||||
padding: 8px 14px;
|
||||
padding-right: 4px;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -9,11 +9,11 @@ interface SpeechContentProps {
|
||||
const SpeechContent: React.FC<SpeechContentProps> = (props) => {
|
||||
console.log('SpeechContent', props);
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
{props.dataList.map((item) => (
|
||||
<SpeechItem key={item.uid} {...item} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user