|
|
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; |