提交 be500336 编写于 作者: Mosher's avatar Mosher

update:更新面板

上级 8bf6fa90
......@@ -4,4 +4,5 @@
{{#eq ctrl.controlType "LIST"}}{{> @macro/front-end/views/view-control/view-list/view-control-list.hbs}}{{/eq~}}
{{#eq ctrl.controlType "APPMENU"}}{{> @macro/front-end/views/view-control/view-menu/view-control-menu.hbs}}{{/eq~}}
{{#eq ctrl.controlType "PICKUPVIEWPANEL"}}{{> @macro/front-end/views/view-control/view-pickup-panel/view-pickup-panel.hbs}}{{/eq~}}
{{#eq ctrl.controlType "TREEVIEW"}}{{> @macro/front-end/views/view-control/view-tree/view-control-tree.hbs}}{{/eq~}}
\ No newline at end of file
{{#eq ctrl.controlType "TREEVIEW"}}{{> @macro/front-end/views/view-control/view-tree/view-control-tree.hbs}}{{/eq~}}
{{#eq ctrl.controlType "PANEL"}}{{> @macro/front-end/views/view-control/view-panel/view-control-panel.hbs}}{{/eq~}}
\ No newline at end of file
{{ctrl.name}}:{
action:{
loadAction: '{{ctrl.getPSControlAction.psAppDEMethod.codeName}}',
removeAction: '{{ctrl.removePSControlAction.psAppDEMethod.codeName}}',
updateAction: '{{ctrl.updatePSControlAction.psAppDEMethod.codeName}}',
loadDraftAction: '{{ctrl.getDraftPSControlAction.psAppDEMethod.codeName}}',
createAction: '{{ctrl.createPSControlAction.psAppDEMethod.codeName}}'
}
},
\ No newline at end of file
<AppPanelButton
{{#if item.caption}}
caption="{{item.caption}}"
{{/if}}
class="app-panel-button app-panel-button__{{lowerCase item.name}}{{#if item.psSysCss}} {{item.psSysCss.cssName}}{{/if}}"
name="{{item.name}}"
tooltip="{{#if item.tooltip}}{{item.tooltip}}{{else if item.caption}}{{item.caption}}{{/if}}"
:visible="state.detailsModel.{{item.name}}.visible"
:disabled="state.detailsModel.{{item.name}}.disabled"
:uIAction="state.detailsModel.{{item.name}}.uIAction"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
{{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}}
:showCaption="{{item.showCaption}}"
@onPanelItemEvents="onPanelItemEvents">
<AppIconText {{#if item.labelPSSysCss}}class="{{item.labelPSSysCss.cssName}}" {{/if}}{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}" {{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}" {{/if}}{{/if}}text="{{item.caption}}"/>
</AppPanelButton>
......@@ -13,11 +13,10 @@
{{#if item.psSysImage.imagePath}}
imgPath="{{item.psSysImage.imagePath}}"
{{/if}}
:showCaption="{{item.showCaption}}"
{{#if item.labelPSSysCss}}
labelCssName="{{item.labelPSSysCss.cssName}}"
{{/if}}
>
:showCaption="{{item.showCaption}}">
{{#if item.psPanelItems}}
{{#each item.psPanelItems as | childItem |}}
{{> @macro/front-end/widgets/panel-detail/include-panel.hbs item=childItem type=childItem.itemType}}
......
{{item.name}}: {
{{#eq itemType 'TABPANEL'}}
{{#each item.psPanelTabPages}}
{{#eq @index 0}}
activedKey: '{{lowerCase this.name}}',
{{/eq}}
{{/each}}
{{/eq}}
{{#item}}
caption: '{{caption}}',
disabled: false,
......@@ -11,7 +18,7 @@
uIAction: {
actionTarget: '{{actionTarget}}',
dataAccessAction: '{{dataAccessAction}}',
noPrivDisplayMode: '{{noPrivDisplayMode}}'
noPrivDisplayMode: '{{noPrivDisplayMode}}',
uIActionType: '{{uIActionType}}',
uIActionTag: '{{uIActionTag}}',
uIActionMode: '{{uIActionMode}}',
......@@ -27,10 +34,6 @@
{{/if}}
{{#if item.psPanelTabPages}}
{{#each item.psPanelTabPages as | tabPage |}}
{{#if tabPage.psPanelItems}}
{{#each tabPage.psPanelItems as | tabPanel |}}
{{> @macro/front-end/widgets/panel-detail/panel-detail-model.hbs item=tabPanel}}
{{/each}}
{{/if}}
{{> @macro/front-end/widgets/panel-detail/panel-detail-model.hbs item=tabPage}}
{{/each}}
{{/if}}
......@@ -15,14 +15,13 @@
{{#if item.psSysImage.imagePath}}
imgPath="{{item.psSysImage.imagePath}}"
{{/if}}
:showCaption="{{item.showCaption}}"
{{#if item.labelPSSysCss}}
labelCssName="{{item.labelPSSysCss.cssName}}"
{{/if}}
{{#if item.labelPos}}
labelPos="{{item.labelPos}}"
{{/if}}
>
:showCaption="{{item.showCaption}}">
{{#if item.psEditor}}
<div class="panel-editor-container" style="{{#if item.psEditor.editorWidth}}width: {{item.psEditor.editorWidth}}px;{{/if}}{{#if item.psEditor.editorHeight}}height: {{item.psEditor.editorHeight}}px{{/if}}">
{{> @macro/front-end/editors/include-editor.hbs type=item.psEditor.editorType item=item ctrlType="panel"}}
......
<AppPanelRaw
name="{{item.name}}"
:visible="state.detailsModel.{{item.name}}.visible"
class="app-panel-rawitem app-panel-rawitem__{{lowerCase item.name}}{{#if item.psSysCss}} {{item.psSysCss.cssName}}{{/if}}"
{{#if item.psSysImage}}
{{#if item.psSysImage.cssClass}}
iconClass="{{item.psSysImage.cssClass}}"
{{/if}}
{{#if item.psSysImage.imagePath}}
imgPath="{{item.psSysImage.imagePath}}"
{{/if}}
{{/if}}
{{#if (and item.psLayoutPos (or item.psLayoutPos.width item.psLayoutPos.height))}}
style="{{#if item.psLayoutPos.width}}width: {{item.psLayoutPos.width}}px; {{/if}}{{#if item.psLayoutPos.height}}height: {{item.psLayoutPos.height}}px; {{/if}}"
{{/if}}
{{#if (or (gt item.rawItemWidth 0) (gt item.rawItemHeight 0))}}
rawStyle="{{#gt item.rawItemWidth 0}}width: {{item.rawItemWidth}}px; {{/gt}}{{#gt item.rawItemHeight 0}}height: {{item.rawItemHeight}}px;{{/gt}}"
{{/if}}
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
{{#if (eq item.contentType 'RAW')}}
value="{{item.rawContent}}"
{{else if (eq item.contentType 'HTML')}}
:value="`{{item.htmlContent}}`"
{{/if}}
contentType="{{item.contentType}}">
</AppPanelRaw>
<AppPanelTabPage
name="{{item.name}}"
caption="{{item.caption}}"
tabClass="app-panel-tabpage app-panel-tabpage__{{lowerCase item.name}}{{#if item.psSysCss}} {{item.psSysCss.cssName}}{{/if}}"
key="{{item.name}}"
:visible="state.detailsModel.{{item.name}}.visible"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
{{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}}
{{#if item.labelPSSysCss}}
labelCssName="{{item.labelPSSysCss.cssName}}"
{{/if}}
:showCaption="{{item.showCaption}}">
<template #tab>
<AppIconText {{#if item.labelPSSysCss}}class="{{item.labelPSSysCss.cssName}}" {{/if}}{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}" {{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}" {{/if}}{{/if}}text="{{item.caption}}"/>
</template>
{{#if item.psPanelItems}}
{{#each item.psPanelItems as | childItem |}}
{{> @macro/front-end/widgets/panel-detail/include-panel.hbs item=childItem type=childItem.itemType}}
{{/each}}
{{/if}}
</AppPanelTabPage>
<AppPanelTabPanel
:activeKey="state.detailsModel.{{item.name}}.activedKey"
name="{{item.name}}"
class="app-panel-tabpanel app-panel-tabpanel__{{lowerCase item.name}}{{#if item.psSysCss}} {{item.psSysCss.cssName}}{{/if}}"
:visible="state.detailsModel.{{item.name}}.visible"
{{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}}
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}">
{{#if item.psPanelTabPages}}
{{#each item.psPanelTabPages as | tabPage |}}
{{> @macro/front-end/widgets/panel-detail/include-panel.hbs item=tabPage type=tabPage.itemType}}
{{/each}}
{{/if}}
</AppPanelTabPanel>
......@@ -25,16 +25,21 @@ const attrs = useAttrs()
let slotStyle = computed(() => {
// 有根元素无需传样式给插槽
if(!props.noRoot){
return ''
}
let result = '';
if (attrs.style) {
result += isObject(attrs.style) ? styleObj2Str(attrs.style) : attrs.style;
return {};
}
let result = {};
if (layout?.value?.colStyle) {
result += layout.value.colStyle;
Object.assign(result, layout.value.colStyle);
}
if (props.layoutOpts?.selfLayout === 'FLEX' && layout?.value?.rowStyle) {
Object.assign(result, layout.value.rowStyle);
}
if (!props.visible) {
Object.assign(result, { display: 'none' });
}
if (attrs.style) {
Object.assign(result, attrs.style);
}
result += props.visible == true ? "" : "display: none;";
return result;
});
// 插槽类名
......
<script setup lang="ts">
import { IActionParam, IParam, deepCopy, ILayoutOpts } from '@core';
interface IProps {
name: string;
tooltip: string;
caption?: string;
visible?: boolean;
showCaption?: boolean;
disabled?: boolean;
uIAction: IParam;
layoutOpts: ILayoutOpts;
}
const props = withDefaults(defineProps<IProps>(), {
visible: true,
showCaption: true,
disabled: false
});
interface EmitEvents {
(name: 'onPanelItemEvents', value: IActionParam): void
}
const emit = defineEmits<EmitEvents>();
// 按钮点击
const click = (event: MouseEvent) => {
const params = deepCopy(props.uIAction);
Object.assign(params, { event: event });
emit('onPanelItemEvents', { tag: props.name, action: 'PanelButton', data: params });
}
</script>
<template>
<a-col v-show="visible">
<a-button type="primary" :disabled="disabled" @click.stop="click">
<slot></slot>
</a-button>
</a-col>
</template>
\ No newline at end of file
<script setup lang="ts">
import { ILayoutOpts } from "@core";
import { ILayoutOpts, LayoutTool } from "@core";
// 输入参数
interface IProps {
caption?: string
......@@ -11,14 +11,32 @@ interface IProps {
const props = withDefaults(defineProps<IProps>(), {
showCaption: true
});
const layout = LayoutTool.useLayout(toRef(props, "layoutOpts"));
const attrs = useAttrs();
const getStyle = computed(() => {
const { parentLayout, selfLayout } = props.layoutOpts;
const style = {};
if (parentLayout === 'FLEX') {
Object.assign(style, layout.value.colStyle);
}
if (selfLayout === 'FLEX') {
Object.assign(style, layout.value.rowStyle);
}
if (attrs.style) {
Object.assign(style, attrs.style);
}
return style;
});
</script>
<template>
<AppCol noRoot :visible="visible" :layoutOpts="layoutOpts">
<template #default="{ slotClass, slotStyle }">
<div :class="slotClass" :style="slotStyle">
<slot></slot>
</div>
</template>
</AppCol>
<a-col v-show="visible" :style="getStyle">
<div v-if="showCaption" class="panel-container-header">
<span class="text">{{caption}}</span>
</div>
<slot></slot>
</a-col>
</template>
\ No newline at end of file
<script setup lang="ts">
import { IActionParam, ILayoutOpts, IParam } from "@core";
interface FormRawProps{
name: string;
layoutOpts: ILayoutOpts;
visible?: boolean;
iconClass?: string;
imgPath?: string;
value?:any;
contentType?: string;
rawStyle?: IParam
}
const props = withDefaults(defineProps<FormRawProps>(), {
visible: true,
});
</script>
<template>
<AppCol :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-panel-raw">
<template #default="{ slotStyle, slotClass }">
<AppRaw
:name="name"
:class="slotClass"
:style="slotStyle"
:iconClass="iconClass"
:value="value"
:rawStyle="rawStyle"
:contentType="contentType">
</AppRaw>
</template>
</AppCol>
</template>
<style lang="scss">
</style>
\ No newline at end of file
<script setup lang="ts">
import { ILayoutOpts } from '@core';
interface IProps {
tabClass: string;
caption?: string
name: string;
layoutOpts: ILayoutOpts;
visible: boolean;
showCaption?: boolean
}
// 输入参数
const props = withDefaults(defineProps<IProps>(), {
showCaption: true
});
</script>
<template>
<a-tab-pane :class="tabClass" v-show="visible" :key="name">
<AppRow :layoutOpts="layoutOpts">
<slot></slot>
</AppRow>
</a-tab-pane>
</template>
\ No newline at end of file
<script setup lang="ts">
import { ILayoutOpts } from '@core';
interface IProps {
activeKey: string;
caption?: string
name: string;
layoutOpts: ILayoutOpts;
visible: boolean;
showCaption?: boolean;
}
// 输入参数
const props = withDefaults(defineProps<IProps>(), {
showCaption: true
});
</script>
<template>
<AppCol :visible="visible" :layoutOpts="layoutOpts" noRoot>
<template #default="{ slotClass, slotStyle }">
<a-tabs v-model:activeKey="activeKey" :class="slotClass" :style="slotStyle">
<slot></slot>
</a-tabs>
</template>
</AppCol>
</template>
\ No newline at end of file
<script setup lang="ts">
</script>
<template>
<AppViewBaseLayout>
<template v-slot:header-left>
<slot name="caption" />
</template>
<template v-slot:header-right>
<slot name="toolbar" />
</template>
<template v-slot:header-bottom>
<slot name="topMessage" />
<slot name="searchForm" />
</template>
<template v-slot:body-top>
<slot name="bodyMessage" />
</template>
<slot />
<template v-slot:footer-content>
<slot name="bottomMessage" />
</template>
</AppViewBaseLayout>
</template>
<style lang="scss">
</style>
\ No newline at end of file
import { ILayoutOpts, notEmpty } from '@core';
import { ILayoutOpts, notEmpty, IParam } from '@core';
import { isNumber } from 'qx-util';
import { Ref } from 'vue';
......@@ -17,16 +17,27 @@ export class LayoutTool {
* @returns {string}
* @memberof LayoutTool
*/
public static getRowFlexStyle(layoutOpts: ILayoutOpts): string {
public static getRowFlexStyle(layoutOpts: ILayoutOpts): IParam {
if (layoutOpts?.selfLayout == 'FLEX') {
const { dir, align, vAlign } = layoutOpts;
let cssStyle: string = 'width: 100%; height: 100%; overflow: auto; display: flex;';
cssStyle += dir ? `flex-direction: ${dir};` : '';
cssStyle += align ? `justify-content: ${align};` : '';
cssStyle += vAlign ? `align-items: ${vAlign};` : '';
const cssStyle = {
width: '100%',
height: '100%',
overflow: 'auto',
display: 'flex'
};
if (dir) {
Object.assign(cssStyle, { 'flex-direction': dir });
}
if (align) {
Object.assign(cssStyle, { 'justify-content': align });
}
if (vAlign) {
Object.assign(cssStyle, { 'align-items': vAlign });
}
return cssStyle;
} else {
return '';
return {};
}
}
......@@ -38,12 +49,14 @@ export class LayoutTool {
* @returns {string}
* @memberof LayoutTool
*/
public static getColFlexStyle(layoutOpts: ILayoutOpts): string {
public static getColFlexStyle(layoutOpts: ILayoutOpts): IParam {
if (layoutOpts?.parentLayout == 'FLEX' && notEmpty(layoutOpts.grow)) {
let grow = layoutOpts.grow! < 0 ? 0 : layoutOpts.grow;
return `flex-grow: ${grow};`;
return {
'flex-grow': grow
}
}
return '';
return {};
}
/**
......@@ -112,9 +125,9 @@ export class LayoutTool {
*/
public static useLayout(layoutOpts: Ref<ILayoutOpts>) {
// 创建新的ref对象
const layoutResult: Ref<{ rowStyle: string; colStyle: string; colGridOpts: any }> = ref({
rowStyle: '',
colStyle: '',
const layoutResult: Ref<{ rowStyle: IParam; colStyle: IParam; colGridOpts: any }> = ref({
rowStyle: {},
colStyle: {},
colGridOpts: {},
});
watch(
......
......@@ -13,3 +13,4 @@ export * from './tree-view'
export * from './portal-view'
export * from './tab-exp-view'
export * from './list-view'
export * from './panel-view'
\ No newline at end of file
export * from './panel-view-prop'
export * from './panel-view-state'
export * from './panel-view'
\ No newline at end of file
import { MainViewProps } from "../main-view";
/**
* 实体面板视图输入参数
*
* @export
* @interface PanelViewProps
* @extends {MainViewProps}
*/
export interface PanelViewProps extends MainViewProps {
}
\ No newline at end of file
import { MainViewState } from "../main-view";
/**
* 实体面板视图状态
*
* @export
* @interface PanelViewState
* @extends {MainViewState}
*/
export interface PanelViewState extends MainViewState {}
\ No newline at end of file
import { IParam } from "@core/interface";
import { MainView } from "../main-view";
import { PanelViewState } from "./panel-view-state";
/**
* 实体面板视图
*
* @export
* @class PanelView
* @extends {MainView}
*/
export class PanelView extends MainView {
/**
* 实体面板视图输入参数
*
* @type {PanelViewState}
* @memberof PanelView
*/
public declare state: PanelViewState;
/**
* 面板部件引用
*
* @type {IParam}
* @memberof PanelView
*/
public declare panel: IParam;
/**
* 视图初始化模块
*
* @memberof PanelView
*/
public useViewInit(): void {
super.useViewInit();
this.panel = ref(null);
}
/**
* 安装视图所有功能模块
*
* @return {*}
* @memberof PanelView
*/
public moduleInstall() {
const superParams = super.moduleInstall();
return {
...superParams,
panel: this.panel
};
}
}
\ No newline at end of file
......@@ -85,10 +85,56 @@ export class PanelControl extends MainControl {
return load;
}
/**
* 加载面板数据
*
* @private
* @param {IParam} [opts={}]
* @memberof PanelControl
*/
private loadPanelData(opts: IParam = {}) {
}
/**
* 处理面板项事件
*
* @protected
* @param {IActionParam} actionParam
* @memberof PanelControl
*/
protected onPanelItemEvents(actionParam: IActionParam) {
const { tag, action, data } = actionParam;
switch (action) {
case 'PanelButton':
this.handleButtonAction(tag, data);
break;
}
}
/**
* 处理按钮行为
*
* @private
* @param {string} tag 按钮标识
* @param {IParam} action 数据源
* @memberof PanelControl
*/
private handleButtonAction(tag: string, action: IParam) {
if (!action) {
console.warn("面板按钮执行参数不足");
return;
}
const inputParam = {
context: this.state.context,
viewParams: this.state.viewParams,
data: this.getData(),
event: action.event,
actionEnvironment: this
}
App.getAppActionService().execute(action, inputParam);
}
/**
* @description 安装部件所有功能模块的方法
* @return {*}
......@@ -100,6 +146,7 @@ export class PanelControl extends MainControl {
return {
...superParams,
load: this.useLoad(),
onPanelItemEvents: this.onPanelItemEvents.bind(this)
}
}
......
import {{page.codeName}} from "./{{spinalCase page.codeName}}.vue";
export default {{page.codeName}};
export const viewState = {
{{> @macro/front-end/views/view-base-config.hbs}}
};
\ No newline at end of file
<script setup lang="ts">
import { Subject } from 'rxjs';
import { PanelView, IActionParam, IParam, IContext } from '@core';
import { viewState } from './{{spinalCase page.codeName}}-state';
{{#page.ctrls}}
{{#eq controlType "PANEL"}}
import { {{codeName}}Panel } from '@widgets/{{spinalCase psAppDataEntity.codeName}}/{{spinalCase codeName}}-panel';
{{/eq}}
{{/page.ctrls}}
// props声明和默认值处理
interface Props {
context?: IContext;
viewParams?: IParam;
openType?: "ROUTE" | "MODAL" | "EMBED";
viewSubject?: Subject<IActionParam>;
}
const props = withDefaults(defineProps<Props>(), {
openType:'ROUTE',
viewSubject: () => new Subject<IActionParam>()
})
// emit声明
interface ViewEmit {
(name: "viewEvent", value: IActionParam): void;
}
const emit = defineEmits<ViewEmit>();
// 安装功能模块,提供状态和能力方法
const panelView = new PanelView(viewState, props, emit).moduleInstall();
const { state, panel, onToolbarEvent, onCtrlEvent } = panelView;
{{#if page.psAppCounterRefs}}
// 计数器数据
const counterData = computed(() => {
const { counterServices } = toRefs(state);
if (counterServices && counterServices.value && counterServices.value.length) {
return counterServices.value[0].data;
}
return {};
})
{{/if}}
</script>
<template>
<AppPanelViewLayout :class="['app-panel-view', state.viewSysCss]" :showCaptionBar="state.showCaptionBar">
<template v-slot:caption>
<AppIconText
class="app-view__caption"
size="large"
:subCaption="state.subCaption"
:text="state.viewCaption"
/>
</template>
{{#page.ctrls}}
{{#eq controlType "TOOLBAR"}}
<template v-slot:toolbar>
<AppToolbar
mode="button"
name="{{lowerCase codeName}}"
:actionModel="state.toolbar"
{{#if page.psAppCounterRefs}}
:counterData="counterData"
{{/if}}
@onToolbarEvent="onToolbarEvent"/>
</template>
{{/eq}}
{{#eq controlType "PANEL"}}
<{{codeName}}Panel
ref="panel"
name="{{name}}"
:showBusyIndicator="true"
:context="state.context"
:viewParams="state.viewParams"
:controlAction="state.{{name}}.action"
:viewSubject="state.viewSubject"
:parent="panelView"
@ctrlEvent="onCtrlEvent"
></{{codeName}}Panel>
{{/eq}}
{{/page.ctrls}}
</AppPanelViewLayout>
</template>
<style lang="scss">
</style>
\ No newline at end of file
......@@ -28,10 +28,10 @@ interface CtrlEmit {
const emit = defineEmits <CtrlEmit> ();
// 安装功能模块,提供状态和能力方法
const { name, state, load, loadDraft, save, remove, refresh, onEditorEvent, onComponentEvent, getData, xDataCtrl } = new PanelControl(ctrlState, props, emit).moduleInstall();
const { name, state, load, onPanelItemEvents, getData, xDataCtrl } = new PanelControl(ctrlState, props, emit).moduleInstall();
// 暴露内部状态及能力
defineExpose({ name, state, load, loadDraft, save, remove, refresh, getData });
defineExpose({ name, state, load, getData });
</script>
<template>
<AppRow
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册