mirror of https://gitee.com/cf-fz/WebCAD.git
!2116 新增:右侧工具栏材质面板显示模式
parent
b6ad900edb
commit
50a7fe47cf
@ -0,0 +1,144 @@
|
||||
.material-explorer {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.material-config {
|
||||
height: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.right-material-param {
|
||||
padding-bottom: 5px;
|
||||
flex-grow: 1;
|
||||
flex-basis: 200px;
|
||||
overflow: hidden;
|
||||
|
||||
.material-param {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.setsplit();
|
||||
|
||||
.my-material-param {
|
||||
margin-top: 2px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.material-search {
|
||||
height: 34px;
|
||||
|
||||
input {
|
||||
width: 99%;
|
||||
}
|
||||
}
|
||||
|
||||
.material-params {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
.img-tree {
|
||||
height: 40%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
|
||||
.bp3-tree {
|
||||
height: 100%;
|
||||
padding-bottom: 10px;
|
||||
box-shadow: none;
|
||||
|
||||
&>ul {
|
||||
max-height: 95%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.bp3-tree-node-content-1 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.material-datalist {
|
||||
width: 100%;
|
||||
height: 60%;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&> :nth-child(1) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mat-list:first-child {
|
||||
padding-bottom: 10px;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.look-mat {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&>li {
|
||||
text-align: center;
|
||||
|
||||
.hint:hover::before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
&>.bp3-control {
|
||||
left: 10px;
|
||||
top: 10;
|
||||
}
|
||||
|
||||
&>p {
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-dialog-container {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 30;
|
||||
|
||||
.bp3-dialog {
|
||||
width: unset;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//split组件样式
|
||||
.setsplit {
|
||||
.gutter {
|
||||
background-color: #999;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 10%;
|
||||
}
|
||||
|
||||
.gutter.gutter-vertical {
|
||||
cursor: row-resize;
|
||||
padding: auto;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.split {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
@ -1,396 +0,0 @@
|
||||
import { Classes, ITreeNode, Tree } from "@blueprintjs/core";
|
||||
import hotkeys from "hotkeys-js-ext";
|
||||
import { action, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { end } from "xaop";
|
||||
import { app } from "../../../ApplicationServices/Application";
|
||||
import { arrayLast } from "../../../Common/ArrayExt";
|
||||
import { DirUrl } from "../../../Common/HostUrl";
|
||||
import { MouseKey } from "../../../Common/KeyEnum";
|
||||
import { DirectoryId, PostJson, RequestStatus } from "../../../Common/Request";
|
||||
import { CommonPanelEventBus } from "./CommonPanel";
|
||||
import { Pagination } from "./Pagination";
|
||||
import './RightMyMaterialPanel.less';
|
||||
export interface IDirectoryProps
|
||||
{
|
||||
id: DirectoryId | string;
|
||||
path: string;
|
||||
pathNum: number[];
|
||||
}
|
||||
interface ICommonPanelState
|
||||
{
|
||||
nodes: ITreeNode[]; //目录节点
|
||||
defaultDirName: string; //新目录名字
|
||||
updateNode: ITreeNode; //需要更新的目录节点
|
||||
}
|
||||
interface ICommonPanelProps
|
||||
{
|
||||
defaultDirId: string; //根目录ID
|
||||
getUrl: string; //获取数据URL
|
||||
dirNameFilter?: string[];
|
||||
}
|
||||
@observer
|
||||
export class RightMaterialPanel extends React.Component<ICommonPanelProps, ICommonPanelState>
|
||||
{
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
nodes: [],
|
||||
defaultDirName: "",
|
||||
updateNode: undefined,
|
||||
};
|
||||
this._CurrentDir.id = DirectoryId.MaterialDir;
|
||||
this._IdKey = "material_id";
|
||||
}
|
||||
static CurrentDirCache: Map<string, IDirectoryProps> = new Map();
|
||||
@observable _DataList = [];
|
||||
@observable _SelectIds = new Set<string>();
|
||||
@observable _CurrentDir: IDirectoryProps = {
|
||||
id: DirectoryId.None,
|
||||
path: "",
|
||||
pathNum: []
|
||||
};
|
||||
@observable _PageData = { //分页数据
|
||||
count: 0,
|
||||
currentPage: 1,
|
||||
pageCount: 15
|
||||
};
|
||||
@observable _SearchStr = "";//搜索材质名
|
||||
_IdKey: string;
|
||||
_Events: Function[] = [];
|
||||
_Tree: HTMLElement; //目录数元素
|
||||
_TimeId = null; //搜索时的定时器
|
||||
|
||||
get IsCtrlDown()
|
||||
{
|
||||
return app.Editor.ModalManage.IsCtrlDown || hotkeys.ctrl;
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
//监听右键其他位置
|
||||
if (this._Tree)
|
||||
{
|
||||
this._Tree.addEventListener('mousedown', this._HandleTreeMouseDown);
|
||||
}
|
||||
this._LoadingData();
|
||||
|
||||
//如果有通知修改,那么我们刷新这个
|
||||
this._Events.push(end(CommonPanelEventBus.GetInstance(), CommonPanelEventBus.GetInstance().UpdateEvent, (url: string, isdelete?: boolean) =>
|
||||
{
|
||||
if (url === this.props.getUrl)
|
||||
{
|
||||
if (isdelete)
|
||||
{
|
||||
Object.assign(this._CurrentDir, { id: this.props.defaultDirId, path: "", pathNum: [] });
|
||||
RightMaterialPanel.CurrentDirCache.delete(this.props.defaultDirId);
|
||||
}
|
||||
this._LoadingData();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
componentWillUnmount()
|
||||
{
|
||||
if (this._Tree)
|
||||
{
|
||||
this._Tree.removeEventListener('mousedown', this._HandleTreeMouseDown);
|
||||
}
|
||||
|
||||
this._Events.forEach(f => f());
|
||||
this._Events.length = 0;
|
||||
}
|
||||
render()
|
||||
{
|
||||
return (
|
||||
<div id="RightMyMaterialPanel" style={{ position: "relative" }}>
|
||||
<div className="searchMaterial">
|
||||
<input
|
||||
disabled={this.props.defaultDirId === DirectoryId.HistoryDit}
|
||||
className="bp3-input"
|
||||
placeholder="搜索材质..."
|
||||
type="search"
|
||||
defaultValue={this._SearchStr}
|
||||
onKeyDown={(e) => { e.stopPropagation(); }}
|
||||
onChange={(e) => this._HandleSearch(e)}
|
||||
/>
|
||||
</div>
|
||||
<div className="materialParams">
|
||||
<div
|
||||
className="bp3-card img-tree"
|
||||
ref={c => this._Tree = c}
|
||||
>
|
||||
<Tree
|
||||
contents={this.state.nodes}
|
||||
onNodeClick={this._HandleNodeClick}
|
||||
onNodeCollapse={(node) => this._HandleNodeCollapse(node, true)}
|
||||
onNodeExpand={(node) => this._HandleNodeCollapse(node, false)}
|
||||
className={Classes.ELEVATION_0}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="bp3-card img-lib"
|
||||
>
|
||||
{
|
||||
React.Children.map(this.props.children, child =>
|
||||
child && React.cloneElement(child as React.DetailedReactHTMLElement<any, any>,
|
||||
{
|
||||
dataList: this._DataList,
|
||||
currentDir: this._CurrentDir,
|
||||
getData: this._HandleGetData,
|
||||
select: this._HandleSelectData,
|
||||
selectIds: this._SelectIds,
|
||||
})
|
||||
)
|
||||
}
|
||||
{
|
||||
this._PageData.count > this._PageData.pageCount &&
|
||||
<Pagination
|
||||
getImgListFun={this._HandleGetData}
|
||||
pageData={this._PageData}
|
||||
maxCount={3}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_HandleSelectData = (e: React.MouseEvent<HTMLInputElement>, data) =>
|
||||
{
|
||||
const id = data[this._IdKey];
|
||||
const selectIds = this._SelectIds;
|
||||
|
||||
if (e.button === MouseKey.Left)
|
||||
{
|
||||
if (!this.IsCtrlDown)
|
||||
selectIds.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.IsCtrlDown && !selectIds.has(id))
|
||||
selectIds.clear();
|
||||
}
|
||||
|
||||
if (this.IsCtrlDown)
|
||||
{
|
||||
if (selectIds.has(id))
|
||||
selectIds.delete(id);
|
||||
else
|
||||
selectIds.add(id);
|
||||
}
|
||||
else
|
||||
selectIds.add(id);
|
||||
};
|
||||
|
||||
//选中目录亮显
|
||||
_SelectNode = (nodeData: ITreeNode, isSelected?: boolean) =>
|
||||
{
|
||||
this._ForEachNode(this.state.nodes, n => (n.isSelected = false));
|
||||
nodeData.isSelected = true;
|
||||
this.setState(this.state);
|
||||
};
|
||||
|
||||
//点击目录
|
||||
_HandleNodeClick = async (nodeData: ITreeNode, _nodePath: number[]) =>
|
||||
{
|
||||
const isReLoad = nodeData.id !== this._CurrentDir.id;
|
||||
this._GetCurrentDir(nodeData.id, _nodePath);
|
||||
this._SelectIds.clear();
|
||||
if (isReLoad)
|
||||
await this._HandleGetData();
|
||||
this._SelectNode(nodeData);
|
||||
};
|
||||
|
||||
//去掉其他节点被选择状态
|
||||
_ForEachNode(nodes: ITreeNode[], callback: (node: ITreeNode) => void)
|
||||
{
|
||||
if (nodes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const node of nodes)
|
||||
{
|
||||
callback(node);
|
||||
this._ForEachNode(node.childNodes, callback);
|
||||
}
|
||||
}
|
||||
|
||||
//获取当前目录路径
|
||||
_GetCurrentDir = (dirId: React.ReactText, nodePath: number[]) =>
|
||||
{
|
||||
let path = "";
|
||||
let childNodes: ITreeNode[];
|
||||
for (let i of nodePath)
|
||||
{
|
||||
let node: ITreeNode;
|
||||
if (!childNodes)
|
||||
{
|
||||
node = this.state.nodes[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
node = childNodes[i];
|
||||
}
|
||||
path += node.label + "/";
|
||||
childNodes = node.childNodes;
|
||||
}
|
||||
Object.assign(this._CurrentDir, { id: dirId, path, pathNum: nodePath });
|
||||
RightMaterialPanel.CurrentDirCache.set(this.props.defaultDirId, { id: dirId as DirectoryId, path, pathNum: nodePath });
|
||||
};
|
||||
|
||||
//分析目录转换为ui节点数
|
||||
_ParseNodes = (dirs: any) =>
|
||||
{
|
||||
let newNodes: ITreeNode[] = [];
|
||||
for (let dir of dirs)
|
||||
{
|
||||
let node: ITreeNode = {
|
||||
id: dir.dir_id,
|
||||
label: dir.dir_name,
|
||||
icon: "folder-close",
|
||||
hasCaret: dir.childs.length > 0,
|
||||
className: dir.dir_id, //为了识别这个元素的目录id
|
||||
childNodes: this._ParseNodes(dir.childs),
|
||||
};
|
||||
newNodes.push(node);
|
||||
}
|
||||
return newNodes;
|
||||
};
|
||||
|
||||
//展开折叠目录
|
||||
_HandleNodeCollapse = (nodeData: ITreeNode, isCollapse: boolean) =>
|
||||
{
|
||||
nodeData.isExpanded = !isCollapse;
|
||||
this.setState(this.state);
|
||||
};
|
||||
|
||||
/**
|
||||
* 服务段获取数据
|
||||
* name-查询字符串,curr_page-当前页,dir_id:目录id
|
||||
* desc 倒序
|
||||
*/
|
||||
@action
|
||||
_HandleGetData = async (queryData?: { dir_id?: string, name?: string, curr_page?: number; }) =>
|
||||
{
|
||||
let query: any;
|
||||
|
||||
query = {
|
||||
dir_id: this._CurrentDir.id,
|
||||
curr_page: 1,
|
||||
page_count: this._PageData.pageCount,
|
||||
name: this._SearchStr,
|
||||
};
|
||||
|
||||
//若不传入数据,用默认查询数据.
|
||||
if (queryData)
|
||||
{
|
||||
Object.assign(query, queryData);
|
||||
}
|
||||
|
||||
this._PageData.currentPage = query.curr_page;
|
||||
if (query.name && query.dir_id === this.props.defaultDirId)
|
||||
query.dir_id = DirectoryId.None;
|
||||
let data = await PostJson(this.props.getUrl, query);
|
||||
|
||||
if (data.err_code === RequestStatus.Ok && Number(data.count))
|
||||
{
|
||||
let dataList: any[];
|
||||
dataList = data.images || data.materials || data.toplines || data.files || data.modules || [];
|
||||
dataList.forEach(d => d.isChecked = false);
|
||||
this._DataList = dataList;
|
||||
}
|
||||
else
|
||||
this._DataList.length = 0;
|
||||
|
||||
this._PageData.count = parseInt(data.count);
|
||||
this._SelectIds.clear();
|
||||
};
|
||||
|
||||
//点击节点容器的动作
|
||||
_HandleTreeMouseDown = (e: MouseEvent) =>
|
||||
{
|
||||
let el = e.target as HTMLElement;
|
||||
if (e.button === MouseKey.Left)
|
||||
{
|
||||
if (el.classList.contains('bp3-tree'))
|
||||
{
|
||||
this._ForEachNode(this.state.nodes, n => (n.isSelected = false));
|
||||
if (this._CurrentDir.id !== this.props.defaultDirId)
|
||||
{
|
||||
Object.assign(this._CurrentDir, { id: this.props.defaultDirId, path: "", pathNum: [] });
|
||||
RightMaterialPanel.CurrentDirCache.set(this.props.defaultDirId, { id: this.props.defaultDirId as DirectoryId, path: "", pathNum: [] });
|
||||
this._HandleGetData();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_LoadingData = async () =>
|
||||
{
|
||||
let data = await PostJson(DirUrl.query, { dir_type: this.props.defaultDirId });
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
let dirs = data.dirs as { dir_name: string; }[];
|
||||
if (this.props.dirNameFilter)
|
||||
{
|
||||
dirs = dirs.filter(dir =>
|
||||
{
|
||||
return this.props.dirNameFilter.some(s => dir.dir_name.includes(s));
|
||||
});
|
||||
}
|
||||
this.setState({ nodes: this._ParseNodes(dirs) });
|
||||
}
|
||||
let currentDirProps = RightMaterialPanel.CurrentDirCache.get(this.props.defaultDirId);
|
||||
if (currentDirProps)
|
||||
{
|
||||
this._LoadCurrentNode(currentDirProps);
|
||||
}
|
||||
await this._HandleGetData();
|
||||
setTimeout(() =>
|
||||
{
|
||||
if (currentDirProps?.pathNum?.length && this._Tree)
|
||||
{
|
||||
let treeRoot = this._Tree.children[0].children[0];
|
||||
treeRoot.scrollTop = arrayLast(currentDirProps.pathNum) * 30;
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
_LoadCurrentNode = (currentDirProps: IDirectoryProps) =>
|
||||
{
|
||||
let node: ITreeNode;
|
||||
for (let n of currentDirProps.pathNum)
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
node = this.state.nodes[n];
|
||||
}
|
||||
else
|
||||
node = node.childNodes[n];
|
||||
if (!node) return;
|
||||
if (node.childNodes.length)
|
||||
node.isExpanded = true;
|
||||
}
|
||||
if (node)
|
||||
{
|
||||
this._SelectNode(node, true);
|
||||
Object.assign(this._CurrentDir, currentDirProps);
|
||||
}
|
||||
};
|
||||
|
||||
_HandleSearch = async (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
{
|
||||
this._SearchStr = e.currentTarget.value;
|
||||
if (this._TimeId)
|
||||
clearTimeout(this._TimeId);
|
||||
this._TimeId = setTimeout(async () =>
|
||||
{
|
||||
await this._HandleGetData();
|
||||
}, 500);
|
||||
};
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
#RightMyMaterialPanel {
|
||||
height : 100px;
|
||||
padding: 0;
|
||||
|
||||
.searchMaterial{
|
||||
margin: 2px 0 0 0;
|
||||
height: 34px;
|
||||
|
||||
input{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.materialParams{
|
||||
height: calc(100% - 34px);
|
||||
|
||||
.img-tree {
|
||||
height : 40%;
|
||||
width : 100%;
|
||||
padding : 0;
|
||||
overflow: auto;
|
||||
|
||||
.bp3-tree {
|
||||
height : 100%;
|
||||
padding-bottom: 10px;
|
||||
box-shadow: none;
|
||||
|
||||
&>ul {
|
||||
max-height: 95%;
|
||||
overflow : auto;
|
||||
}
|
||||
|
||||
.bp3-tree-node-content-1 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-lib {
|
||||
width : 100%;
|
||||
height : 60%;
|
||||
padding : 0 10px;
|
||||
overflow : visible;
|
||||
position : relative;
|
||||
display : flex;
|
||||
flex-direction: column;
|
||||
|
||||
&>:nth-child(1){
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mat-list:first-child {
|
||||
padding-bottom: 10px;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.look-mat {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&>li {
|
||||
text-align: center;
|
||||
|
||||
.hint:hover::before {
|
||||
content : none;
|
||||
}
|
||||
|
||||
&>.bp3-control {
|
||||
left: 10px;
|
||||
top : 10;
|
||||
}
|
||||
|
||||
&>p {
|
||||
margin-bottom: 0;
|
||||
width : 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-dialog-container {
|
||||
position: fixed;
|
||||
left : 0;
|
||||
top : 0;
|
||||
z-index : 30;
|
||||
|
||||
.bp3-dialog {
|
||||
width : unset;
|
||||
margin : 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue