import { Component } from 'vue-property-decorator';
import { VueLifeCycleProcessing } from '../../../decorators';
import { contextMenu, ContextMenuItem } from '@ibiz/context-menu';
import { DesignContainerBase } from '../design-container-base/design-container-base';
import { Util } from '@ibizstudio-ex/runtime';
@Component({})
@VueLifeCycleProcessing()
export class DesignGridContainer extends DesignContainerBase {
/**
* 子数据布局模式支持
*
* @author chitanda
* @date 2022-03-21 10:03:40
* @type {number[][]}
*/
layoutMode: number[][] = [[12], [3, 6, 3], [3, 9], [9, 3], [6, 6], [4, 4, 4], [3, 3, 3, 3]];
/**
* @description 子项默认参数
* @memberof DesignContainerGrid
*/
defaultChildParam = { itemtype: 'CONTAINER', showcaption: 0, playoutmode: 'SIMPLEFLEX' };
/**
* @description 自定义右键菜单项
* @type {ContextMenuItem[]}
* @memberof DesignContainerGrid
*/
contextMenus: ContextMenuItem[] = [
{
tag: 'addBefore',
text: '在左侧添加',
icon: 'assets/svg/double-left-arrow.svg',
},
{
tag: 'addAfter',
text: '在右侧添加',
icon: 'assets/svg/double-right-arrow.svg',
},
{
type: 'separator',
},
{
tag: 'remove',
text: '删除',
icon: 'assets/svg/trash.svg',
},
];
/**
* 选择子项布局绘制模式
*
* @author chitanda
* @date 2022-03-21 15:03:46
* @return {*} {VNode}
*/
renderSelectModel(): any {
return (
{this.layoutMode.map(arr => {
return (
this.onCellClick(e, arr)}
>
{arr.map(item => {
return (
{item}
);
})}
);
})}
取消
);
}
/**
* @description 栅格子项
* @param {MouseEvent} e
* @param {number[]} arr
* @return {*} {Promise}
* @memberof DesignGroup
*/
async onCellClick(e: MouseEvent, arr: number[]): Promise {
e.stopPropagation();
this.service.disableAcc();
const items = arr.map((num, index) => {
return {
...this.defaultChildParam,
flexgrow: num,
srfpkey: this.data.srfkey,
srfkey: Util.createUUID(),
ppssysviewpanelitemid: this.data.pssysviewpanelitemid,
ppssysviewpanelitemname: this.data.pssysviewpanelitemname,
ordervalue: (index + 1) * 100,
};
});
for (let index = 0; index < items.length; index++) {
const data = items[index];
const res = await this.service.GetDraftTemp(this.context, data);
if (res.ok) {
await this.service.CreateTemp(this.context, res.data);
}
}
this.service.enableAcc();
(this.ctx.ctrl as any).evt.emit("refreshPanel");
}
/**
* 取消新建
*
* @author chitanda
* @date 2022-03-21 18:03:12
* @param {MouseEvent} e
*/
onCancel(e: MouseEvent): void {
e.stopPropagation();
this.deleteHandle(e);
}
/**
* 绘制栅格容器
*
* @author chitanda
* @date 2022-03-22 15:03:20
* @param {number} i
* @param {PanelLayoutDataProvider} data
* @return {*} {VNode}
*/
renderGridContainer(i: number, data: any): any {
const style: Record = {};
if (data.flexgrow != null && data.flexgrow > 0) {
style.width = `${(data.flexgrow / 12) * 100}%`;
} else {
style['flex-grow'] = 1;
style['flex-basis']=0;
style.width = "auto";
style.minWidth = `${(1 / 12) * 100}%`;
}
return (
this.onContextMenu(e, i, data),
}}
/>
);
}
/**
* @description 点击打开自定义功能菜单
* @param {MouseEvent} event
* @param {number} i
* @param {*} data
* @memberof DesignGroup
*/
onContextMenu(event: MouseEvent, i: number, data: any): void {
if (event) {
event.stopPropagation();
}
contextMenu.open(event, this.contextMenus, { minWidth: 150 }).click((item: ContextMenuItem) => {
this.onContextMenuClick(event, item, i, data);
});
}
/**
* 上下文菜单点击
*
* @author chitanda
* @date 2022-03-22 15:03:38
* @param {MouseEvent} e
* @param {ContextMenuItem} item
* @param {number} i 数据位置
* @param {PanelLayoutDataProvider} data 当前数据
*/
onContextMenuClick($event: MouseEvent, item: ContextMenuItem, i: number, data: any): void {
switch (item.tag) {
case 'addBefore':
this.addAutoChild(i);
break;
case 'addAfter':
this.addAutoChild(i + 1);
break;
case 'remove':
this.deleteChild(data);
break;
}
}
/**
* 添加一个自适应子
*
* @author chitanda
* @date 2022-03-22 17:03:10
* @param {number} i 需要插入的位置
* @return {*} {Promise}
*/
async addAutoChild(i: number): Promise {
const param = {
...this.defaultChildParam,
srfpkey: this.data.srfkey,
srfkey: Util.createUUID(),
ppssysviewpanelitemid: this.data.pssysviewpanelitemid,
ppssysviewpanelitemname: this.data.pssysviewpanelitemname,
};
const res = await this.service.GetDraftTemp(this.context, param);
if (res.ok) {
this.service.disableAcc();
const result = await this.service.CreateTemp(this.context, res.data);
if (result.ok) {
this.list.splice(i, 0, result.data);
await this.sortChildren(i);
}
this.service.enableAcc();
}
}
/**
* 从第几个开始重新排序
*
* @author chitanda
* @date 2022-02-21 19:02:03
* @param {number} num 开始排序下标
*/
async sortChildren(num: number) {
if (this.list.length === 0) {
this.$forceUpdate();
return;
}
for (let i = num; i < this.list.length; i++) {
const item = this.list[i];
item.ordervalue = (i + 1) * 100;
}
const items = this.list.slice(num);
await this.service.updateBatchLocal(this.context, items);
}
/**
* 删除子数据
*
* @author chitanda
* @date 2022-02-21 16:02:47
* @param {PanelDataProvider} data
* @return {*} {Promise}
*/
deleteChild(data: any): void {
this.service.disableAcc()
this.service.RemoveTemp(this.context, data);
const i = this.list.findIndex(item => item.pssysviewpanelid === data.pssysviewpanelid);
this.list.splice(i, 1);
this.setSelect(this.data);
this.sortChildren(i);
this.service.enableAcc();
this.$forceUpdate();
}
/**
* @description 绘制子项
* @param {*} item
* @return {*}
* @memberof DesignGroup
*/
renderChildItem(item: any) {
if (item.isDefaultLayout || item.isCtrls) {
return null;
}
return this.ctx.ctrl.renderChildItem(this.$createElement, this.ctx, item, this.data);
}
/**
* @description 绘制拖拽区
* @param {any[]} list
* @param {*} [content]
* @return {*} {*}
* @memberof DesignGroup
*/
renderDraggable(list: any[], content?: any): any {
const h = this.$createElement;
return h(
'draggable',
{
attrs: {
handle: this.options.handle,
group: this.options.group,
ghostClass: 'ghostClass-draggle',
forceFallback: true,
animation: this.options.animation,
list: list,
},
class: 'draggable-container',
on: {
change: (e: any) => this.change(e, list),
},
},
[
h(
'transition-group',
{
attrs: {
type: 'transition',
name: 'flip-list',
},
class: this.getDraggableClass(),
...this.getDraggableOtherParams(),
},
content,
),
],
);
}
/**
* @description 外层容器-重绘
* @return {*} {*}
* @memberof DesignContainerGrid
*/
renderContent(): any {
const { text, showcaption, showtitlebar } = this.data;
const contentStyle = this.getContentStyle(this.data);
const hiddenHeader = showcaption == 0 || showtitlebar == 0;
return (
{
hiddenHeader ? (
) : (
)
}
< div class='content' style={contentStyle}>
{Object.is(this.list?.length, 0)
? this.renderSelectModel() : null
}
{this.list?.map((item: any, i: number) => this.renderGridContainer(i, item))}
);
}
render() {
const { srfkey } = this.data;
this.calcStyle();
return (
this.onActiveClick(e, this.data)}
on-dblclick={(e: any) => this.editorHandle(e)}
>
{this.renderContent()}
{this.renderOther()}
);
}
}