You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
7.9 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React, { useEffect, useState, useRef } from 'react';
import styles from './style/index.module.less';
import { Button, Select, Space } from '@arco-design/web-react';
import { IconFullscreen, IconFullscreenExit } from '@arco-design/web-react/icon';
import { useSelector, useDispatch } from 'react-redux';
import { getMyComponentList } from '@/api/componentBase';
import { updateComponentCodingPath } from '@/store/ideContainer';
import { getComponentBaseInfo } from '@/api/componentDevelopProcess';
const Option = Select.Option;
const ComponentCoding = () => {
const [serverUrl, setServerUrl] = useState(''); // code-server 地址
const [optionsList, setOptionsList] = useState([]); // 下拉选择菜单
const [originList, setOriginList] = useState([]); // 原始数据-组件列表
const [currentComponent, setCurrentComponent] = useState({}); // 当前组件信息
const [isFullscreen, setIsFullscreen] = useState(false); // 全屏状态
const iframeRef = useRef(null);
const { componentCoding } = useSelector((state: any) => state.ideContainer);
const dispatch = useDispatch();
const getOptionsList = async () => {
const res: any = await getMyComponentList({
currPage: 1,
pageSize: 999
});
if (res.code === 200) {
setOriginList(res.data.list);
setOptionsList(res.data.list.map(item => {
return { label: item.name, value: item.localProjectPath, ...item };
}));
}
};
const getComponentInfo = async () => {
const res: any = await getComponentBaseInfo(componentCoding.id);
if (res.code === 200) {
setCurrentComponent(res.data);
}
};
useEffect(() => {
getOptionsList();
}, []);
useEffect(() => {
getComponentInfo();
const uri = process.env.NEXT_PUBLIC_DEV_CODE_SERVER_HOST;
const codeServerFolderPre = '/app/data';
// 使用传入的localProjectPath或默认值
const path = componentCoding.localProjectPath || '/000000/admin_testcode1/master';
setServerUrl(`${uri}?folder=${codeServerFolderPre}${path}`);
}, [componentCoding]);
// 监听全屏状态变化
useEffect(() => {
const handleFullscreenChange = () => {
const isCurrentlyFullscreen =
document.fullscreenElement ||
(document as any).webkitFullscreenElement ||
(document as any).mozFullScreenElement ||
(document as any).msFullscreenElement;
setIsFullscreen(!!isCurrentlyFullscreen);
};
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
document.addEventListener('mozfullscreenchange', handleFullscreenChange);
document.addEventListener('MSFullscreenChange', handleFullscreenChange);
return () => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
document.removeEventListener('mozfullscreenchange', handleFullscreenChange);
document.removeEventListener('MSFullscreenChange', handleFullscreenChange);
};
}, []);
// 切换全屏状态
const toggleFullscreen = () => {
const iframeContainer = document.querySelector(`.${styles['code-iframe']}`) as HTMLElement;
if (!isFullscreen) {
// 进入全屏
if (iframeContainer.requestFullscreen) {
iframeContainer.requestFullscreen();
}
else if ((iframeContainer as any).webkitRequestFullscreen) {
(iframeContainer as any).webkitRequestFullscreen();
}
else if ((iframeContainer as any).mozRequestFullScreen) {
(iframeContainer as any).mozRequestFullScreen();
}
else if ((iframeContainer as any).msRequestFullscreen) {
(iframeContainer as any).msRequestFullscreen();
}
}
else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
}
else if ((document as any).webkitExitFullscreen) {
(document as any).webkitExitFullscreen();
}
else if ((document as any).mozCancelFullScreen) {
(document as any).mozCancelFullScreen();
}
else if ((document as any).msExitFullscreen) {
(document as any).msExitFullscreen();
}
}
};
return (
<div className={styles['component-coding']}>
<div className={styles['header']}>
<Space
size={50}
style={{ marginTop: '20px', marginBottom: '30px' }}
>
<div className={styles['handle-row']}>
<Space size={40}>
<div className={styles['handle-row-item']}>
<span></span>
<span>{componentCoding.name || '未选择组件'}</span>
</div>
<div className={styles['handle-row-item']}>
<span></span>
<span>{componentCoding.projectId || '未选择组件'}</span>
</div>
<div className={styles['handle-row-item']}>
<span></span>
<Select
placeholder="选择组件"
style={{ width: 250 }}
showSearch
filterOption={(inputValue, option) => {
return option.props.children.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0;
}}
onChange={(value) => {
// 查找选中项的完整信息
const selectedComponent = originList.find(item => item.localProjectPath === value);
if (selectedComponent) {
// 更新Redux状态
dispatch(updateComponentCodingPath({
localProjectPath: selectedComponent.localProjectPath,
name: selectedComponent.name,
projectId: selectedComponent.projectId,
id: selectedComponent.id
}));
}
}}
value={componentCoding.localProjectPath || undefined}
>
{optionsList.map((option, index) => (
<Option key={option.value} value={option.value}>
{option.label}
</Option>
))}
</Select>
</div>
</Space>
</div>
</Space>
<Space>
<Button
type="primary"
style={{ marginLeft: 5, borderRadius: 4 }}
>
</Button>
</Space>
</div>
<div className={styles['code-iframe']}>
<div className={styles['code-iframe-handle']}>
<Space size={10} className={styles['code-iframe-handle-left']}>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/tongbu.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
</span>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/git.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
git
</span>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/tijiao.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
</span>
</Space>
<div className={styles['code-iframe-handle-right']} onClick={toggleFullscreen}>
{isFullscreen ? (
<IconFullscreenExit style={{ width: 18, height: 18, marginRight: 5, marginLeft: 5, color: '#ffffff' }} />
) : (
<IconFullscreen style={{ width: 18, height: 18, marginRight: 5, marginLeft: 5, color: '#ffffff' }} />
)}
</div>
</div>
<iframe width="100%" height="100%" frameBorder={0} src={serverUrl} ref={iframeRef} />
</div>
</div>
);
};
export default ComponentCoding;