feat: print button for descriptions

This commit is contained in:
chenos 2021-04-01 21:15:51 +08:00
parent acb769b0c1
commit b8b5940205
4 changed files with 110 additions and 55 deletions

View File

@ -43,6 +43,7 @@
"react-drag-listview": "^0.1.8",
"react-image-lightbox": "^5.1.1",
"react-sortable-hoc": "^1.11.0",
"react-to-print": "^2.12.3",
"styled-components": "^5.2.1",
"umi": "^3.2.23",
"yorkie": "^2.0.0"

View File

@ -5,11 +5,17 @@ import {
PlusOutlined,
SelectOutlined,
DeleteOutlined,
PrinterOutlined,
ExportOutlined,
} from '@ant-design/icons';
import Drawer from '@/components/pages/AdminLoader/Drawer';
import View from '@/components/pages/AdminLoader/View';
import get from 'lodash/get';
import set from 'lodash/set';
import ReactToPrint from 'react-to-print';
import api from '@/api-client';
const ACTIONS = new Map<string, any>();
export function Create(props) {
const { size, onFinish, schema = {}, associatedKey, ...restProps } = props;
@ -284,20 +290,62 @@ export function Filter(props) {
);
}
export function Print(props) {
const { schema = {}, contentRef } = props;
const { title, buttonProps = {} } = schema;
return (
<ReactToPrint
trigger={() => (
<Button {...buttonProps} icon={<PrinterOutlined />}>
{title}
</Button>
)}
content={() => contentRef.current}
pageStyle={`
@page {
margin: 1cm;
}
table { page-break-inside:auto }
tr { page-break-inside:avoid; page-break-after:auto }
`}
documentTitle={' '}
/>
);
}
export function Export(props) {
const { schema = {}, onFinish } = props;
const { title, buttonProps = {} } = schema;
return (
<Button
{...buttonProps}
icon={<ExportOutlined />}
onClick={async () => {
onFinish && (await onFinish({ fields: [] }));
}}
>
{title}
</Button>
);
}
export function Actions(props) {
const { onTrigger = {}, actions = [], style, ...restProps } = props;
return (
actions.length > 0 && (
<div className={'action-buttons'} style={style}>
{actions.map(action => (
<div className={`${action.type}-action-button action-button`}>
<Action
{...restProps}
onFinish={onTrigger[action.type]}
schema={action}
/>
</div>
))}
{actions.map(
action =>
ACTIONS.has(action.type) && (
<div className={`${action.type}-action-button action-button`}>
<Action
{...restProps}
onFinish={onTrigger[action.type]}
schema={action}
/>
</div>
),
)}
</div>
)
);
@ -305,8 +353,6 @@ export function Actions(props) {
export default Actions;
const ACTIONS = new Map<string, any>();
export function registerAction(type: string, Action: any) {
ACTIONS.set(type, Action);
}
@ -328,3 +374,5 @@ registerAction('update', Update);
registerAction('create', Create);
registerAction('destroy', Destroy);
registerAction('filter', Filter);
registerAction('print', Print);
registerAction('export', Export);

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useRef } from 'react';
import './style.less';
import { Helmet } from 'umi';
import { Spin } from '@nocobase/client';
@ -24,7 +24,6 @@ import Field from '@/components/views/Field';
import { Form } from './Form';
import { configResponsive, useResponsive } from 'ahooks';
import { InfoCircleOutlined } from '@ant-design/icons';
import scopes from '@/components/views/Form/scopes';
configResponsive({
small: 0,
@ -84,6 +83,7 @@ export function Descriptions(props) {
'fields[appends]': appends,
});
});
const contentRef = useRef();
if (loading) {
return <Spin />;
}
@ -97,6 +97,7 @@ export function Descriptions(props) {
};
}
const groups = toGroups(fields);
return (
<div>
<Actions
@ -106,55 +107,58 @@ export function Descriptions(props) {
onDataChange && onDataChange(values);
},
}}
contentRef={contentRef}
associatedKey={associatedKey}
data={data}
actions={actions}
style={{ marginBottom: 14 }}
/>
{groups.map(group => (
<AntdDescriptions
// layout={'vertical'}
// size={'middle'}
// bordered
{...descriptionsProps}
title={
group.title && (
<span>
{group.title}{' '}
{group.tooltip && (
<Tooltip title={group.tooltip}>
<div ref={contentRef} className={'print-content'}>
{groups.map(group => (
<AntdDescriptions
// layout={'vertical'}
// size={'middle'}
// bordered
{...descriptionsProps}
title={
group.title && (
<span>
{group.title}{' '}
{group.tooltip && (
<Tooltip title={group.tooltip}>
<InfoCircleOutlined />
</Tooltip>
)}
</span>
)
}
column={1}
>
{group.children.map((field: any) => {
const label = field.tooltip ? (
<>
{field.title || field.name}&nbsp;
<Tooltip title={field.tooltip}>
<InfoCircleOutlined />
</Tooltip>
)}
</span>
)
}
column={1}
>
{group.children.map((field: any) => {
const label = field.tooltip ? (
<>
{field.title || field.name}&nbsp;
<Tooltip title={field.tooltip}>
<InfoCircleOutlined />
</Tooltip>
</>
) : (
field.title || field.name
);
return (
<AntdDescriptions.Item label={label}>
<Field
data={data}
viewType={'descriptions'}
schema={field}
value={get(data, field.name)}
/>
</AntdDescriptions.Item>
);
})}
</AntdDescriptions>
))}
</>
) : (
field.title || field.name
);
return (
<AntdDescriptions.Item label={label}>
<Field
data={data}
viewType={'descriptions'}
schema={field}
value={get(data, field.name)}
/>
</AntdDescriptions.Item>
);
})}
</AntdDescriptions>
))}
</div>
</div>
);
}

View File

@ -25,6 +25,8 @@ export default {
title: '操作类型',
dataSource: [
{ label: '筛选', value: 'filter' },
{ label: '打印', value: 'print' },
{ label: '导出', value: 'export' },
{ label: '新增', value: 'create' },
{ label: '编辑', value: 'update' },
{ label: '删除', value: 'destroy' },