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

add:新增表格导航视图、表格导航栏部件支持

上级 b60332f1
<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 { ExpViewProps } from "../exp-view";
/**
* 表格导航视图输入参数
*
* @export
* @interface GridExpViewProps
* @extends {ExpViewProps}
*/
export interface GridExpViewProps extends ExpViewProps {}
\ No newline at end of file
import { ExpViewState } from "../exp-view";
/**
* 表格导航视图状态
*
* @export
* @interface GridExpViewState
* @extends {ExpViewState}
*/
export interface GridExpViewState extends ExpViewState {}
\ No newline at end of file
import { ExpView } from "../exp-view";
import { GridExpViewProps } from "./grid-exp-view-prop";
import { GridExpViewState } from "./grid-exp-view-state";
/**
* 表格导航视图
*
* @export
* @class GridExpView
* @extends {ExpView}
*/
export class GridExpView extends ExpView {
/**
* 表格导航视图状态
*
* @type {GridExpViewState}
* @memberof GridExpView
*/
public declare state: GridExpViewState;
/**
* 表格导航视图输入参数
*
* @type {GridExpViewProps}
* @memberof GridExpView
*/
public declare props: GridExpViewProps;
}
\ No newline at end of file
export * from './grid-exp-view-prop';
export * from './grid-exp-view-state';
export { GridExpView } from './grid-exp-view';
\ No newline at end of file
......@@ -15,4 +15,5 @@ export * from './tab-exp-view'
export * from './list-view'
export * from './panel-view'
export * from './pickup-tree-view'
export * from './list-exp-view'
\ No newline at end of file
export * from './list-exp-view'
export * from './grid-exp-view'
\ No newline at end of file
......@@ -45,7 +45,15 @@ export class GridControl extends MDControl {
}
// 表格行样式
const useRowClassName = (record: IParam, index: number) => {
return index % 2 === 1 ? "table-striped" : null;
let classStr: string = '';
if (index % 2 === 1) {
classStr += ' table-striped';
}
const { selectedRowKeys } = toRefs(this.state);
if (selectedRowKeys.value.indexOf(record.srfkey) !== -1) {
classStr += ' ant-table-row-selected';
}
return classStr;
}
// 表格行自定义
const useCustomRow = (record: IParam, index: number) => {
......@@ -78,16 +86,15 @@ export class GridControl extends MDControl {
// 表格选择功能配置
const useRowSelectionOption = computed(() => {
// 作为导航部件或单选时不呈现多选框
if (selectFirstDefault) {
if (selectFirstDefault || !this.state.isMultiple) {
return false;
}
return {
type: this.state.isMultiple ? 'checkbox' : 'radio',
type: 'checkbox',
columnWidth: selectColumnWidth,
selectedRowKeys: this.state.selectedRowKeys,
checkStrictly: false,
onSelect: (record: IParam, selected: boolean, selectedRows: IParam[], $event: any) => {
const { selections } = toRefs(this.state);
if (selected) {
const { appDeKeyFieldName } = this.state;
const selectedRowKey: string = record[appDeKeyFieldName] || record.srfkey;
......@@ -95,21 +102,19 @@ export class GridControl extends MDControl {
if (Object.is(index,-1) && record.children && record.children.length > 0) {
useExpandedRowKeys.value.push(selectedRowKey);
}
selections.value.push(selectedRows);
this.emit("ctrlEvent", { tag: this.props.name, action: "selectionChange", data: selection })
}
},
onChange: (_selectedRowKeys: string[], selectedRows: any[]) => {
this.state.selectedRowKeys = _selectedRowKeys;
const { selectedRowKeys, selections } = toRefs(this.state);
selectedRowKeys.value = [..._selectedRowKeys];
const selection: IParam[] = [];
selectedRows.forEach((select: IParam) => {
if (!select.children) {
selection.push(select);
}
})
});
// 选中赋值
this.state.selections = selection;
selections.value = [...selection];
this.emit("ctrlEvent", { tag: this.props.name, action: "selectionChange", data: selection })
},
};
......@@ -335,10 +340,13 @@ export class GridControl extends MDControl {
public handleDefaultSelect() {
const { selectFirstDefault, items } = this.state;
if (selectFirstDefault && items && items.length) {
const { selectedRowKeys, selections } = toRefs(this.state);
selections.value = [items[0]];
selectedRowKeys.value = [items[0].srfkey];
this.emit("ctrlEvent", {
tag: this.props.name,
action: "selectionChange",
data: [deepCopy(items[0])],
data: [items[0]],
});
}
}
......
import { ExpBarControlProps } from "../exp-bar-control";
/**
* 表格导航栏输入参数
*
* @export
* @interface GridExpBarControlProps
* @extends {ExpBarControlProps}
*/
export interface GridExpBarControlProps extends ExpBarControlProps {}
\ No newline at end of file
import { ExpBarControlState } from "../exp-bar-control";
/**
* 表格导航栏部件状态
*
* @export
* @interface GridExpBarControlState
* @extends {ExpBarControlState}
*/
export interface GridExpBarControlState extends ExpBarControlState {}
\ No newline at end of file
import { ExpBarControl } from "../exp-bar-control";
import { GridExpBarControlProps } from "./grid-exp-bar-control-prop";
import { GridExpBarControlState } from "./grid-exp-bar-control-state";
/**
* 表格导航栏部件
*
* @export
* @class GridExpBarControl
* @extends {ExpBarControl}
*/
export class GridExpBarControl extends ExpBarControl {
/**
* 表格导航栏状态
*
* @type {GridExpBarControlState}
* @memberof GridExpBarControl
*/
public declare state: GridExpBarControlState;
/**
* 表格导航栏输入参数
*
* @type {GridExpBarControlProps}
* @memberof GridExpBarControl
*/
public declare props: GridExpBarControlProps;
}
\ No newline at end of file
export * from './grid-exp-bar-control-prop';
export * from './grid-exp-bar-control-state';
export { GridExpBarControl } from './grid-exp-bar-control';
\ No newline at end of file
......@@ -17,4 +17,5 @@ export * from './tab-exp-panel-control'
export * from './tab-view-panel-control'
export * from './list-control'
export * from './panel-control'
export * from './list-exp-bar-control'
\ No newline at end of file
export * from './list-exp-bar-control'
export * from './grid-exp-bar-control'
\ No newline at end of file
......@@ -21,6 +21,7 @@ const routes = [
{{#if (or
(eq appView.viewType 'DEEDITVIEW')
(eq appView.viewType 'DEGRIDVIEW')
(eq appView.viewType 'DEGRIDEXPVIEW')
(eq appView.viewType 'DELISTVIEW')
(eq appView.viewType 'DELISTEXPVIEW')
(eq appView.viewType 'DEPANELVIEW')
......
import {{page.codeName}} from "./{{spinalCase page.codeName}}.vue";
export default {{page.codeName}};
export const viewState = {
{{#each page.ctrls as | ctrl |}}
{{#if (eq ctrl.controlType "GRIDEXPBAR")}}
gridExpBarName: '{{ctrl.name}}',
{{/if}}
{{/each}}
{{> @macro/front-end/views/view-base-config.hbs}}
};
\ No newline at end of file
<script setup lang="ts">
import { Subject } from 'rxjs';
import { GridExpView, IActionParam, IParam, IContext } from '@core';
import { viewState } from './{{spinalCase page.codeName}}-state';
{{#page.ctrls}}
{{#eq controlType "GRIDEXPBAR"}}
import { {{codeName}}GridExpBar } from '@widgets/{{spinalCase psAppDataEntity.codeName}}/{{spinalCase codeName}}-grid-exp-bar';
{{/eq}}
{{/page.ctrls}}
interface Props {
context?: IContext;
viewParams?: IParam;
openType?: "ROUTE" | "MODAL" | "EMBED";
viewSubject?: Subject<IActionParam>;
}
const props = withDefaults(defineProps<Props>(), {
openType:'ROUTE',
viewSubject: () => new Subject<IActionParam>()
})
interface ViewEmit {
(name: "viewEvent", value: IActionParam): void;
}
const emit = defineEmits<ViewEmit>();
// 安装功能模块
const gridExpView = new GridExpView(viewState, props, emit).moduleInstall()
const { state, onCtrlEvent, onToolbarEvent } = gridExpView;
</script>
<template>
<AppGridExpViewLayout :class="['app-grid-exp-view', state.viewSysCss]">
<template v-slot:caption>
<AppIconText class="app-view__caption" size="large" :text="state.viewCaption" />
</template>
{{#page.ctrls}}
{{#eq controlType "TOOLBAR"}}
<template v-slot:toolbar>
<AppToolbar
mode="button"
name="{{lowerCase codeName}}"
:actionModel="state.toolbar"
@onToolbarEvent="onToolbarEvent"/>
</template>
{{/eq}}
{{#eq controlType "GRIDEXPBAR"}}
<{{codeName}}GridExpBar
name="{{name}}"
:context="state.context"
:showBusyIndicator="true"
:viewParams="state.viewParams"
:viewSubject="state.viewSubject"
:parent="gridExpView"
@ctrlEvent="onCtrlEvent"
></{{codeName}}GridExpBar>
{{/eq}}
{{/page.ctrls}}
</AppGridExpViewLayout>
</template>
\ No newline at end of file
import {{ctrl.codeName}}GridExpBar from "./{{spinalCase ctrl.codeName}}-grid-exp-bar.vue";
export { {{ctrl.codeName}}GridExpBar };
export const ctrlState = {
controlCodeName: '{{ctrl.codeName}}',
controlName: '{{ctrl.name}}',
counter: 0,
enableSearch: {{ctrl.enableSearch}},
xDataControlName: '{{ctrl.xDataControlName}}',
selection: {},
searchValue: '',
showTitleBar: {{#if ctrl.showTitleBar}}true{{else}}false{{/if}},
split: 0.2,
title: '{{ctrl.title}}',
titleRes: '{{#if ctrl.titlePSLanguageRes}}{{ctrl.titlePSLanguageRes.lanResTag}}{{/if}}',
{{#each ctrl.psControls as | childCtrl |}}
{{#eq childCtrl.controlType 'TOOLBAR'}}
toolbar: [
{{#childCtrl.psDEToolbarItems}}
{ name:'{{name}}',caption:'{{caption}}',groupExtractMode:'{{groupExtractMode}}',itemType:'{{itemType}}',noPrivDisplayMode:'{{noPrivDisplayMode}}',showIcon:{{showIcon}},showCaption:{{showCaption}},tooltip:'{{tooltip}}',disabled: false, visible: true, imgPath: '{{imgPath}}',iconClass: '{{iconClass}}',xDataControlName:'{{xDataControlName}}',{{#if psUIAction}}uIAction:{codeName:'{{psUIAction.codeName}}',fullCodeName:'{{psUIAction.fullCodeName}}',uIActionMode:'{{psUIAction.uIActionMode}}',actionTarget:'{{psUIAction.actionTarget}}',uIActionTag:'{{psUIAction.uIActionTag}}',dataAccessAction:'{{psUIAction.dataAccessAction}}',uIActionType:'{{psUIAction.uIActionType}}'}{{#if psUIAction.counterId}},counterId: '{{psUIAction.counterId}}'{{/if}}{{/if}} },
{{/childCtrl.psDEToolbarItems}}
],
{{/eq}}
{{#eq childCtrl.controlType 'GRID'}}
{{childCtrl.name}}: {
action:{
loadAction: '{{childCtrl.getPSControlAction.psAppDEMethod.codeName}}',
removeAction: '{{childCtrl.removePSControlAction.psAppDEMethod.codeName}}',
updateAction: '{{childCtrl.updatePSControlAction.psAppDEMethod.codeName}}',
loadDraftAction: '{{childCtrl.getDraftPSControlAction.psAppDEMethod.codeName}}',
createAction: '{{childCtrl.createPSControlAction.psAppDEMethod.codeName}}',
fetchAction:'{{childCtrl.fetchPSControlAction.psAppDEMethod.codeName}}'
}
},
{{#and childCtrl.navPSDER childCtrl.navPSDER.minorCodeName}}
navPSDer: 'n_{{lowerCase childCtrl.navPSDER.minorCodeName}}_eq',
{{/and}}
{{#if childCtrl.navFilter}}
navFilter: '{{lowerCase childCtrl.navFilter}}',
{{/if}}
{{#if childCtrl.navPSAppView}}
navViewName: '{{childCtrl.navPSAppView.name}}',
{{/if}}
{{#if childCtrl.psNavigateContexts}}
navigateContexts: {{> @macro/front-end/common/navparam.hbs appNavParams=childCtrl.psNavigateContexts}},
{{/if}}
{{#if childCtrl.psNavigateParams}}
navigateParams: {{> @macro/front-end/common/navparam.hbs appNavParams=childCtrl.psNavigateParams}},
{{/if}}
{{/eq}}
{{/each}}
};
<script setup lang="ts">
import { Subject } from 'rxjs';
import { IActionParam, IParam, ControlAction, GridExpBarControl, IContext } from '@core';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-grid-exp-bar-state';
{{#ctrl.psControls}}
{{#eq controlType "GRID"}}
import { {{codeName}}Grid} from '@widgets/{{spinalCase psAppDataEntity.codeName}}/{{spinalCase codeName}}-grid';
{{#if navPSAppView}}
import {{navPSAppView.name}} from '@views/{{spinalCase navPSAppView.psAppModule.codeName}}/{{spinalCase navPSAppView.codeName}}';
{{/if}}
{{/eq}}
{{/ctrl.psControls}}
interface Props {
name:string,
parent: IParam;
context: IContext;
viewParams?: IParam;
showBusyIndicator?: boolean;
viewMode?: number;
viewSubject: Subject<IActionParam>;
}
const props = withDefaults(defineProps < Props > (), {
viewSubject: () => new Subject < IActionParam > (),
viewMode: 0,
showBusyIndicator: true,
});
interface CtrlEmit {
(name: "ctrlEvent", value: IActionParam): void;
}
const emit = defineEmits <CtrlEmit> ();
// 安装功能模块,提供状态和能力方法
const { name, state, onCtrlEvent, xDataControl, search, onToolbarEvent } = new GridExpBarControl(ctrlState, props, emit).moduleInstall();
// 暴露内部状态及能力
defineExpose({ name, state });
</script>
<template>
<div class="app-grid-exp-bar app-exp-bar{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}">
<AppSplit v-model="state.split">
<template #left>
<div v-if="state.enableSearch || state.toolbar || state.showTitleBar" class="exp-bar-header">
<div class="title" v-if="state.showTitleBar"><span>\{{ state.title }}</span></div>
{{~#if ctrl.enableSearch}}
<a-input-search class="search" v-model:value="state.searchValue" @search="search" />
{{/if}}
{{#each ctrl.psControls as | childCtrl |}}
{{#eq childCtrl.controlType 'TOOLBAR'}}
{{!-- TODO 计数器 --}}
<AppToolbar
mode="button"
name="{{lowerCase childCtrl.codeName}}"
:actionModel="state.toolbar"
@onToolbarEvent="onToolbarEvent">
</AppToolbar>
{{/eq}}
{{/each}}
</div>
<div class="exp-bar-body">
{{#ctrl.psControls}}
{{#eq controlType "GRID"}}
<{{codeName}}Grid
ref="xDataControl"
name="{{name}}"
:controlAction="state.{{name}}.action"
:context="state.context"
:viewParams="state.viewParams"
:viewSubject="state.viewSubject"
:selectFirstDefault="true"
:isBranchAvailable="true"
:rowActiveMode="1"
:multiple="false"
:parent="parent"
@ctrlEvent="onCtrlEvent"
></{{codeName}}Grid>
{{/eq}}
{{/ctrl.psControls}}
</div>
</template>
<template #right>
{{#ctrl.psControls}}
{{#eq controlType "GRID"}}
{{#if navPSAppView}}
<{{navPSAppView.name}}
v-if="state.selection && state.selection.key"
class="grid-exp-bar-navview exp-bar-navview"
:context="state.selection.context"
:key="state.selection.key"
:viewDefaultUsage="false"
:viewParams="state.selection.viewParams"
></{{navPSAppView.name}}>
{{/if}}
{{/eq}}
{{/ctrl.psControls}}
</template>
</AppSplit>
</div>
</template>
<style lang="scss" scoped>
.app-grid-exp-bar {
width: 100%;
height: 100%;
}
</style>
\ No newline at end of file
......@@ -24,7 +24,7 @@ interface Props {
const props = withDefaults(defineProps < Props > (), {
viewSubject: () => new Subject < IActionParam > (),
showBusyIndicator: true,
multiple: false,
multiple: true,
rowEditState: false,
rowActiveMode: 0,
selectFirstDefault: false,
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册