runningTree的边界容错
This commit is contained in:
parent
f023e98125
commit
ce35a8c292
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
|
|
@ -14,4 +15,4 @@ export default function Render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
}[];
|
||||
}, {
|
||||
makeItems: (isMobile: boolean) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useEffect } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Space, Button, Divider, Popover, Typography, } from 'antd';
|
||||
import { MoreOutlined, } from '@ant-design/icons';
|
||||
import Style from './mobile.module.less';
|
||||
|
|
@ -12,5 +11,22 @@ export default function Render(props) {
|
|||
useEffect(() => {
|
||||
makeItems(isMobile);
|
||||
}, [zhCNKeys]);
|
||||
return (_jsxs("div", { className: Style.container, children: [items && items.map((ele, index) => (_jsxs(_Fragment, { children: [_jsx("div", { className: Style.btn, onClick: ele.onClick, children: _jsx(Typography.Link, { children: ele.label }) }), index !== items.length - 1 && (_jsx(Divider, { type: "vertical" }))] }))), moreItems && moreItems.length > 0 && (_jsx(Divider, { type: "vertical" })), moreItems && moreItems.length > 0 && (_jsx(Popover, { placement: 'topRight', content: _jsx(Space, { direction: "vertical", children: moreItems.map((ele) => (_jsx(Button, { size: "small", type: "link", onClick: ele.onClick, children: ele.label }))) }), trigger: "click", children: _jsx(Button, { type: "link", icon: (_jsx(MoreOutlined, {})) }) }))] }));
|
||||
return (<div className={Style.container}>
|
||||
{items && items.map((ele, index) => (<>
|
||||
<div className={Style.btn} onClick={ele.onClick}>
|
||||
<Typography.Link>
|
||||
{ele.label}
|
||||
</Typography.Link>
|
||||
</div>
|
||||
{index !== items.length - 1 && (<Divider type="vertical"></Divider>)}
|
||||
</>))}
|
||||
{moreItems && moreItems.length > 0 && (<Divider type="vertical"/>)}
|
||||
{moreItems && moreItems.length > 0 && (<Popover placement='topRight' content={<Space direction="vertical">
|
||||
{moreItems.map((ele) => (<Button size="small" type="link" onClick={ele.onClick}>
|
||||
{ele.label}
|
||||
</Button>))}
|
||||
</Space>} trigger="click">
|
||||
<Button type="link" icon={(<MoreOutlined />)}/>
|
||||
</Popover>)}
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { ActionDef, WebComponentProps } from '../../types/Page';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { ED, OakExtraActionProps } from '../../types/AbstractComponent';
|
||||
|
|
@ -23,5 +24,5 @@ export default function Render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
onAction: (action?: string, cascadeAction?: CascadeActionProps) => void;
|
||||
}, {
|
||||
makeItems: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useEffect } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Space, Button, Modal, } from 'antd';
|
||||
import Style from './web.module.less';
|
||||
const { confirm } = Modal;
|
||||
function ItemComponent(props) {
|
||||
const { label, type, onClick } = props;
|
||||
if (type === 'button') {
|
||||
return (_jsx(Button, { onClick: () => onClick(), children: label }));
|
||||
return (<Button onClick={() => onClick()}>
|
||||
{label}
|
||||
</Button>);
|
||||
}
|
||||
return _jsx("a", { onClick: (e) => {
|
||||
return <a onClick={(e) => {
|
||||
onClick();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}, children: label });
|
||||
}}>
|
||||
{label}
|
||||
</a>;
|
||||
}
|
||||
export default function Render(props) {
|
||||
const { methods, data } = props;
|
||||
|
|
@ -22,7 +25,13 @@ export default function Render(props) {
|
|||
useEffect(() => {
|
||||
makeItems();
|
||||
}, [zhCNKeys, actions, cascadeActions, extraActions]);
|
||||
return (_jsx("div", { className: Style.panelContainer, children: _jsx(Space, { align: 'center', size: 12, style: { width: '100%' }, wrap: true, children: _jsx(_Fragment, { children: items?.map((ele, index) => {
|
||||
return (_jsx(ItemComponent, { label: ele.label, type: "a", onClick: ele.onClick }));
|
||||
}) }) }) }));
|
||||
return (<div className={Style.panelContainer}>
|
||||
<Space align='center' size={12} style={{ width: '100%' }} wrap>
|
||||
<>
|
||||
{items?.map((ele, index) => {
|
||||
return (<ItemComponent label={ele.label} type="a" onClick={ele.onClick}/>);
|
||||
})}
|
||||
</>
|
||||
</Space>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { SpaceProps } from 'antd';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -17,4 +18,4 @@ export default function Render(props: WebComponentProps<EntityDict, keyof Entity
|
|||
okText: string;
|
||||
cancelText: string;
|
||||
};
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Button, Modal, Dropdown, Typography, } from 'antd';
|
||||
import Style from './web.module.less';
|
||||
const { confirm } = Modal;
|
||||
function ItemComponent(props) {
|
||||
const { type, buttonProps, render, onClick, text } = props;
|
||||
if (type === 'button') {
|
||||
return (_jsx(Button, { ...buttonProps, onClick: onClick, children: text }));
|
||||
return (<Button {...buttonProps} onClick={onClick}>
|
||||
{text}
|
||||
</Button>);
|
||||
}
|
||||
if (render) {
|
||||
return _jsx("div", { onClick: onClick, children: render });
|
||||
return <div onClick={onClick}>{render}</div>;
|
||||
}
|
||||
return _jsx("a", { onClick: onClick, children: text });
|
||||
return <a onClick={onClick}>{text}</a>;
|
||||
}
|
||||
export default function Render(props) {
|
||||
const { methods, data } = props;
|
||||
|
|
@ -76,20 +78,12 @@ export default function Render(props) {
|
|||
return null;
|
||||
}
|
||||
if (mode === 'table-cell') {
|
||||
return (_jsxs(Space, { ...spaceProps, children: [newItems?.map((ele, index) => {
|
||||
return (_jsx(ItemComponent, { ...ele, onClick: ele.onClick2, text: ele.text }));
|
||||
}), moreItems && moreItems.length > 0 && (_jsx(Dropdown, { menu: {
|
||||
items: moreItems.map((ele, index) => ({
|
||||
label: ele.text,
|
||||
key: index,
|
||||
})),
|
||||
onClick: (e) => {
|
||||
const item = moreItems[e.key];
|
||||
item.onClick2();
|
||||
},
|
||||
}, placement: "top", arrow: true, children: _jsx("a", { onClick: (e) => e.preventDefault(), children: "\u66F4\u591A" }) }))] }));
|
||||
}
|
||||
return (_jsxs("div", { className: Style.panelContainer, children: [moreItems && moreItems.length > 0 && (_jsx(Dropdown, { menu: {
|
||||
return (<Space {...spaceProps}>
|
||||
{newItems?.map((ele, index) => {
|
||||
return (<ItemComponent {...ele} onClick={ele.onClick2} text={ele.text}/>);
|
||||
})}
|
||||
|
||||
{moreItems && moreItems.length > 0 && (<Dropdown menu={{
|
||||
items: moreItems.map((ele, index) => ({
|
||||
label: ele.text,
|
||||
key: index,
|
||||
|
|
@ -98,7 +92,28 @@ export default function Render(props) {
|
|||
const item = moreItems[e.key];
|
||||
item.onClick2();
|
||||
},
|
||||
}, arrow: true, children: _jsx(Typography, { className: Style.more, children: "\u66F4\u591A" }) })), _jsx(Space, { ...spaceProps, children: newItems?.map((ele, index) => {
|
||||
return (_jsx(ItemComponent, { type: "button", ...ele, onClick: ele.onClick2, text: ele.text }));
|
||||
}) })] }));
|
||||
}} placement="top" arrow>
|
||||
<a onClick={(e) => e.preventDefault()}>更多</a>
|
||||
</Dropdown>)}
|
||||
</Space>);
|
||||
}
|
||||
return (<div className={Style.panelContainer}>
|
||||
{moreItems && moreItems.length > 0 && (<Dropdown menu={{
|
||||
items: moreItems.map((ele, index) => ({
|
||||
label: ele.text,
|
||||
key: index,
|
||||
})),
|
||||
onClick: (e) => {
|
||||
const item = moreItems[e.key];
|
||||
item.onClick2();
|
||||
},
|
||||
}} arrow>
|
||||
<Typography className={Style.more}>更多</Typography>
|
||||
</Dropdown>)}
|
||||
<Space {...spaceProps}>
|
||||
{newItems?.map((ele, index) => {
|
||||
return (<ItemComponent type="button" {...ele} onClick={ele.onClick2} text={ele.text}/>);
|
||||
})}
|
||||
</Space>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { IMode, Item } from './type';
|
||||
|
|
@ -17,4 +18,4 @@ export default function Render(props: WebComponentProps<EntityDict, keyof Entity
|
|||
okText: string;
|
||||
cancelText: string;
|
||||
};
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Modal, Typography, } from 'antd';
|
||||
import OakIcon from '../icon';
|
||||
import classNames from 'classnames';
|
||||
|
|
@ -8,7 +7,7 @@ const { confirm } = Modal;
|
|||
function ItemComponent(props) {
|
||||
const { icon, buttonProps, render, onClick, iconRender, iconProps, mode, text, } = props;
|
||||
if (render) {
|
||||
return _jsx("div", { onClick: onClick, children: render });
|
||||
return <div onClick={onClick}>{render}</div>;
|
||||
}
|
||||
const { style = {}, rootStyle = {}, bgColor } = iconProps || {};
|
||||
let icon2;
|
||||
|
|
@ -16,16 +15,23 @@ function ItemComponent(props) {
|
|||
icon2 = iconRender;
|
||||
}
|
||||
else if (typeof icon === 'string') {
|
||||
icon2 = (_jsx(OakIcon, { name: icon, className: classNames(Style.icon, {
|
||||
icon2 = (<OakIcon name={icon} className={classNames(Style.icon, {
|
||||
[Style.iconWhite]: !!bgColor,
|
||||
}), style: style }));
|
||||
})} style={style}/>);
|
||||
}
|
||||
else {
|
||||
icon2 = icon;
|
||||
}
|
||||
return (_jsx(Button, { className: Style.btn, type: "text", ...buttonProps, onClick: onClick, children: _jsxs("div", { className: Style.space, children: [mode === 'card' && !!icon2 ? (_jsx("div", { className: Style.iconBox, style: Object.assign({}, bgColor && {
|
||||
backgroundColor: bgColor,
|
||||
}, rootStyle), children: icon2 })) : (icon2), _jsx(Typography, { children: text })] }) }));
|
||||
return (<Button className={Style.btn} type="text" {...buttonProps} onClick={onClick}>
|
||||
<div className={Style.space}>
|
||||
{mode === 'card' && !!icon2 ? (<div className={Style.iconBox} style={Object.assign({}, bgColor && {
|
||||
backgroundColor: bgColor,
|
||||
}, rootStyle)}>
|
||||
{icon2}
|
||||
</div>) : (icon2)}
|
||||
<Typography>{text}</Typography>
|
||||
</div>
|
||||
</Button>);
|
||||
}
|
||||
export default function Render(props) {
|
||||
const { methods, data } = props;
|
||||
|
|
@ -74,61 +80,76 @@ export default function Render(props) {
|
|||
if (!newItems || newItems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return (_jsxs("div", { className: Style.tabContainer, children: [_jsx("div", { className: Style.scrollBox, children: _jsx("div", { id: id, className: Style.scrollView, onScroll: (e) => {
|
||||
const scrollLeft = e.target.scrollLeft;
|
||||
setSlideLeft(scrollLeft * slideRatio);
|
||||
}, children: _jsx("div", { className: Style.tabView, children: tabNums.map((tabNum, index) => {
|
||||
return (_jsx("div", { className: Style.btnContainer, children: newItems
|
||||
.filter((btn, index2) => (tabNum - 1) * count <
|
||||
index2 + 1 &&
|
||||
index2 + 1 <= tabNum * count)
|
||||
.map((ele, index2) => {
|
||||
const { label, action } = ele;
|
||||
let text;
|
||||
if (label) {
|
||||
text = label;
|
||||
return (<div className={Style.tabContainer}>
|
||||
<div className={Style.scrollBox}>
|
||||
<div id={id} className={Style.scrollView} onScroll={(e) => {
|
||||
const scrollLeft = e.target.scrollLeft;
|
||||
setSlideLeft(scrollLeft * slideRatio);
|
||||
}}>
|
||||
<div className={Style.tabView}>
|
||||
{tabNums.map((tabNum, index) => {
|
||||
return (<div className={Style.btnContainer}>
|
||||
{newItems
|
||||
.filter((btn, index2) => (tabNum - 1) * count <
|
||||
index2 + 1 &&
|
||||
index2 + 1 <= tabNum * count)
|
||||
.map((ele, index2) => {
|
||||
const { label, action } = ele;
|
||||
let text;
|
||||
if (label) {
|
||||
text = label;
|
||||
}
|
||||
else {
|
||||
text = getActionName(action);
|
||||
}
|
||||
let onClick = async () => {
|
||||
if (ele.onClick) {
|
||||
ele.onClick(ele);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if (ele.alerted) {
|
||||
onClick = async () => {
|
||||
const { title, content, okText, cancelText, } = getAlertOptions(ele);
|
||||
confirm({
|
||||
title,
|
||||
content,
|
||||
okText,
|
||||
cancelText,
|
||||
onOk: async () => {
|
||||
if (ele.onClick) {
|
||||
ele.onClick(ele);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
text = getActionName(action);
|
||||
}
|
||||
let onClick = async () => {
|
||||
if (ele.onClick) {
|
||||
ele.onClick(ele);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if (ele.alerted) {
|
||||
onClick = async () => {
|
||||
const { title, content, okText, cancelText, } = getAlertOptions(ele);
|
||||
confirm({
|
||||
title,
|
||||
content,
|
||||
okText,
|
||||
cancelText,
|
||||
onOk: async () => {
|
||||
if (ele.onClick) {
|
||||
ele.onClick(ele);
|
||||
return;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
return (_jsx("div", { className: classNames(Style.btnBox, {
|
||||
[Style.btnBox_top]: newItems.length >
|
||||
column &&
|
||||
index2 >
|
||||
column - 1,
|
||||
}), style: {
|
||||
height: `calc(100% / ${newItems.length >
|
||||
column
|
||||
? rows
|
||||
: 1})`,
|
||||
width: `calc(100% / ${column})`,
|
||||
}, children: _jsx(ItemComponent, { ...ele, onClick: onClick, mode: mode, text: text }) }, index2));
|
||||
}) }));
|
||||
}) }) }) }), slideShow && (_jsx("div", { className: Style.slideBar, children: _jsx("div", { className: Style.slideShow, style: {
|
||||
width: slideWidth,
|
||||
marginLeft: slideLeft <= 1 ? 0 : slideLeft,
|
||||
} }) }))] }));
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
return (<div key={index2} className={classNames(Style.btnBox, {
|
||||
[Style.btnBox_top]: newItems.length >
|
||||
column &&
|
||||
index2 >
|
||||
column - 1,
|
||||
})} style={{
|
||||
height: `calc(100% / ${newItems.length >
|
||||
column
|
||||
? rows
|
||||
: 1})`,
|
||||
width: `calc(100% / ${column})`,
|
||||
}}>
|
||||
<ItemComponent {...ele} onClick={onClick} mode={mode} text={text}/>
|
||||
</div>);
|
||||
})}
|
||||
</div>);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{slideShow && (<div className={Style.slideBar}>
|
||||
<div className={Style.slideShow} style={{
|
||||
width: slideWidth,
|
||||
marginLeft: slideLeft <= 1 ? 0 : slideLeft,
|
||||
}}/>
|
||||
</div>)}
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -25,5 +26,5 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
column: ColumnMapType;
|
||||
renderData: AttrRender[];
|
||||
judgeAttributes: OakAbsAttrJudgeDef[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Image } from 'antd-mobile';
|
||||
import styles from './mobile.module.less';
|
||||
// type Width = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
||||
|
|
@ -7,25 +7,53 @@ function RenderRow(props) {
|
|||
const { type, label, value } = props;
|
||||
if (type === 'image') {
|
||||
if (value instanceof Array) {
|
||||
return (_jsxs("div", { className: styles.renderRow, children: [_jsx("div", { className: styles.renderLabel, children: label }), _jsx(Space, { wrap: true, children: value.map((ele) => (_jsx(Image, { width: 70, height: 70, src: ele, fit: "contain" }))) })] }));
|
||||
return (<div className={styles.renderRow}>
|
||||
<div className={styles.renderLabel}>
|
||||
{label}
|
||||
</div>
|
||||
<Space wrap>
|
||||
{value.map((ele) => (<Image width={70} height={70} src={ele} fit="contain"/>))}
|
||||
</Space>
|
||||
</div>);
|
||||
}
|
||||
else {
|
||||
return (_jsxs("div", { className: styles.renderRow, children: [_jsx("div", { className: styles.renderLabel, children: label }), _jsx(Space, { wrap: true, children: _jsx(Image, { width: 70, height: 70, src: value, fit: "contain" }) })] }));
|
||||
return (<div className={styles.renderRow}>
|
||||
<div className={styles.renderLabel}>
|
||||
{label}
|
||||
</div>
|
||||
<Space wrap>
|
||||
<Image width={70} height={70} src={value} fit="contain"/>
|
||||
</Space>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
return (_jsxs("div", { className: styles.renderRow, children: [_jsx("div", { className: styles.renderLabel, children: label }), _jsx("div", { className: styles.renderValue, children: value ? String(value) : '--' })] }));
|
||||
return (<div className={styles.renderRow}>
|
||||
<div className={styles.renderLabel}>
|
||||
{label}
|
||||
</div>
|
||||
<div className={styles.renderValue}>{value ? String(value) : '--'}</div>
|
||||
</div>);
|
||||
}
|
||||
export default function Render(props) {
|
||||
const { methods, data: oakData } = props;
|
||||
const { t } = methods;
|
||||
const { title, renderData, entity, judgeAttributes, data, } = oakData;
|
||||
return (_jsxs("div", { className: styles.panel, children: [title && (_jsx("div", { className: styles.title, children: title })), _jsx("div", { className: styles.panel_content, children: _jsx(Space, { direction: "vertical", style: { '--gap': '10px' }, children: judgeAttributes && judgeAttributes.map((ele) => {
|
||||
let renderValue = getValue(data, ele.path, ele.entity, ele.attr, ele.attrType, t);
|
||||
let renderLabel = getLabel(ele.attribute, ele.entity, ele.attr, t);
|
||||
const renderType = getType(ele.attribute, ele.attrType);
|
||||
if ([null, '', undefined].includes(renderValue)) {
|
||||
renderValue = t('not_filled_in');
|
||||
}
|
||||
return (_jsx(RenderRow, { label: renderLabel, value: renderValue, type: renderType }));
|
||||
}) }) })] }));
|
||||
return (<div className={styles.panel}>
|
||||
{title && (<div className={styles.title}>
|
||||
{title}
|
||||
</div>)}
|
||||
<div className={styles.panel_content}>
|
||||
<Space direction="vertical" style={{ '--gap': '10px' }}>
|
||||
{judgeAttributes && judgeAttributes.map((ele) => {
|
||||
let renderValue = getValue(data, ele.path, ele.entity, ele.attr, ele.attrType, t);
|
||||
let renderLabel = getLabel(ele.attribute, ele.entity, ele.attr, t);
|
||||
const renderType = getType(ele.attribute, ele.attrType);
|
||||
if ([null, '', undefined].includes(renderValue)) {
|
||||
renderValue = t('not_filled_in');
|
||||
}
|
||||
return (<RenderRow label={renderLabel} value={renderValue} type={renderType}/>);
|
||||
})}
|
||||
</Space>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { Breakpoint } from 'antd';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
|
|
@ -17,4 +18,4 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
column: number | Record<Breakpoint, number>;
|
||||
renderData: AttrRender[];
|
||||
judgeAttributes: OakAbsAttrJudgeDef[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Tag, Descriptions, Image, Space } from 'antd';
|
||||
import { getLabel, getType, getValue } from '../../utils/usefulFn';
|
||||
import { get } from 'oak-domain/lib/utils/lodash';
|
||||
|
|
@ -6,14 +6,20 @@ function RenderRow(props) {
|
|||
const { type, value, color } = props;
|
||||
if (type === 'image') {
|
||||
if (value instanceof Array) {
|
||||
return (_jsx(Space, { wrap: true, children: value.map((ele) => (_jsx(Image, { width: 100, height: 100, src: ele, style: { objectFit: 'contain' } }))) }));
|
||||
return (<Space wrap>
|
||||
{value.map((ele) => (<Image width={100} height={100} src={ele} style={{ objectFit: 'contain' }}/>))}
|
||||
</Space>);
|
||||
}
|
||||
else {
|
||||
return (_jsx(Space, { wrap: true, children: _jsx(Image, { width: 100, height: 100, src: value, style: { objectFit: 'contain' } }) }));
|
||||
return (<Space wrap>
|
||||
<Image width={100} height={100} src={value} style={{ objectFit: 'contain' }}/>
|
||||
</Space>);
|
||||
}
|
||||
}
|
||||
if (type === 'enum') {
|
||||
_jsx(Tag, { color: color, children: value });
|
||||
<Tag color={color}>
|
||||
{value}
|
||||
</Tag>;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
@ -21,7 +27,8 @@ export default function Render(props) {
|
|||
const { methods, data: oakData } = props;
|
||||
const { t } = methods;
|
||||
const { entity, title, colorDict, bordered, column, renderData, layout = "horizontal", judgeAttributes, data, } = oakData;
|
||||
return (_jsx(Descriptions, { title: title, column: column, bordered: bordered, layout: layout, children: judgeAttributes?.map((ele) => {
|
||||
return (<Descriptions title={title} column={column} bordered={bordered} layout={layout}>
|
||||
{judgeAttributes?.map((ele) => {
|
||||
let renderValue = getValue(data, ele.path, ele.entity, ele.attr, ele.attrType, t);
|
||||
let renderLabel = getLabel(ele.attribute, ele.entity, ele.attr, t);
|
||||
const renderType = getType(ele.attribute, ele.attrType);
|
||||
|
|
@ -30,6 +37,9 @@ export default function Render(props) {
|
|||
}
|
||||
const stateValue = get(data, ele.path);
|
||||
const color = colorDict && colorDict[ele.entity]?.[ele.attr]?.[stateValue] || 'default';
|
||||
return (_jsx(Descriptions.Item, { label: renderLabel, span: ele.attribute.span || 1, children: _jsx(RenderRow, { type: renderType, value: renderValue, color: color }) }));
|
||||
}) }));
|
||||
return (<Descriptions.Item label={renderLabel} span={ele.attribute.span || 1}>
|
||||
<RenderRow type={renderType} value={renderValue} color={color}/>
|
||||
</Descriptions.Item>);
|
||||
})}
|
||||
</Descriptions>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -14,5 +15,5 @@ export default function render(props: WebComponentProps<ED, keyof ED, true, {
|
|||
}>;
|
||||
}, {
|
||||
onEntityClicked: (entity: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import Styles from './web.module.less';
|
||||
export default function render(props) {
|
||||
const { t } = props.methods;
|
||||
return (_jsx("div", { className: Styles.container, children: t('useWideScreen') }));
|
||||
return (<div className={Styles.container}>
|
||||
{t('useWideScreen')}
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -14,5 +15,5 @@ export default function render(props: WebComponentProps<ED, keyof ED, true, {
|
|||
}>;
|
||||
}, {
|
||||
onEntityClicked: (entity: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Switch, Input, Form } from 'antd';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import { useState } from 'react';
|
||||
|
|
@ -37,54 +36,68 @@ export default function render(props) {
|
|||
});
|
||||
}
|
||||
}
|
||||
return (_jsxs("div", { className: Styles.container, children: [_jsxs(Form, { style: {
|
||||
margin: 20,
|
||||
}, children: [_jsx(Form.Item, { label: "filter", children: _jsx(_Fragment, { children: _jsx(Input, { onChange: ({ currentTarget }) => setSearch(currentTarget.value), allowClear: true }) }) }), _jsx(Form.Item, { label: "strict mode", children: _jsx(_Fragment, { children: _jsx(Switch, { checked: strict, onChange: (checked) => setStrict(checked) }) }) })] }), _jsx(ReactEcharts, { style: { width: '100%', height: '100%', minHeight: 750 }, option: {
|
||||
tooltip: {},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
force: {
|
||||
initLayout: 'circular',
|
||||
gravity: 0,
|
||||
repulsion: [10, 80],
|
||||
edgeLength: [10, 50]
|
||||
},
|
||||
data: data2,
|
||||
links: links2,
|
||||
lineStyle: {
|
||||
opacity: 0.9,
|
||||
width: 2,
|
||||
curveness: 0
|
||||
},
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
autoCurveness: true,
|
||||
roam: true,
|
||||
draggable: true,
|
||||
edgeSymbol: ['none', 'arrow'],
|
||||
edgeSymbolSize: 7,
|
||||
emphasis: {
|
||||
scale: true,
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
width: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
}, notMerge: true, lazyUpdate: false, onEvents: {
|
||||
click: (info) => {
|
||||
const { data, dataType } = info;
|
||||
if (dataType === 'node') {
|
||||
const { name } = data;
|
||||
onEntityClicked(name);
|
||||
}
|
||||
return (<div className={Styles.container}>
|
||||
<Form style={{
|
||||
margin: 20,
|
||||
}}>
|
||||
<Form.Item label="filter">
|
||||
<>
|
||||
<Input onChange={({ currentTarget }) => setSearch(currentTarget.value)} allowClear/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="strict mode">
|
||||
<>
|
||||
<Switch checked={strict} onChange={(checked) => setStrict(checked)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<ReactEcharts style={{ width: '100%', height: '100%', minHeight: 750 }} option={{
|
||||
tooltip: {},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
force: {
|
||||
initLayout: 'circular',
|
||||
gravity: 0,
|
||||
repulsion: [10, 80],
|
||||
edgeLength: [10, 50]
|
||||
},
|
||||
} })] }));
|
||||
data: data2,
|
||||
links: links2,
|
||||
lineStyle: {
|
||||
opacity: 0.9,
|
||||
width: 2,
|
||||
curveness: 0
|
||||
},
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
autoCurveness: true,
|
||||
roam: true,
|
||||
draggable: true,
|
||||
edgeSymbol: ['none', 'arrow'],
|
||||
edgeSymbolSize: 7,
|
||||
emphasis: {
|
||||
scale: true,
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
width: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
}} notMerge={true} lazyUpdate={false} onEvents={{
|
||||
click: (info) => {
|
||||
const { data, dataType } = info;
|
||||
if (dataType === 'node') {
|
||||
const { name } = data;
|
||||
onEntityClicked(name);
|
||||
}
|
||||
},
|
||||
}}/>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
import { ColumnProps, ValueType, ViewType } from '../../types/Filter';
|
||||
|
|
@ -16,4 +17,4 @@ export default function Render<ED2 extends ED>(props: WebComponentProps<ED2, key
|
|||
}, {
|
||||
getNamedFilter: (name: string) => Record<string, any>;
|
||||
setFilterAndResetFilter: (viewType: ViewType, value?: ValueType) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Input, Form, Select, DatePicker, } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import weekday from 'dayjs/plugin/weekday';
|
||||
|
|
@ -34,14 +34,16 @@ export default function Render(props) {
|
|||
}
|
||||
let V;
|
||||
if (column.render) {
|
||||
return (_jsx(Form.Item, { label: label, name: name, children: _jsx(_Fragment, { children: column.render }) }));
|
||||
return (<Form.Item label={label} name={name}>
|
||||
<>{column.render}</>
|
||||
</Form.Item>);
|
||||
}
|
||||
switch (viewType) {
|
||||
case 'Input': {
|
||||
V = (_jsx(Input, { placeholder: placeholder || t('placeholder.input'), onChange: (e) => {
|
||||
V = (<Input placeholder={placeholder || t('placeholder.input')} onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
setFilterAndResetFilter(viewType, val);
|
||||
}, allowClear: true, onPressEnter: () => { } }));
|
||||
}} allowClear onPressEnter={() => { }}/>);
|
||||
break;
|
||||
}
|
||||
case 'Select': {
|
||||
|
|
@ -52,13 +54,13 @@ export default function Render(props) {
|
|||
value: ele.value,
|
||||
}));
|
||||
const multiple = ['$in', '$nin'].includes(op || '');
|
||||
V = (_jsx(Select, { mode: multiple ? 'multiple' : undefined, allowClear: true, placeholder: placeholder || t('placeholder.select'), onChange: (value) => {
|
||||
V = (<Select mode={multiple ? 'multiple' : undefined} allowClear placeholder={placeholder || t('placeholder.select')} onChange={(value) => {
|
||||
let value2 = multiple ? value : [value];
|
||||
if (value === undefined || value === null) {
|
||||
value2 = [];
|
||||
}
|
||||
setFilterAndResetFilter(viewType, value2);
|
||||
}, options: options2 }));
|
||||
}} options={options2}/>);
|
||||
break;
|
||||
}
|
||||
case 'DatePicker': {
|
||||
|
|
@ -66,21 +68,19 @@ export default function Render(props) {
|
|||
const { showTime = false } = dateProps || {};
|
||||
//assert(op, '选择时间,算子必须传入');
|
||||
const unitOfTime = 'day';
|
||||
V = (_jsx(DatePicker, { placeholder: placeholder || t('placeholder.select'), style: { width: '100%' }, format: "YYYY-MM-DD", showTime: showTime, onChange: (date, dateString) => {
|
||||
V = (<DatePicker placeholder={placeholder || t('placeholder.select')} style={{ width: '100%' }} format="YYYY-MM-DD" showTime={showTime} onChange={(date, dateString) => {
|
||||
setFilterAndResetFilter(viewType, date);
|
||||
} }));
|
||||
}}/>);
|
||||
break;
|
||||
}
|
||||
case 'DatePicker.RangePicker': {
|
||||
const { dateProps } = column;
|
||||
const { showTime = false } = dateProps || {};
|
||||
V = (_jsx(DatePicker.RangePicker
|
||||
V = (<DatePicker.RangePicker
|
||||
// placeholder={placeholder || t('placeholder.select')}
|
||||
, {
|
||||
// placeholder={placeholder || t('placeholder.select')}
|
||||
style: { width: '100%' }, showTime: showTime, onChange: (dates, dateStrings) => {
|
||||
style={{ width: '100%' }} showTime={showTime} onChange={(dates, dateStrings) => {
|
||||
setFilterAndResetFilter(viewType, dates);
|
||||
} }));
|
||||
}}/>);
|
||||
break;
|
||||
}
|
||||
case 'RefAttr': {
|
||||
|
|
@ -88,13 +88,15 @@ export default function Render(props) {
|
|||
const filter = getNamedFilter(name);
|
||||
const value = get(filter, getOp(column), '');
|
||||
const multiple = ['$in', '$nin'].includes(op || '');
|
||||
V = (_jsx(RefAttr, { placeholder: placeholder || t('placeholder.select'), multiple: multiple, entityIds: value ? (multiple ? value : [value]) : [], pickerRender: Object.assign({}, column.refProps), onChange: (ids) => {
|
||||
V = (<RefAttr placeholder={placeholder || t('placeholder.select')} multiple={multiple} entityIds={value ? (multiple ? value : [value]) : []} pickerRender={Object.assign({}, column.refProps)} onChange={(ids) => {
|
||||
setFilterAndResetFilter(viewType, ids);
|
||||
} }));
|
||||
}}/>);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (_jsx(Form.Item, { label: label, name: name, children: _jsx(_Fragment, { children: V }) }));
|
||||
return (<Form.Item label={label} name={name}>
|
||||
<>{V}</>
|
||||
</Form.Item>);
|
||||
}
|
||||
function assertMessage(attr, attrType, op, ops) {
|
||||
return `attr为【${attr}】, 传入的算子【${op}】不支持,类型【${attrType}】只支持【${JSON.stringify(ops)}】`;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
import { ColSpanType, ColumnProps } from '../../types/Filter';
|
||||
|
|
@ -18,5 +19,5 @@ export default function Render<ED2 extends ED>(props: WebComponentProps<ED, keyo
|
|||
width: Width;
|
||||
}, {
|
||||
getNamedFilters: () => Record<string, any>[];
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): React.JSX.Element | null;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Button, Space, Form, Badge, Row, Col } from 'antd';
|
||||
import { DownOutlined, UpOutlined } from '@ant-design/icons';
|
||||
import Filter from '../filter2';
|
||||
|
|
@ -63,7 +62,9 @@ export default function Render(props) {
|
|||
tfColumns.forEach((column, index) => {
|
||||
const { colSpan } = column;
|
||||
const colSpan2 = getSpan(colSpan || 1, mergedColumn);
|
||||
const item = (_jsx(Col, { span: gridColumn * colSpan2, children: _jsx(Filter, { column: column, entity: entity, oakPath: oakFullpath }) }));
|
||||
const item = (<Col span={gridColumn * colSpan2}>
|
||||
<Filter column={column} entity={entity} oakPath={oakFullpath}/>
|
||||
</Col>);
|
||||
if (index === 0) {
|
||||
firstItem = item;
|
||||
}
|
||||
|
|
@ -136,18 +137,40 @@ export default function Render(props) {
|
|||
const buttonItemLayout = formLayout === 'horizontal'
|
||||
? { wrapperCol: { span: 18, offset: 6 } }
|
||||
: null;
|
||||
items.push(_jsx(Col, { span: _gridColumn, children: _jsx(Form.Item, { ...buttonItemLayout, children: _jsxs(Space, { className: Style.actionBox, children: [_jsx(Badge, { count: count, children: _jsx(Button, { type: "default", onClick: () => {
|
||||
filterNames.forEach((ele) => removeNamedFilterByName(ele));
|
||||
form.resetFields();
|
||||
refresh();
|
||||
}, children: t('common::reset') }) }), _jsx(Button, { type: "primary", onClick: () => {
|
||||
if (typeof onSearch === 'function') {
|
||||
onSearch();
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
}, children: t('common::select') }), showExpandButton && (_jsx(Button, { type: "link", onClick: () => {
|
||||
setOpen(!open);
|
||||
}, children: _jsxs(Space, { children: [open ? t('common::shrink') : t('common::expand'), open ? _jsx(UpOutlined, {}) : _jsx(DownOutlined, {})] }) }))] }) }) }));
|
||||
return (_jsx(Form, { form: form, ...formItemLayout, layout: formLayout, children: _jsx(Row, { gutter: [16, 16], children: items }) }));
|
||||
items.push(<Col span={_gridColumn}>
|
||||
<Form.Item {...buttonItemLayout}>
|
||||
<Space className={Style.actionBox}>
|
||||
<Badge count={count}>
|
||||
<Button type="default" onClick={() => {
|
||||
filterNames.forEach((ele) => removeNamedFilterByName(ele));
|
||||
form.resetFields();
|
||||
refresh();
|
||||
}}>
|
||||
{t('common::reset')}
|
||||
</Button>
|
||||
</Badge>
|
||||
<Button type="primary" onClick={() => {
|
||||
if (typeof onSearch === 'function') {
|
||||
onSearch();
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
}}>
|
||||
{t('common::select')}
|
||||
</Button>
|
||||
{showExpandButton && (<Button type="link" onClick={() => {
|
||||
setOpen(!open);
|
||||
}}>
|
||||
<Space>
|
||||
{open ? t('common::shrink') : t('common::expand')}
|
||||
|
||||
{open ? <UpOutlined /> : <DownOutlined />}
|
||||
</Space>
|
||||
</Button>)}
|
||||
</Space>
|
||||
</Form.Item>
|
||||
</Col>);
|
||||
return (<Form form={form} {...formItemLayout} layout={formLayout}>
|
||||
<Row gutter={[16, 16]}>{items}</Row>
|
||||
</Form>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ export default function Render(props: WebComponentProps<EntityDict, keyof Entity
|
|||
size?: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import './web.less';
|
||||
export default function Render(props) {
|
||||
const { data } = props;
|
||||
|
|
@ -11,5 +11,5 @@ export default function Render(props) {
|
|||
if (className) {
|
||||
class_name += ' ' + className;
|
||||
}
|
||||
return (_jsx("span", { className: class_name, style: Object.assign(style, size && { fontSize: size }, color && !isColor && { color }) }));
|
||||
return (<span className={class_name} style={Object.assign(style, size && { fontSize: size }, color && !isColor && { color })}></span>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
type Props = {
|
||||
mode?: 'select';
|
||||
selected?: boolean;
|
||||
|
|
@ -9,5 +10,5 @@ type Props = {
|
|||
onClick?: () => void;
|
||||
type?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' | 'initial' | 'inherit';
|
||||
};
|
||||
declare function ImgBox(props: Props): import("react/jsx-runtime").JSX.Element;
|
||||
declare function ImgBox(props: Props): React.JSX.Element;
|
||||
export default ImgBox;
|
||||
|
|
|
|||
|
|
@ -1,46 +1,60 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import styles from './index.module.less';
|
||||
import { Space, Checkbox, Divider, Modal, Image } from 'antd';
|
||||
import { EyeOutlined, } from '@ant-design/icons';
|
||||
const { confirm } = Modal;
|
||||
function MaskView(props) {
|
||||
const { selected, onClick, setVisibleTrue } = props;
|
||||
return (_jsx("div", { className: selected ? styles['mask-checked'] : styles.mask, onClick: onClick, children: _jsxs("div", { className: styles.row2, children: [_jsx(Checkbox, { checked: selected }), _jsx(Space, { size: 0, split: _jsx(Divider, { type: "vertical" }), children: _jsx(EyeOutlined, { style: {
|
||||
color: 'white',
|
||||
fontSize: '1.4em',
|
||||
}, onClick: (e) => {
|
||||
setVisibleTrue();
|
||||
e.stopPropagation();
|
||||
} }) })] }) }));
|
||||
return (<div className={selected ? styles['mask-checked'] : styles.mask} onClick={onClick}>
|
||||
<div className={styles.row2}>
|
||||
<Checkbox checked={selected}/>
|
||||
<Space size={0} split={<Divider type="vertical"/>}>
|
||||
<EyeOutlined style={{
|
||||
color: 'white',
|
||||
fontSize: '1.4em',
|
||||
}} onClick={(e) => {
|
||||
setVisibleTrue();
|
||||
e.stopPropagation();
|
||||
}}/>
|
||||
</Space>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
function ImgBox(props) {
|
||||
const { width, height, bordered = false, type = 'contain', src, alt, mode, selected, onClick } = props;
|
||||
const [visible, setVisible] = useState(false);
|
||||
if (bordered) {
|
||||
return (_jsxs("div", { className: styles.imgBoxBorder, children: [mode === 'select' && (_jsx(MaskView, { selected: selected, onClick: () => onClick && onClick(), setVisibleTrue: () => {
|
||||
setVisible(true);
|
||||
} })), _jsx("img", { width: width || 72, height: height || 72, src: src, style: {
|
||||
objectFit: type,
|
||||
borderRadius: 8,
|
||||
}, alt: 'img' || alt }), _jsx(Image, { style: { display: 'none' }, src: src, preview: {
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: (value) => {
|
||||
setVisible(value);
|
||||
},
|
||||
} })] }));
|
||||
}
|
||||
return (_jsxs("div", { className: styles.imgBox, children: [mode === 'select' && (_jsx(MaskView, { selected: selected, onClick: () => onClick && onClick(), setVisibleTrue: () => {
|
||||
return (<div className={styles.imgBoxBorder}>
|
||||
{mode === 'select' && (<MaskView selected={selected} onClick={() => onClick && onClick()} setVisibleTrue={() => {
|
||||
setVisible(true);
|
||||
} })), _jsx("img", { width: width || 72, height: height || 72, src: src, style: {
|
||||
objectFit: type,
|
||||
}, alt: 'img' || alt }), _jsx(Image, { style: { display: 'none' }, src: src, preview: {
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: (value) => {
|
||||
setVisible(value);
|
||||
},
|
||||
} })] }));
|
||||
}}/>)}
|
||||
<img width={width || 72} height={height || 72} src={src} style={{
|
||||
objectFit: type,
|
||||
borderRadius: 8,
|
||||
}} alt={'img' || alt}/>
|
||||
<Image style={{ display: 'none' }} src={src} preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: (value) => {
|
||||
setVisible(value);
|
||||
},
|
||||
}}/>
|
||||
</div>);
|
||||
}
|
||||
return (<div className={styles.imgBox}>
|
||||
{mode === 'select' && (<MaskView selected={selected} onClick={() => onClick && onClick()} setVisibleTrue={() => {
|
||||
setVisible(true);
|
||||
}}/>)}
|
||||
<img width={width || 72} height={height || 72} src={src} style={{
|
||||
objectFit: type,
|
||||
}} alt={'img' || alt}/>
|
||||
<Image style={{ display: 'none' }} src={src} preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: (value) => {
|
||||
setVisible(value);
|
||||
},
|
||||
}}/>
|
||||
</div>);
|
||||
}
|
||||
export default ImgBox;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { ListButtonProps } from '../../../types/AbstractComponent';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
export default function Render(props: WebComponentProps<EntityDict & BaseEntityDict, keyof EntityDict, false, {
|
||||
items: ListButtonProps[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
// TODO 应该是要antd-mobile组件
|
||||
import { FloatButton } from 'antd';
|
||||
import { BarsOutlined, } from '@ant-design/icons';
|
||||
|
|
@ -8,7 +8,9 @@ export default function Render(props) {
|
|||
const { items } = data;
|
||||
if (items && items.length === 1) {
|
||||
const item = items[0];
|
||||
return (_jsx(FloatButton, { shape: "circle", type: "primary", style: { right: 24 }, icon: item.icon, description: item.icon ? null : item.label, onClick: () => item.onClick() }));
|
||||
return (<FloatButton shape="circle" type="primary" style={{ right: 24 }} icon={item.icon} description={item.icon ? null : item.label} onClick={() => item.onClick()}/>);
|
||||
}
|
||||
return (_jsx(FloatButton.Group, { shape: 'circle', trigger: "click", type: "primary", style: { right: 24 }, icon: _jsx(BarsOutlined, {}), children: items && items.map((ele) => (_jsx(FloatButton, { icon: ele.icon, description: ele.icon ? null : ele.label, onClick: () => ele.onClick() }))) }));
|
||||
return (<FloatButton.Group shape='circle' trigger="click" type="primary" style={{ right: 24 }} icon={<BarsOutlined />}>
|
||||
{items && items.map((ele) => (<FloatButton icon={ele.icon} description={ele.icon ? null : ele.label} onClick={() => ele.onClick()}/>))}
|
||||
</FloatButton.Group>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { ListButtonProps } from '../../../types/AbstractComponent';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
export default function Render(props: WebComponentProps<EntityDict & BaseEntityDict, keyof EntityDict, false, {
|
||||
items: ListButtonProps[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Button } from 'antd';
|
||||
export default function Render(props) {
|
||||
const { methods, data: oakData } = props;
|
||||
const { items } = oakData;
|
||||
// 为了i18更新时能够重新渲染
|
||||
return (_jsx(Space, { children: items.filter((ele) => ele.show).map((ele) => (_jsx(Button, { type: ele.type, onClick: ele.onClick, children: ele.label }))) }));
|
||||
return (<Space>
|
||||
{items.filter((ele) => ele.show).map((ele) => (<Button type={ele.type} onClick={ele.onClick}>
|
||||
{ele.label}
|
||||
</Button>))}
|
||||
</Space>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
declare function ColumnSetting(): import("react/jsx-runtime").JSX.Element;
|
||||
import React from 'react';
|
||||
declare function ColumnSetting(): React.JSX.Element;
|
||||
export default ColumnSetting;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { SettingOutlined, VerticalAlignBottomOutlined, VerticalAlignTopOutlined, } from '@ant-design/icons';
|
||||
import { Popover, Space, Tooltip, Tree, Button } from 'antd';
|
||||
import Style from './index.module.less';
|
||||
|
|
@ -9,15 +8,29 @@ import { useFeatures } from '../../../platforms/web';
|
|||
function ListItem(props) {
|
||||
const features = useFeatures();
|
||||
const { disabled, title, onSelect, showToBottom, showToTop, onMoveTop, onMoveBottom, } = props;
|
||||
return (_jsxs("div", { className: Style.listItemView, onClick: onSelect, children: [_jsx("div", { className: Style.listItemTitle, children: title }), !disabled ? (_jsxs("div", { className: Style.listIconView, children: [_jsx(Tooltip, { title: features.locales.t('leftPin'), children: showToTop && (_jsx("div", { className: Style.listIcon, onClick: (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
onMoveTop();
|
||||
}, children: _jsx(VerticalAlignTopOutlined, {}) })) }), _jsx(Tooltip, { title: features.locales.t('rightPin'), children: showToBottom && (_jsx("div", { className: Style.listIcon, onClick: (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
onMoveBottom();
|
||||
}, children: _jsx(VerticalAlignBottomOutlined, {}) })) })] })) : null] }));
|
||||
return (<div className={Style.listItemView} onClick={onSelect}>
|
||||
<div className={Style.listItemTitle}>{title}</div>
|
||||
{!disabled ? (<div className={Style.listIconView}>
|
||||
<Tooltip title={features.locales.t('leftPin')}>
|
||||
{showToTop && (<div className={Style.listIcon} onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
onMoveTop();
|
||||
}}>
|
||||
<VerticalAlignTopOutlined />
|
||||
</div>)}
|
||||
</Tooltip>
|
||||
<Tooltip title={features.locales.t('rightPin')}>
|
||||
{showToBottom && (<div className={Style.listIcon} onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
onMoveBottom();
|
||||
}}>
|
||||
<VerticalAlignBottomOutlined />
|
||||
</div>)}
|
||||
</Tooltip>
|
||||
</div>) : null}
|
||||
</div>);
|
||||
}
|
||||
function ColumnSetting() {
|
||||
const features = useFeatures();
|
||||
|
|
@ -71,7 +84,7 @@ function ColumnSetting() {
|
|||
setTableAttributes([...tableAttributes]);
|
||||
}
|
||||
};
|
||||
const listDom = (_jsx(Tree, { itemHeight: 24, draggable: true, checkable: true, onDrop: (info) => {
|
||||
const listDom = (<Tree itemHeight={24} draggable={true} checkable={true} onDrop={(info) => {
|
||||
const dropKey = info.node.key;
|
||||
const dragKey = info.dragNode.key;
|
||||
const { dropPosition, dropToGap } = info;
|
||||
|
|
@ -79,9 +92,20 @@ function ColumnSetting() {
|
|||
? dropPosition + 1
|
||||
: dropPosition;
|
||||
move(dragKey, dropKey, position);
|
||||
}, blockNode: true, onCheck: (checkedKeys, e) => {
|
||||
}} blockNode onCheck={(checkedKeys, e) => {
|
||||
onCheck(e.node);
|
||||
}, titleRender: (node) => (_jsx(ListItem, { disabled: node.disabled, title: node.title, nodeKey: node.key, showToTop: node.keyIndex !== 0, showToBottom: node.keyIndex !== treeData.length - 1, onSelect: () => onCheck(node), onMoveTop: () => move(node.key, treeData[0].key, 0), onMoveBottom: () => move(node.key, treeData[treeData.length - 1].key, treeData.length + 1) })), checkedKeys: checkedKeys, showLine: false, treeData: treeData }));
|
||||
return (_jsx(Popover, { arrow: false, title: _jsxs("div", { className: Style.titleView, children: [_jsx("strong", { children: features.locales.t('columnSetting') }), _jsx(Button, { type: "link", onClick: onReset, children: features.locales.t('common::reset') })] }), trigger: "click", placement: "bottomRight", content: _jsx(Space, { children: listDom }), children: _jsx(Tooltip, { title: features.locales.t('columnSetting'), children: _jsx("div", { className: Style.iconBox, children: _jsx(SettingOutlined, {}) }) }) }));
|
||||
}} titleRender={(node) => (<ListItem disabled={node.disabled} title={node.title} nodeKey={node.key} showToTop={node.keyIndex !== 0} showToBottom={node.keyIndex !== treeData.length - 1} onSelect={() => onCheck(node)} onMoveTop={() => move(node.key, treeData[0].key, 0)} onMoveBottom={() => move(node.key, treeData[treeData.length - 1].key, treeData.length + 1)}/>)} checkedKeys={checkedKeys} showLine={false} treeData={treeData}/>);
|
||||
return (<Popover arrow={false} title={<div className={Style.titleView}>
|
||||
<strong>{features.locales.t('columnSetting')}</strong>
|
||||
<Button type="link" onClick={onReset}>
|
||||
{features.locales.t('common::reset')}
|
||||
</Button>
|
||||
</div>} trigger="click" placement="bottomRight" content={<Space>{listDom}</Space>}>
|
||||
<Tooltip title={features.locales.t('columnSetting')}>
|
||||
<div className={Style.iconBox}>
|
||||
<SettingOutlined />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</Popover>);
|
||||
}
|
||||
export default ColumnSetting;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { OakAbsDerivedAttrDef } from '../../../types/AbstractComponent';
|
||||
|
|
@ -6,4 +7,4 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
value: string | string[];
|
||||
type: OakAbsDerivedAttrDef['type'];
|
||||
color: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Typography } from 'antd';
|
||||
import ImgBox from '../../imgBox';
|
||||
const { Link, Text } = Typography;
|
||||
|
|
@ -6,19 +6,29 @@ export default function Render(props) {
|
|||
const { methods, data: oakData } = props;
|
||||
const { value, type, color } = oakData;
|
||||
if (value === null || value === '' || value === undefined) {
|
||||
return (_jsx(_Fragment, { children: "--" }));
|
||||
return (<>--</>);
|
||||
}
|
||||
else if (type === 'image') {
|
||||
if (value instanceof Array) {
|
||||
return (_jsx(Space, { children: value.map((ele) => (_jsx(ImgBox, { src: ele, width: 100, height: 60 }))) }));
|
||||
return (<Space>
|
||||
{value.map((ele) => (<ImgBox src={ele} width={100} height={60}/>))}
|
||||
</Space>);
|
||||
}
|
||||
return (_jsx(ImgBox, { src: value, width: 100, height: 60 }));
|
||||
return (<ImgBox src={value} width={100} height={60}/>);
|
||||
}
|
||||
else if (type === 'link') {
|
||||
if (value instanceof Array) {
|
||||
return (_jsx(Space, { direction: "vertical", children: value.map((ele) => (_jsx(Link, { href: ele, target: "_blank", ellipsis: true, children: ele }))) }));
|
||||
return (<Space direction="vertical">
|
||||
{value.map((ele) => (<Link href={ele} target="_blank" ellipsis>
|
||||
{ele}
|
||||
</Link>))}
|
||||
</Space>);
|
||||
}
|
||||
return (_jsx(Link, { href: value, target: "_blank", ellipsis: true, children: value }));
|
||||
return (<Link href={value} target="_blank" ellipsis>
|
||||
{value}
|
||||
</Link>);
|
||||
}
|
||||
return (_jsx(Text, { ellipsis: true, children: value }));
|
||||
return (<Text ellipsis>
|
||||
{value}
|
||||
</Text>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { OakAbsDerivedAttrDef } from '../../../types/AbstractComponent';
|
||||
|
|
@ -7,4 +8,4 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
type: OakAbsDerivedAttrDef['type'];
|
||||
color: string;
|
||||
linkUrl: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Tag, Tooltip, Typography } from 'antd';
|
||||
import ImgBox from '../../imgBox';
|
||||
const { Link } = Typography;
|
||||
|
|
@ -6,7 +6,7 @@ export default function Render(props) {
|
|||
const { methods, data: oakData } = props;
|
||||
const { value, type, color, linkUrl } = oakData;
|
||||
if (value === null || value === '' || value === undefined) {
|
||||
return (_jsx(_Fragment, { children: "--" }));
|
||||
return (<>--</>);
|
||||
}
|
||||
// 属性类型是enum要使用标签
|
||||
else if (type === 'enum') {
|
||||
|
|
@ -18,26 +18,38 @@ export default function Render(props) {
|
|||
if (renderColor === 'danger') {
|
||||
renderColor = 'error';
|
||||
}
|
||||
return (_jsx(Tag, { color: renderColor, children: value }));
|
||||
return (<Tag color={renderColor}>
|
||||
{value}
|
||||
</Tag>);
|
||||
}
|
||||
else if (type === 'image') {
|
||||
if (value instanceof Array) {
|
||||
return (_jsx(Space, { children: value.map((ele) => (_jsx(ImgBox, { src: ele, width: 120, height: 70 }))) }));
|
||||
return (<Space>
|
||||
{value.map((ele) => (<ImgBox src={ele} width={120} height={70}/>))}
|
||||
</Space>);
|
||||
}
|
||||
return (_jsx(ImgBox, { src: value, width: 120, height: 70 }));
|
||||
return (<ImgBox src={value} width={120} height={70}/>);
|
||||
}
|
||||
else if (type === 'link') {
|
||||
let href = linkUrl;
|
||||
if (value instanceof Array) {
|
||||
return (_jsx(Space, { direction: "vertical", children: value.map((ele) => {
|
||||
return (<Space direction="vertical">
|
||||
{value.map((ele) => {
|
||||
href = ele;
|
||||
if (linkUrl) {
|
||||
href = linkUrl;
|
||||
}
|
||||
return (_jsx(Link, { href: href, children: ele }));
|
||||
}) }));
|
||||
return (<Link href={href}>
|
||||
{ele}
|
||||
</Link>);
|
||||
})}
|
||||
</Space>);
|
||||
}
|
||||
return (_jsx(Link, { href: href, children: value }));
|
||||
return (<Link href={href}>
|
||||
{value}
|
||||
</Link>);
|
||||
}
|
||||
return (_jsx(Tooltip, { placement: "topLeft", title: value, children: value }));
|
||||
return (<Tooltip placement="topLeft" title={value}>
|
||||
{value}
|
||||
</Tooltip>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { ButtonProps } from 'antd';
|
||||
type buttonProps = {
|
||||
label: string;
|
||||
|
|
@ -9,5 +10,5 @@ type ToolBarProps = {
|
|||
buttonGroup?: buttonProps[];
|
||||
reload: () => void;
|
||||
};
|
||||
declare function ToolBar(props: ToolBarProps): import("react/jsx-runtime").JSX.Element;
|
||||
declare function ToolBar(props: ToolBarProps): React.JSX.Element;
|
||||
export default ToolBar;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Space, Tooltip } from 'antd';
|
||||
import { ReloadOutlined } from '@ant-design/icons';
|
||||
import ButtonGroup from '../buttonGroup';
|
||||
|
|
@ -8,8 +8,21 @@ import Style from './index.module.less';
|
|||
function ToolBar(props) {
|
||||
const { title, buttonGroup, reload } = props;
|
||||
const features = useFeatures();
|
||||
return (_jsxs("div", { className: Style.toolbarContainer, children: [_jsx("div", { className: Style.title, children: title }), _jsx("div", { className: Style.toolbarRight, children: _jsxs(Space, { children: [buttonGroup && buttonGroup.length > 0 && (_jsx(ButtonGroup, { items: buttonGroup })), _jsx(Tooltip, { title: features.locales.t('reload'), children: _jsx("div", { className: Style.reloadIconBox, onClick: () => {
|
||||
reload();
|
||||
}, children: _jsx(ReloadOutlined, {}) }) }), _jsx(ColumnSetting, {})] }) })] }));
|
||||
return (<div className={Style.toolbarContainer}>
|
||||
<div className={Style.title}>{title}</div>
|
||||
<div className={Style.toolbarRight}>
|
||||
<Space>
|
||||
{buttonGroup && buttonGroup.length > 0 && (<ButtonGroup items={buttonGroup}/>)}
|
||||
<Tooltip title={features.locales.t('reload')}>
|
||||
<div className={Style.reloadIconBox} onClick={() => {
|
||||
reload();
|
||||
}}>
|
||||
<ReloadOutlined />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<ColumnSetting />
|
||||
</Space>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
export default ToolBar;
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
type: 'single' | 'multiple' | 'none';
|
||||
}) => void;
|
||||
};
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import ActionBtn from '../actionBtn';
|
||||
import styles from './mobile.module.less';
|
||||
|
|
@ -11,32 +10,55 @@ export default function Render(props) {
|
|||
const { oakLoading, entity, extraActions, mobileData, onAction, disabledOp = false, rowSelection } = data;
|
||||
const useSelect = !!rowSelection?.type;
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
return (_jsx("div", { className: styles.container, children: oakLoading ? (_jsx("div", { className: styles.loadingView, children: _jsx(Spin, { size: 'large' }) })) : (_jsx(_Fragment, { children: mobileData && mobileData.map((ele) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', flex: 1 }, children: [useSelect && (_jsx(Checkbox, { checked: selectedRowKeys.includes(ele.record.id), onChange: (checked) => {
|
||||
if (checked) {
|
||||
selectedRowKeys.push(ele.record.id);
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
else {
|
||||
const index = selectedRowKeys.findIndex((ele2) => ele2 === ele.record.id);
|
||||
selectedRowKeys.splice(index, 1);
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
} })), _jsxs("div", { className: styles.card, onClick: () => {
|
||||
const index = selectedRowKeys.findIndex((ele2) => ele2 === ele.record?.id);
|
||||
let keys = selectedRowKeys;
|
||||
if (rowSelection?.type === 'checkbox') {
|
||||
if (index !== -1) {
|
||||
keys.splice(index, 1);
|
||||
}
|
||||
else {
|
||||
keys.push(ele.record?.id);
|
||||
}
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
else {
|
||||
keys = [ele.record?.id];
|
||||
setSelectedRowKeys([ele.record?.id]);
|
||||
}
|
||||
rowSelection?.onChange && rowSelection?.onChange(keys, ele.record, { type: rowSelection.type === 'checkbox' ? 'multiple' : 'single' });
|
||||
}, children: [_jsx("div", { className: styles.cardContent, children: ele.data.map((ele2) => (_jsxs("div", { className: styles.textView, children: [_jsx("div", { className: styles.label, children: ele2.label }), _jsx("div", { className: styles.value, children: _jsx(RenderCell, { value: ele2.value, type: ele2.type }) })] }))) }), !disabledOp && (_jsx("div", { style: { display: 'flex', alignItems: 'center', padding: 10 }, children: _jsx(ActionBtn, { entity: entity, extraActions: extraActions, actions: ele.record?.['#oakLegalActions'], cascadeActions: ele.record?.['#oakLegalCascadeActions'], onAction: (action, cascadeAction) => onAction && onAction(ele.record, action, cascadeAction) }) }))] })] }))) })) }));
|
||||
return (<div className={styles.container}>
|
||||
{oakLoading ? (<div className={styles.loadingView}>
|
||||
<Spin size='large'/>
|
||||
</div>) : (<>
|
||||
{mobileData && mobileData.map((ele) => (<div style={{ display: 'flex', alignItems: 'center', flex: 1 }}>
|
||||
{useSelect && (<Checkbox checked={selectedRowKeys.includes(ele.record.id)} onChange={(checked) => {
|
||||
if (checked) {
|
||||
selectedRowKeys.push(ele.record.id);
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
else {
|
||||
const index = selectedRowKeys.findIndex((ele2) => ele2 === ele.record.id);
|
||||
selectedRowKeys.splice(index, 1);
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
}}/>)}
|
||||
<div className={styles.card} onClick={() => {
|
||||
const index = selectedRowKeys.findIndex((ele2) => ele2 === ele.record?.id);
|
||||
let keys = selectedRowKeys;
|
||||
if (rowSelection?.type === 'checkbox') {
|
||||
if (index !== -1) {
|
||||
keys.splice(index, 1);
|
||||
}
|
||||
else {
|
||||
keys.push(ele.record?.id);
|
||||
}
|
||||
setSelectedRowKeys([...selectedRowKeys]);
|
||||
}
|
||||
else {
|
||||
keys = [ele.record?.id];
|
||||
setSelectedRowKeys([ele.record?.id]);
|
||||
}
|
||||
rowSelection?.onChange && rowSelection?.onChange(keys, ele.record, { type: rowSelection.type === 'checkbox' ? 'multiple' : 'single' });
|
||||
}}>
|
||||
<div className={styles.cardContent}>
|
||||
{ele.data.map((ele2) => (<div className={styles.textView}>
|
||||
<div className={styles.label}>
|
||||
{ele2.label}
|
||||
</div>
|
||||
<div className={styles.value}>
|
||||
<RenderCell value={ele2.value} type={ele2.type}/>
|
||||
</div>
|
||||
</div>))}
|
||||
</div>
|
||||
{!disabledOp && (<div style={{ display: 'flex', alignItems: 'center', padding: 10 }}>
|
||||
<ActionBtn entity={entity} extraActions={extraActions} actions={ele.record?.['#oakLegalActions']} cascadeActions={ele.record?.['#oakLegalCascadeActions']} onAction={(action, cascadeAction) => onAction && onAction(ele.record, action, cascadeAction)}/>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>))}
|
||||
</>)}
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { TableProps } from 'antd';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
|
|
@ -21,4 +22,4 @@ export default function Render(props: WebComponentProps<EntityDict & BaseEntityD
|
|||
i18n: any;
|
||||
hideHeader?: boolean;
|
||||
judgeAttributes: OakAbsAttrJudgeDef[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { Table } from 'antd';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { get } from 'oak-domain/lib/utils/lodash';
|
||||
|
|
@ -44,7 +43,7 @@ export default function Render(props) {
|
|||
const stateValue = get(row, ele.path);
|
||||
let href = '';
|
||||
if ([null, undefined, ''].includes(stateValue)) {
|
||||
return _jsx(_Fragment, {});
|
||||
return <></>;
|
||||
}
|
||||
const color = colorDict && colorDict[ele.entity]?.[ele.attr]?.[stateValue];
|
||||
if (type === 'enum' && !color) {
|
||||
|
|
@ -53,7 +52,7 @@ export default function Render(props) {
|
|||
if (type === 'link') {
|
||||
href = getLinkUrl(ele.attribute, { oakId: row?.id });
|
||||
}
|
||||
return (_jsx(TableCell, { color: color, value: value, type: type, linkUrl: href }));
|
||||
return (<TableCell color={color} value={value} type={type} linkUrl={href}/>);
|
||||
}
|
||||
};
|
||||
if (width) {
|
||||
|
|
@ -79,26 +78,26 @@ export default function Render(props) {
|
|||
render: (value, row) => {
|
||||
const oakActions = row?.['#oakLegalActions'];
|
||||
// assert(!!oakActions, '行数据中不存在#oakLegalActions, 请禁用(disableOp:true)或添加actions')
|
||||
return (_jsx(ActionBtn, { entity: entity, extraActions: extraActions, actions: oakActions || [], cascadeActions: row?.['#oakLegalCascadeActions'], onAction: (action, cascadeAction) => onAction && onAction(row, action, cascadeAction) }));
|
||||
return (<ActionBtn entity={entity} extraActions={extraActions} actions={oakActions || []} cascadeActions={row?.['#oakLegalCascadeActions']} onAction={(action, cascadeAction) => onAction && onAction(row, action, cascadeAction)}/>);
|
||||
}
|
||||
});
|
||||
}
|
||||
setTabelColumns(tableColumns);
|
||||
}
|
||||
}, [data, zhCNKeys, schema, tableAttributes]);
|
||||
return (_jsx(Table, { rowKey: "id", rowSelection: rowSelection?.type && {
|
||||
return (<Table rowKey="id" rowSelection={rowSelection?.type && {
|
||||
type: rowSelection?.type,
|
||||
selectedRowKeys,
|
||||
onChange: (selectedRowKeys, row, info) => {
|
||||
rowSelection?.onChange &&
|
||||
rowSelection?.onChange(selectedRowKeys, row, info);
|
||||
},
|
||||
}, loading: loading, dataSource: data, columns: tableColumns, pagination: tablePagination, scroll: showScroll
|
||||
}} loading={loading} dataSource={data} columns={tableColumns} pagination={tablePagination} scroll={showScroll
|
||||
? {
|
||||
scrollToFirstRowOnChange: true,
|
||||
x: 1200,
|
||||
}
|
||||
: {}, onRow: (record) => {
|
||||
: {}} onRow={(record) => {
|
||||
return {
|
||||
onClick: () => {
|
||||
const index = selectedRowKeys.findIndex((ele) => ele === record.id);
|
||||
|
|
@ -119,5 +118,5 @@ export default function Render(props) {
|
|||
rowSelection?.onChange(keys, row, { type: 'all' });
|
||||
},
|
||||
};
|
||||
}, showHeader: !hideHeader }));
|
||||
}} showHeader={!hideHeader}></Table>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,5 +38,5 @@ export declare const TableContext: React.Context<{
|
|||
setSchema: ((schema: any) => void) | undefined;
|
||||
onReset: (() => void) | undefined;
|
||||
}>;
|
||||
declare const ProList: <ED2 extends ED, T extends keyof ED2>(props: Props<ED2, T>) => import("react/jsx-runtime").JSX.Element;
|
||||
declare const ProList: <ED2 extends ED, T extends keyof ED2>(props: Props<ED2, T>) => React.JSX.Element;
|
||||
export default ProList;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { createContext, useEffect, useState } from 'react';
|
||||
import React, { createContext, useEffect, useState } from 'react';
|
||||
import { translateAttributes } from '../../utils/usefulFn';
|
||||
import List from '../list';
|
||||
import ToolBar from '../list/toolBar';
|
||||
|
|
@ -57,7 +56,7 @@ const ProList = (props) => {
|
|||
const totalStr = features.locales.t('total number of rows');
|
||||
return `${totalStr}:${total > 999 ? `${total} +` : total}`;
|
||||
};
|
||||
return (_jsx(TableContext.Provider, { value: {
|
||||
return (<TableContext.Provider value={{
|
||||
tableAttributes,
|
||||
entity: entity,
|
||||
schema,
|
||||
|
|
@ -66,22 +65,28 @@ const ProList = (props) => {
|
|||
onReset: () => {
|
||||
initTableAttributes();
|
||||
},
|
||||
}, children: _jsxs("div", { className: Style.container, children: [!isMobile && (_jsx(ToolBar, { title: title, buttonGroup: buttonGroup, reload: () => {
|
||||
onReload && onReload();
|
||||
} })), isMobile && _jsx(ButtonGroup, { items: buttonGroup }), _jsx(List, { entity: entity, extraActions: extraActions, onAction: onAction, disabledOp: disabledOp, attributes: attributes, data: !disableSerialNumber
|
||||
? data?.map((ele, index) => {
|
||||
if (tablePagination) {
|
||||
const total = tablePagination.total || 0;
|
||||
const pageSize = tablePagination.pageSize || 20; //条数
|
||||
const current = tablePagination.current || 1; //当前页
|
||||
ele['#'] =
|
||||
pageSize * (current - 1) +
|
||||
(index + 1);
|
||||
}
|
||||
return ele;
|
||||
})
|
||||
: data, loading: loading, tablePagination: Object.assign({
|
||||
showTotal,
|
||||
}, tablePagination), rowSelection: rowSelection })] }) }));
|
||||
}}>
|
||||
<div className={Style.container}>
|
||||
{!isMobile && (<ToolBar title={title} buttonGroup={buttonGroup} reload={() => {
|
||||
onReload && onReload();
|
||||
}}/>)}
|
||||
{isMobile && <ButtonGroup items={buttonGroup}/>}
|
||||
<List entity={entity} extraActions={extraActions} onAction={onAction} disabledOp={disabledOp} attributes={attributes} data={!disableSerialNumber
|
||||
? data?.map((ele, index) => {
|
||||
if (tablePagination) {
|
||||
const total = tablePagination.total || 0;
|
||||
const pageSize = tablePagination.pageSize || 20; //条数
|
||||
const current = tablePagination.current || 1; //当前页
|
||||
ele['#'] =
|
||||
pageSize * (current - 1) +
|
||||
(index + 1);
|
||||
}
|
||||
return ele;
|
||||
})
|
||||
: data} loading={loading} tablePagination={Object.assign({
|
||||
showTotal,
|
||||
}, tablePagination)} rowSelection={rowSelection}/>
|
||||
</div>
|
||||
</TableContext.Provider>);
|
||||
};
|
||||
export default ProList;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from "react";
|
||||
type LocationProps = {
|
||||
poiName?: string;
|
||||
coordinate?: [number, number];
|
||||
|
|
@ -15,5 +16,5 @@ export type Poi = {
|
|||
detail: string;
|
||||
coordinate: [number, number];
|
||||
};
|
||||
export default function Location(props: LocationProps): import("react/jsx-runtime").JSX.Element;
|
||||
export default function Location(props: LocationProps): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { Row, Col, Input, List, Empty, Spin, } from 'antd';
|
||||
import { SearchOutlined, CheckCircleFilled } from '@ant-design/icons';
|
||||
|
|
@ -31,39 +30,67 @@ export default function Location(props) {
|
|||
}
|
||||
}, [searchValue]);
|
||||
const center = currentPoi?.coordinate || props.coordinate;
|
||||
const Locate = (_jsx(List, { className: Styles["location-list"], header: _jsx(Input, { ref: searchRef, placeholder: "\u8BF7\u8F93\u5165\u5B8C\u6574\u540D\u79F0\uFF08\u5982\u201C\u6D59\u6C5F\u5927\u5B66\u201D\uFF09\u800C\u975E\u7B80\u79F0\uFF08\u5982\u201C\u6D59\u5927\u201D\uFF09", value: searchValue, allowClear: true, onChange: (e) => {
|
||||
const Locate = (<List className={Styles["location-list"]} header={<Input ref={searchRef} placeholder="请输入完整名称(如“浙江大学”)而非简称(如“浙大”)" value={searchValue} allowClear onChange={(e) => {
|
||||
setSearchValue(e.target.value);
|
||||
}, prefix: _jsx(SearchOutlined, {}), onFocus: () => {
|
||||
}} prefix={<SearchOutlined />} onFocus={() => {
|
||||
setMode('searchPoi');
|
||||
}, onBlur: () => {
|
||||
} }), children: mode === 'searchPoi' && (_jsx(React.Fragment, { children: searchLoading ? (_jsx("div", { className: Styles['location-list-meta'], children: _jsx(Spin, { delay: 0, spinning: true, size: "default" }) })) : (pois?.length
|
||||
}} onBlur={() => {
|
||||
}}/>}>
|
||||
{mode === 'searchPoi' && (<React.Fragment>
|
||||
{searchLoading ? (<div className={Styles['location-list-meta']}>
|
||||
<Spin delay={0} spinning size="default"/>
|
||||
</div>) : (pois?.length
|
||||
? pois.map((poi, index) => {
|
||||
return (_jsx("div", { onClick: () => {
|
||||
return (<div key={poi.id} onClick={() => {
|
||||
setCurrentPoi(poi);
|
||||
props.onLocated({
|
||||
poiName: poi.detail,
|
||||
coordinate: poi.coordinate,
|
||||
areaId: poi.areaId,
|
||||
});
|
||||
}, children: _jsx(List.Item, { actions: [
|
||||
_jsx("div", { style: {
|
||||
width: 24,
|
||||
}, children: currentPoi?.id ===
|
||||
poi.id && (_jsx(CheckCircleFilled, { className: Styles['location-list-checked'] })) }),
|
||||
], children: _jsx(List.Item.Meta, { title: poi.detail }) }) }, poi.id));
|
||||
}}>
|
||||
<List.Item actions={[
|
||||
<div style={{
|
||||
width: 24,
|
||||
}}>
|
||||
{currentPoi?.id ===
|
||||
poi.id && (<CheckCircleFilled className={Styles['location-list-checked']}/>)}
|
||||
</div>,
|
||||
]}>
|
||||
<List.Item.Meta title={poi.detail}/>
|
||||
</List.Item>
|
||||
</div>);
|
||||
})
|
||||
: (_jsx("div", { className: Styles['location-list-meta'], children: _jsx(Empty, { description: `没有${searchValue}相关的地名搜索结果`, image: Empty.PRESENTED_IMAGE_SIMPLE }) }))) })) }));
|
||||
: (<div className={Styles['location-list-meta']}>
|
||||
<Empty description={`没有${searchValue}相关的地名搜索结果`} image={Empty.PRESENTED_IMAGE_SIMPLE}/>
|
||||
</div>))}
|
||||
</React.Fragment>)}
|
||||
</List>);
|
||||
if (window.innerWidth > 480) {
|
||||
return (_jsxs(Row, { gutter: [16, 16], style: {
|
||||
return (<Row gutter={[16, 16]} style={{
|
||||
width: '100%',
|
||||
minHeight: 600,
|
||||
}, children: [_jsx(Col, { xs: 24, sm: 14, children: _jsx(Map, { style: { height: '100%' }, id: "location-map", center: center, markers: center ? [center] : undefined }) }), _jsx(Col, { xs: 24, sm: 10, children: Locate })] }));
|
||||
}}>
|
||||
<Col xs={24} sm={14}>
|
||||
<Map style={{ height: '100%' }} id="location-map" center={center} markers={center ? [center] : undefined}/>
|
||||
</Col>
|
||||
<Col xs={24} sm={10}>
|
||||
{Locate}
|
||||
</Col>
|
||||
</Row>);
|
||||
}
|
||||
return (_jsxs(Col, { style: {
|
||||
return (<Col style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch',
|
||||
}, children: [_jsx(Row, { children: _jsx(Map, { style: { height: 400, width: '100%' }, id: "location-map", center: center, markers: center ? [center] : undefined }) }), _jsx(Row, { style: { flex: 1, marginLeft: 5, marginRight: 5 }, children: Locate })] }));
|
||||
}}>
|
||||
<Row>
|
||||
<Map style={{ height: 400, width: '100%' }} id="location-map" center={center} markers={center ? [center] : undefined}/>
|
||||
</Row>
|
||||
<Row style={{ flex: 1, marginLeft: 5, marginRight: 5 }}>
|
||||
{Locate}
|
||||
</Row>
|
||||
</Col>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import 'ol/ol.css';
|
||||
type MapProps = {
|
||||
id?: string;
|
||||
|
|
@ -10,5 +11,5 @@ type MapProps = {
|
|||
autoLocate?: boolean;
|
||||
markers?: Array<[number, number]>;
|
||||
};
|
||||
export default function Map(props: MapProps): import("react/jsx-runtime").JSX.Element;
|
||||
export default function Map(props: MapProps): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import OlMap from 'ol/Map';
|
||||
import Feature from 'ol/Feature';
|
||||
import XYZ from 'ol/source/XYZ';
|
||||
|
|
@ -117,5 +116,5 @@ export default function Map(props) {
|
|||
map.render();
|
||||
}
|
||||
}, [props.markers]);
|
||||
return (_jsx("div", { id: `map-${id || prefix}`, className: Styles.map, style: props.style }));
|
||||
return (<div id={`map-${id || prefix}`} className={Styles.map} style={props.style}/>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
type Props = {
|
||||
items: Array<{
|
||||
title: string;
|
||||
|
|
@ -5,5 +6,5 @@ type Props = {
|
|||
}>;
|
||||
title: string;
|
||||
};
|
||||
export default function Render(props: Props): import("react/jsx-runtime").JSX.Element;
|
||||
export default function Render(props: Props): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Breadcrumb, Divider } from 'antd';
|
||||
export default function Render(props) {
|
||||
const { items, title } = props;
|
||||
const items2 = items.concat({ title });
|
||||
return (_jsxs(_Fragment, { children: [_jsx(Breadcrumb, { items: items2.map((ele) => {
|
||||
const { title, href } = ele;
|
||||
if (href) {
|
||||
return {
|
||||
title,
|
||||
href,
|
||||
};
|
||||
}
|
||||
return {
|
||||
title,
|
||||
};
|
||||
}) }), _jsx(Divider, { style: { marginTop: 4 } })] }));
|
||||
return (<>
|
||||
<Breadcrumb items={items2.map((ele) => {
|
||||
const { title, href } = ele;
|
||||
if (href) {
|
||||
return {
|
||||
title,
|
||||
href,
|
||||
};
|
||||
}
|
||||
return {
|
||||
title,
|
||||
};
|
||||
})}/>
|
||||
<Divider style={{ marginTop: 4 }}/>
|
||||
</>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ type PageHeaderProps = {
|
|||
type ED = EntityDict & BaseEntityDict;
|
||||
export default function Render(props: WebComponentProps<ED, keyof ED, false, PageHeaderProps, {
|
||||
goBack: (delta?: number) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Row, Col, Button } from 'antd';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import classNames from 'classnames';
|
||||
|
|
@ -7,13 +7,35 @@ export default function Render(props) {
|
|||
const { style, className, children, title, subTitle, extra, showBack = false, onBack, backIcon, delta, contentMargin = true, contentStyle, contentClassName, tags, showHeader = true, } = props.data;
|
||||
const { t, goBack } = props.methods;
|
||||
const prefixCls = 'oak';
|
||||
return (_jsxs("div", { style: style, className: classNames(`${prefixCls}-pageHeader`, className), children: [showHeader && (title || showBack || subTitle || tags || extra) && (_jsx("div", { className: `${prefixCls}-pageHeader-header`, children: _jsxs(Row, { justify: "center", children: [_jsxs(Col, { flex: "auto", className: `${prefixCls}-pageHeader-header-col`, children: [showBack && (_jsx(Button, { type: "text", className: `${prefixCls}-pageHeader-header-back`, onClick: () => {
|
||||
if (typeof onBack === 'function') {
|
||||
onBack();
|
||||
return;
|
||||
}
|
||||
goBack(delta);
|
||||
}, children: backIcon || (_jsx(ArrowLeftOutlined, { className: `${prefixCls}-pageHeader-header-backIcon` })) })), title && (_jsx("span", { className: `${prefixCls}-pageHeader-header-title`, children: title })), subTitle && (_jsx("span", { className: `${prefixCls}-pageHeader-header-subTitle`, children: subTitle })), tags] }), _jsx(Col, { flex: "auto", children: extra })] }) })), _jsx("div", { style: contentStyle, className: classNames(`${prefixCls}-pageHeader-content`, contentClassName, {
|
||||
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
|
||||
}), children: children })] }));
|
||||
return (<div style={style} className={classNames(`${prefixCls}-pageHeader`, className)}>
|
||||
{showHeader && (title || showBack || subTitle || tags || extra) && (<div className={`${prefixCls}-pageHeader-header`}>
|
||||
<Row justify="center">
|
||||
<Col flex="auto" className={`${prefixCls}-pageHeader-header-col`}>
|
||||
{showBack && (<Button type="text" className={`${prefixCls}-pageHeader-header-back`} onClick={() => {
|
||||
if (typeof onBack === 'function') {
|
||||
onBack();
|
||||
return;
|
||||
}
|
||||
goBack(delta);
|
||||
}}>
|
||||
{backIcon || (<ArrowLeftOutlined className={`${prefixCls}-pageHeader-header-backIcon`}/>)}
|
||||
</Button>)}
|
||||
{title && (<span className={`${prefixCls}-pageHeader-header-title`}>
|
||||
{title}
|
||||
</span>)}
|
||||
{subTitle && (<span className={`${prefixCls}-pageHeader-header-subTitle`}>
|
||||
{subTitle}
|
||||
</span>)}
|
||||
{tags}
|
||||
</Col>
|
||||
<Col flex="auto">{extra}</Col>
|
||||
</Row>
|
||||
</div>)}
|
||||
|
||||
<div style={contentStyle} className={classNames(`${prefixCls}-pageHeader-content`, contentClassName, {
|
||||
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
|
||||
})}>
|
||||
{children}
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps, RowWithActions } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
export default function Render(props: WebComponentProps<ED, keyof ED, false, {
|
||||
|
|
@ -7,4 +8,4 @@ export default function Render(props: WebComponentProps<ED, keyof ED, false, {
|
|||
onSelect: (rows: RowWithActions<ED, keyof ED>[]) => void;
|
||||
multiple: boolean;
|
||||
titleLabel: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Empty } from 'antd';
|
||||
import AbstractList from '../list';
|
||||
export default function Render(props) {
|
||||
|
|
@ -9,12 +9,14 @@ export default function Render(props) {
|
|||
title: titleLabel,
|
||||
}];
|
||||
if (rows && rows.length) {
|
||||
return (_jsx(AbstractList, { entity: entity, data: rows, loading: oakLoading, attributes: [titleLabel], disabledOp: true, rowSelection: {
|
||||
return (<AbstractList entity={entity} data={rows} loading={oakLoading} attributes={[titleLabel]} disabledOp={true} rowSelection={{
|
||||
type: multiple ? 'checkbox' : 'radio',
|
||||
onChange: (selectRowKeys, selectedRows, info) => {
|
||||
onSelect(selectedRows);
|
||||
}
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
return (_jsx("div", { children: _jsx(Empty, { image: Empty.PRESENTED_IMAGE_SIMPLE }) }));
|
||||
return (<div>
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { OakAbsRefAttrPickerRender } from '../../types/AbstractComponent';
|
||||
|
|
@ -16,5 +17,5 @@ export default function render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
pickerRender: OakAbsRefAttrPickerRender<ED, keyof ED>;
|
||||
onChange: (value: string[]) => void;
|
||||
schema: StorageSchema<EntityDict & BaseEntityDict>;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Checkbox, Input, Radio, Popup, Space, Selector, } from 'antd-mobile';
|
||||
import Picker from '../picker';
|
||||
import { combineFilters } from 'oak-domain/lib/store/filter';
|
||||
|
|
@ -12,70 +11,79 @@ export default function render(props) {
|
|||
const [dynamicSorter, setDynamicSorter] = useState(undefined);
|
||||
const [dynamicProjection, setDynamicProjection] = useState(undefined);
|
||||
if (!data && mode !== 'list') {
|
||||
return _jsx("div", { children: " loading... " });
|
||||
return <div> loading... </div>;
|
||||
}
|
||||
else {
|
||||
switch (mode) {
|
||||
case 'select': {
|
||||
return (_jsx(Selector, { value: [entityId], onChange: (value) => {
|
||||
return (<Selector value={[entityId]} onChange={(value) => {
|
||||
onChange(value);
|
||||
}, options: data.map((ele) => ({
|
||||
}} options={data.map((ele) => ({
|
||||
value: ele.id,
|
||||
label: ele.title,
|
||||
})), multiple: multiple }));
|
||||
}))} multiple={multiple}></Selector>);
|
||||
}
|
||||
case 'radio': {
|
||||
if (multiple) {
|
||||
return (_jsx(Checkbox.Group, { value: entityIds, onChange: (value) => onChange(value), children: data.map((ele) => (_jsx(Checkbox, { value: ele.id, children: ele.title }))) }));
|
||||
return (<Checkbox.Group value={entityIds} onChange={(value) => onChange(value)}>
|
||||
{data.map((ele) => (<Checkbox value={ele.id}>{ele.title}</Checkbox>))}
|
||||
</Checkbox.Group>);
|
||||
}
|
||||
return (_jsx(Radio.Group, { onChange: (value) => onChange([value]), value: entityId, children: data.map((ele) => (_jsx(Radio, { value: ele.id, children: ele.title }))) }));
|
||||
return (<Radio.Group onChange={(value) => onChange([value])} value={entityId}>
|
||||
{data.map((ele) => (<Radio value={ele.id}>{ele.title}</Radio>))}
|
||||
</Radio.Group>);
|
||||
}
|
||||
case 'list': {
|
||||
const { entity, projection, title, titleLabel, filter, sorter, required, getDynamicSelectors, } = pickerRender;
|
||||
return (_jsxs(Space, { children: [_jsx(Input, { value: renderValue, clearable: !required, onClick: async () => {
|
||||
if (getDynamicSelectors) {
|
||||
// todo 这段代码没测过
|
||||
const { projection: dynamicProjection2, filter: dynamicFilter2, sorter: dynamicSorter2, } = await getDynamicSelectors();
|
||||
if (dynamicFilter2 || filter) {
|
||||
setDynamicFilter(combineFilters(entity, schema, [
|
||||
dynamicFilter2,
|
||||
filter,
|
||||
]));
|
||||
}
|
||||
if (dynamicSorter2 || sorter) {
|
||||
setDynamicSorter(dynamicSorter2 || sorter);
|
||||
}
|
||||
if (dynamicProjection2 || projection) {
|
||||
setDynamicProjection(dynamicProjection2 || projection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (filter) {
|
||||
setDynamicFilter(filter);
|
||||
}
|
||||
if (sorter) {
|
||||
setDynamicSorter(sorter);
|
||||
}
|
||||
if (projection) {
|
||||
setDynamicProjection(projection);
|
||||
}
|
||||
}
|
||||
setVisible(true);
|
||||
}, onChange: (value) => {
|
||||
if (!value) {
|
||||
onChange([]);
|
||||
}
|
||||
} }), _jsx(Popup, { visible: visibile, closeOnMaskClick: true, onClose: () => {
|
||||
setDynamicFilter(undefined);
|
||||
setDynamicProjection(undefined);
|
||||
setDynamicSorter(undefined);
|
||||
setVisible(false);
|
||||
}, destroyOnClose: true, showCloseButton: true, bodyStyle: {
|
||||
height: '80%',
|
||||
}, children: _jsx(Picker, { multiple: false, oakPath: `$refAttr-picker-${entity}`, entity: entity, title: title, titleLabel: titleLabel, filter: dynamicFilter, sorter: dynamicSorter, projection: dynamicProjection, onSelect: (data) => {
|
||||
onChange(data.map((ele) => ele.id));
|
||||
setVisible(false);
|
||||
} }) })] }));
|
||||
return (<Space>
|
||||
<Input value={renderValue} clearable={!required} onClick={async () => {
|
||||
if (getDynamicSelectors) {
|
||||
// todo 这段代码没测过
|
||||
const { projection: dynamicProjection2, filter: dynamicFilter2, sorter: dynamicSorter2, } = await getDynamicSelectors();
|
||||
if (dynamicFilter2 || filter) {
|
||||
setDynamicFilter(combineFilters(entity, schema, [
|
||||
dynamicFilter2,
|
||||
filter,
|
||||
]));
|
||||
}
|
||||
if (dynamicSorter2 || sorter) {
|
||||
setDynamicSorter(dynamicSorter2 || sorter);
|
||||
}
|
||||
if (dynamicProjection2 || projection) {
|
||||
setDynamicProjection(dynamicProjection2 || projection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (filter) {
|
||||
setDynamicFilter(filter);
|
||||
}
|
||||
if (sorter) {
|
||||
setDynamicSorter(sorter);
|
||||
}
|
||||
if (projection) {
|
||||
setDynamicProjection(projection);
|
||||
}
|
||||
}
|
||||
setVisible(true);
|
||||
}} onChange={(value) => {
|
||||
if (!value) {
|
||||
onChange([]);
|
||||
}
|
||||
}}/>
|
||||
<Popup visible={visibile} closeOnMaskClick={true} onClose={() => {
|
||||
setDynamicFilter(undefined);
|
||||
setDynamicProjection(undefined);
|
||||
setDynamicSorter(undefined);
|
||||
setVisible(false);
|
||||
}} destroyOnClose={true} showCloseButton={true} bodyStyle={{
|
||||
height: '80%',
|
||||
}}>
|
||||
<Picker multiple={false} oakPath={`$refAttr-picker-${entity}`} entity={entity} title={title} titleLabel={titleLabel} filter={dynamicFilter} sorter={dynamicSorter} projection={dynamicProjection} onSelect={(data) => {
|
||||
onChange(data.map((ele) => ele.id));
|
||||
setVisible(false);
|
||||
}}/>
|
||||
</Popup>
|
||||
</Space>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { OakAbsRefAttrPickerRender } from '../../types/AbstractComponent';
|
||||
|
|
@ -16,5 +17,5 @@ export default function render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
onChange: (value: string[]) => void;
|
||||
placeholder: string;
|
||||
schema: StorageSchema<EntityDict & BaseEntityDict>;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Checkbox, Input, Radio, Modal, Space, Select, } from 'antd';
|
||||
import Picker from '../picker';
|
||||
import { combineFilters } from 'oak-domain/lib/store/filter';
|
||||
|
|
@ -12,13 +11,13 @@ export default function render(props) {
|
|||
const [dynamicSorter, setDynamicSorter] = useState(undefined);
|
||||
const [dynamicProjection, setDynamicProjection] = useState(undefined);
|
||||
if (!data && mode !== 'list') {
|
||||
return _jsx("div", { children: " loading... " });
|
||||
return <div> loading... </div>;
|
||||
}
|
||||
else {
|
||||
switch (mode) {
|
||||
case 'select': {
|
||||
const entityId = entityIds && entityIds[0];
|
||||
return (_jsx(Select, { placeholder: placeholder, mode: multiple ? 'multiple' : undefined, value: multiple ? entityIds : entityId, onChange: (value) => {
|
||||
return (<Select placeholder={placeholder} mode={multiple ? 'multiple' : undefined} value={multiple ? entityIds : entityId} onChange={(value) => {
|
||||
if (typeof value === 'string') {
|
||||
onChange([value]);
|
||||
}
|
||||
|
|
@ -28,68 +27,73 @@ export default function render(props) {
|
|||
else if (value instanceof Array) {
|
||||
onChange(value);
|
||||
}
|
||||
}, options: data.map((ele) => ({
|
||||
}} options={data.map((ele) => ({
|
||||
value: ele.id,
|
||||
label: ele.title,
|
||||
})), allowClear: !pickerRender.required }));
|
||||
}))} allowClear={!pickerRender.required}></Select>);
|
||||
}
|
||||
case 'radio': {
|
||||
const entityId = entityIds && entityIds[0];
|
||||
if (multiple) {
|
||||
return (_jsx(Checkbox.Group, { options: data.map((ele) => ({
|
||||
return (<Checkbox.Group options={data.map((ele) => ({
|
||||
value: ele.id,
|
||||
label: ele.title,
|
||||
})), value: entityIds, onChange: (value) => onChange(value) }));
|
||||
}))} value={entityIds} onChange={(value) => onChange(value)}/>);
|
||||
}
|
||||
return (_jsx(Radio.Group, { onChange: ({ target }) => onChange(target.value), value: entityId, options: data.map((ele) => ({
|
||||
return (<Radio.Group onChange={({ target }) => onChange(target.value)} value={entityId} options={data.map((ele) => ({
|
||||
value: ele.id,
|
||||
label: ele.title,
|
||||
})) }));
|
||||
}))}></Radio.Group>);
|
||||
}
|
||||
case 'list': {
|
||||
const { entity, projection, title, titleLabel, filter, sorter, required, getDynamicSelectors, } = pickerRender;
|
||||
return (_jsxs(Space, { children: [_jsx(Input, { placeholder: placeholder, value: renderValue, allowClear: !required, onClick: async () => {
|
||||
if (getDynamicSelectors) {
|
||||
// todo 这段代码没测过
|
||||
const { projection: dynamicProjection2, filter: dynamicFilter2, sorter: dynamicSorter2, } = await getDynamicSelectors();
|
||||
if (dynamicFilter2 || filter) {
|
||||
setDynamicFilter(combineFilters(entity, schema, [
|
||||
dynamicFilter2,
|
||||
filter,
|
||||
]));
|
||||
}
|
||||
if (dynamicSorter2 || sorter) {
|
||||
setDynamicSorter(dynamicSorter2 || sorter);
|
||||
}
|
||||
if (dynamicProjection2 || projection) {
|
||||
setDynamicProjection(dynamicProjection2 || projection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (filter) {
|
||||
setDynamicFilter(filter);
|
||||
}
|
||||
if (sorter) {
|
||||
setDynamicSorter(sorter);
|
||||
}
|
||||
if (projection) {
|
||||
setDynamicProjection(projection);
|
||||
}
|
||||
}
|
||||
setVisible(true);
|
||||
}, onChange: ({ currentTarget }) => {
|
||||
if (!currentTarget.value) {
|
||||
onChange([]);
|
||||
}
|
||||
} }), _jsx(Modal, { title: `选择${t(`${pickerRender.entity}:name`)}`, open: visibile, closable: true, onCancel: () => {
|
||||
setDynamicFilter(undefined);
|
||||
setDynamicProjection(undefined);
|
||||
setDynamicSorter(undefined);
|
||||
setVisible(false);
|
||||
}, destroyOnClose: true, footer: null, children: _jsx(Picker, { multiple: false, oakPath: `$refAttr-picker-${entity}`, entity: entity, title: title, titleLabel: titleLabel, filter: dynamicFilter, sorter: dynamicSorter, projection: dynamicProjection || projection, onSelect: (data) => {
|
||||
onChange(data.map((ele) => ele.id));
|
||||
setVisible(false);
|
||||
} }) })] }));
|
||||
return (<Space>
|
||||
<Input placeholder={placeholder} value={renderValue} allowClear={!required} onClick={async () => {
|
||||
if (getDynamicSelectors) {
|
||||
// todo 这段代码没测过
|
||||
const { projection: dynamicProjection2, filter: dynamicFilter2, sorter: dynamicSorter2, } = await getDynamicSelectors();
|
||||
if (dynamicFilter2 || filter) {
|
||||
setDynamicFilter(combineFilters(entity, schema, [
|
||||
dynamicFilter2,
|
||||
filter,
|
||||
]));
|
||||
}
|
||||
if (dynamicSorter2 || sorter) {
|
||||
setDynamicSorter(dynamicSorter2 || sorter);
|
||||
}
|
||||
if (dynamicProjection2 || projection) {
|
||||
setDynamicProjection(dynamicProjection2 || projection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (filter) {
|
||||
setDynamicFilter(filter);
|
||||
}
|
||||
if (sorter) {
|
||||
setDynamicSorter(sorter);
|
||||
}
|
||||
if (projection) {
|
||||
setDynamicProjection(projection);
|
||||
}
|
||||
}
|
||||
setVisible(true);
|
||||
}} onChange={({ currentTarget }) => {
|
||||
if (!currentTarget.value) {
|
||||
onChange([]);
|
||||
}
|
||||
}}/>
|
||||
<Modal title={`选择${t(`${pickerRender.entity}:name`)}`} open={visibile} closable={true} onCancel={() => {
|
||||
setDynamicFilter(undefined);
|
||||
setDynamicProjection(undefined);
|
||||
setDynamicSorter(undefined);
|
||||
setVisible(false);
|
||||
}} destroyOnClose={true} footer={null}>
|
||||
<Picker multiple={false} oakPath={`$refAttr-picker-${entity}`} entity={entity} title={title} titleLabel={titleLabel} filter={dynamicFilter} sorter={dynamicSorter} projection={dynamicProjection || projection} onSelect={(data) => {
|
||||
onChange(data.map((ele) => ele.id));
|
||||
setVisible(false);
|
||||
}}/>
|
||||
</Modal>
|
||||
</Space>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -23,5 +24,5 @@ export default function render(props: WebComponentProps<ED, 'actionAuth', true,
|
|||
onChange: (checked: boolean, relationId: string, path: string, actionAuth?: ED['actionAuth']['Schema'][]) => void;
|
||||
onChange2: (checked: boolean, relationId: string, paths: string[], actionAuths: ED['actionAuth']['Schema'][], actionAuth?: ED['actionAuth']['Schema']) => void;
|
||||
confirm: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Table, Checkbox, Button, Row, Typography, Space } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
import { difference, intersection } from 'oak-domain/lib/utils/lodash';
|
||||
|
|
@ -6,59 +5,116 @@ import ActionAuthListSingle from '../../relation/single';
|
|||
export default function render(props) {
|
||||
const { cascadeEntityActions, oakDirty, actions, entity, actionAuthList } = props.data;
|
||||
const { onChange, t, clean, confirm, onChange2 } = props.methods;
|
||||
return (_jsxs(Space, { direction: "vertical", style: { width: '100%' }, children: [_jsx(ActionAuthListSingle, { entity: entity }), _jsx(Table, { columns: [
|
||||
{
|
||||
key: '1',
|
||||
title: '源对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { sourceEntity } = record;
|
||||
return sourceEntity;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { paths } = record;
|
||||
return paths.map((ele, index) => {
|
||||
if (index === 0) {
|
||||
return ele;
|
||||
}
|
||||
else {
|
||||
return _jsxs(_Fragment, { children: [_jsx("br", {}), ele] });
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '相关角色',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
// const { relations, actionAuths, path } = record;
|
||||
const { relations, relationSelections } = record;
|
||||
return (_jsx("div", { style: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}, children: relationSelections.map((ele) => {
|
||||
return (<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<ActionAuthListSingle entity={entity}/>
|
||||
<Table columns={[
|
||||
{
|
||||
key: '1',
|
||||
title: '源对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { sourceEntity } = record;
|
||||
return sourceEntity;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { paths } = record;
|
||||
return paths.map((ele, index) => {
|
||||
if (index === 0) {
|
||||
return ele;
|
||||
}
|
||||
else {
|
||||
return <><br />{ele}</>;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '相关角色',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
// const { relations, actionAuths, path } = record;
|
||||
const { relations, relationSelections } = record;
|
||||
return (<div style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
{/* {
|
||||
relations?.map(
|
||||
(r) => {
|
||||
let checked = false, indeterminate = false;
|
||||
if (actions && actions.length > 0) {
|
||||
const relation = relations.find((ele2) => ele2.relationId === ele.id && !ele2.$$deleteAt$$);
|
||||
if (relation) {
|
||||
const { deActions } = relation;
|
||||
checked = difference(actions, deActions).length === 0;
|
||||
indeterminate = !checked && intersection(actions, deActions).length > 0;
|
||||
// filter出对应path的actionAuth来决定relation的check
|
||||
// sort deActions长的在后,不然会影响checked
|
||||
const actionAuthsByPath = actionAuths?.filter((ele) => ele.paths.includes(path[1]))
|
||||
.sort((a, b) => b.deActions.length - a.deActions.length);
|
||||
if (actionAuthsByPath && actions.length > 0) {
|
||||
for (const aa of actionAuthsByPath) {
|
||||
// 1.relationId相同,deActions也要相同
|
||||
// 如果path中存在多对一的情况要使用name进行判断
|
||||
if (!aa.$$deleteAt$$ && (aa.relationId === r.id
|
||||
|| (record.path.includes('$') && aa.relation?.name === r.name))
|
||||
) {
|
||||
const { deActions } = aa;
|
||||
checked = difference(actions, deActions).length === 0;
|
||||
indeterminate = !checked && intersection(actions, deActions).length > 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _jsx(Checkbox, { disabled: actions.length === 0, checked: checked, indeterminate: indeterminate, onChange: ({ target }) => {
|
||||
onChange2(target.checked, ele.id, record.paths, relations);
|
||||
}, children: ele.name });
|
||||
}) }));
|
||||
}
|
||||
}
|
||||
], dataSource: actionAuthList, pagination: false }), _jsxs(Row, { justify: "end", style: { marginTop: 20, padding: 5 }, children: [_jsx(Button, { style: { marginRight: 10 }, type: 'primary', disabled: !oakDirty, onClick: () => confirm(), children: t("confirm") }), _jsx(Button, { disabled: !oakDirty, onClick: () => clean(), children: t("reset") })] })] }));
|
||||
return (
|
||||
<Checkbox
|
||||
disabled={actions.length === 0}
|
||||
checked={checked}
|
||||
indeterminate={indeterminate}
|
||||
onChange={({ target }) => {
|
||||
const { checked } = target;
|
||||
const actionAuths2 = actionAuths?.filter(
|
||||
ele => ele.relationId === r.id || (record.path.includes('$') && ele.relation?.name === r.name)
|
||||
);
|
||||
|
||||
onChange(checked, r.id, path[1], actionAuths2)
|
||||
}}
|
||||
>
|
||||
{r.name}
|
||||
</Checkbox>
|
||||
)
|
||||
}
|
||||
)
|
||||
} */}
|
||||
{relationSelections.map((ele) => {
|
||||
let checked = false, indeterminate = false;
|
||||
if (actions && actions.length > 0) {
|
||||
const relation = relations.find((ele2) => ele2.relationId === ele.id && !ele2.$$deleteAt$$);
|
||||
if (relation) {
|
||||
const { deActions } = relation;
|
||||
checked = difference(actions, deActions).length === 0;
|
||||
indeterminate = !checked && intersection(actions, deActions).length > 0;
|
||||
}
|
||||
}
|
||||
return <Checkbox disabled={actions.length === 0} checked={checked} indeterminate={indeterminate} onChange={({ target }) => {
|
||||
onChange2(target.checked, ele.id, record.paths, relations);
|
||||
}}>
|
||||
{ele.name}
|
||||
</Checkbox>;
|
||||
})}
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
]} dataSource={actionAuthList} pagination={false}/>
|
||||
<Row justify="end" style={{ marginTop: 20, padding: 5 }}>
|
||||
<Button style={{ marginRight: 10 }} type='primary' disabled={!oakDirty} onClick={() => confirm()}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
<Button disabled={!oakDirty} onClick={() => clean()}>
|
||||
{t("reset")}
|
||||
</Button>
|
||||
</Row>
|
||||
</Space>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -13,5 +14,5 @@ export default function render(props: WebComponentProps<ED, 'actionAuth', true,
|
|||
}, {
|
||||
onChange: (actions: string[], path: any, actionAuth?: ED['actionAuth']['OpSchema']) => void;
|
||||
confirm: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,42 +1,61 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { Table, Checkbox, Button, Row } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
export default function render(props) {
|
||||
const { cascadeEntityActions, oakDirty, entity, relationName } = props.data;
|
||||
const { onChange, t, clean, confirm } = props.methods;
|
||||
return (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "center", style: { margin: 20, padding: 10 }, children: [_jsxs(Row, { style: { marginRight: 10 }, children: [_jsx(Title, { level: 4, children: "\u5F53\u524D\u5BF9\u8C61\uFF1A" }), _jsx(Text, { code: true, children: entity })] }), _jsxs(Row, { children: [_jsx(Title, { level: 4, children: "\u5F53\u524D\u89D2\u8272\uFF1A" }), _jsx(Text, { code: true, children: relationName })] })] }), _jsx(Table, { columns: [
|
||||
{
|
||||
key: '1',
|
||||
title: '目标对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path[0];
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path[1];
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const { actions, actionAuth, path } = record;
|
||||
return (_jsx(Checkbox.Group, { style: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}, options: actions, value: actionAuth?.deActions, onChange: (value) => onChange(value, path, actionAuth) }));
|
||||
}
|
||||
}
|
||||
], dataSource: cascadeEntityActions, pagination: false }), _jsxs(Row, { justify: "end", style: { marginTop: 20, padding: 5 }, children: [_jsx(Button, { style: { marginRight: 10 }, type: 'primary', disabled: !oakDirty, onClick: () => confirm(), children: t("confirm") }), _jsx(Button, { disabled: !oakDirty, onClick: () => clean(), children: t("reset") })] })] }));
|
||||
return (<>
|
||||
<Row justify="center" style={{ margin: 20, padding: 10 }}>
|
||||
<Row style={{ marginRight: 10 }}>
|
||||
<Title level={4}>当前对象:</Title>
|
||||
<Text code>{entity}</Text>
|
||||
</Row>
|
||||
<Row>
|
||||
<Title level={4}>当前角色:</Title>
|
||||
<Text code>{relationName}</Text>
|
||||
</Row>
|
||||
</Row>
|
||||
<Table columns={[
|
||||
{
|
||||
key: '1',
|
||||
title: '目标对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path[0];
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path[1];
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const { actions, actionAuth, path } = record;
|
||||
return (<Checkbox.Group style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}} options={actions} value={actionAuth?.deActions} onChange={(value) => onChange(value, path, actionAuth)}/>);
|
||||
}
|
||||
}
|
||||
]} dataSource={cascadeEntityActions} pagination={false}/>
|
||||
<Row justify="end" style={{ marginTop: 20, padding: 5 }}>
|
||||
<Button style={{ marginRight: 10 }} type='primary' disabled={!oakDirty} onClick={() => confirm()}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
<Button disabled={!oakDirty} onClick={() => clean()}>
|
||||
{t("reset")}
|
||||
</Button>
|
||||
</Row>
|
||||
</>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -16,5 +17,5 @@ export default function render(props: WebComponentProps<ED, 'actionAuth', true,
|
|||
entity: keyof ED;
|
||||
openTip: boolean;
|
||||
onClose: () => void;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
}, {}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table, Checkbox, Button, Space, } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
|
|
@ -15,60 +14,70 @@ export default function render(props) {
|
|||
}));
|
||||
setDatasource(tableRows);
|
||||
}, [relations]);
|
||||
return (_jsxs(Space, { direction: "vertical", style: { width: '100%' }, children: [_jsx(Space, { children: _jsx(Text, { style: { fontSize: 16 }, children: "\u6388\u6743" }) }), _jsx(Table, { rowKey: 'relationId', dataSource: datasource, columns: [
|
||||
{
|
||||
width: 200,
|
||||
dataIndex: 'relation',
|
||||
title: '角色',
|
||||
},
|
||||
{
|
||||
dataIndex: 'actions',
|
||||
title: '操作权限',
|
||||
render: (value, row) => {
|
||||
const options = value.map((ele) => ({
|
||||
label: ele,
|
||||
value: ele,
|
||||
}));
|
||||
const actionAuth = rows
|
||||
.filter((ele) => ele.relationId === row.relationId)
|
||||
.sort((a, b) => b.deActions.length - a.deActions.length)?.[0];
|
||||
const defaultValue = actionAuth
|
||||
? actionAuth.deActions
|
||||
: [];
|
||||
return (_jsx(Checkbox.Group, { style: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}, options: options, defaultValue: defaultValue, onChange: (checkedArr) => {
|
||||
const path2 = path.replaceAll('(user)', '');
|
||||
if (!actionAuth) {
|
||||
/* methods.addItem({
|
||||
relationId:
|
||||
row.relationId || '',
|
||||
paths: [path2],
|
||||
deActions:
|
||||
checkedArr as string[],
|
||||
destEntity: entity as string,
|
||||
}); */
|
||||
}
|
||||
else {
|
||||
methods.updateItem({
|
||||
deActions: checkedArr,
|
||||
}, actionAuth.id);
|
||||
}
|
||||
if (!checkedArr.length && actionAuth) {
|
||||
methods.removeItem(actionAuth.id);
|
||||
}
|
||||
} }));
|
||||
},
|
||||
},
|
||||
], pagination: false }), _jsx("div", { style: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
justifyContent: 'flex-end',
|
||||
padding: 8,
|
||||
}, children: _jsx(Button, { disabled: !path, type: "primary", onClick: () => {
|
||||
methods.execute();
|
||||
onClose();
|
||||
}, children: "\u4FDD\u5B58\u5E76\u5173\u95ED" }) })] }));
|
||||
return (<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Space>
|
||||
<Text style={{ fontSize: 16 }}>授权</Text>
|
||||
</Space>
|
||||
<Table rowKey={'relationId'} dataSource={datasource} columns={[
|
||||
{
|
||||
width: 200,
|
||||
dataIndex: 'relation',
|
||||
title: '角色',
|
||||
},
|
||||
{
|
||||
dataIndex: 'actions',
|
||||
title: '操作权限',
|
||||
render: (value, row) => {
|
||||
const options = value.map((ele) => ({
|
||||
label: ele,
|
||||
value: ele,
|
||||
}));
|
||||
const actionAuth = rows
|
||||
.filter((ele) => ele.relationId === row.relationId)
|
||||
.sort((a, b) => b.deActions.length - a.deActions.length)?.[0];
|
||||
const defaultValue = actionAuth
|
||||
? actionAuth.deActions
|
||||
: [];
|
||||
return (<Checkbox.Group style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}} options={options} defaultValue={defaultValue} onChange={(checkedArr) => {
|
||||
const path2 = path.replaceAll('(user)', '');
|
||||
if (!actionAuth) {
|
||||
/* methods.addItem({
|
||||
relationId:
|
||||
row.relationId || '',
|
||||
paths: [path2],
|
||||
deActions:
|
||||
checkedArr as string[],
|
||||
destEntity: entity as string,
|
||||
}); */
|
||||
}
|
||||
else {
|
||||
methods.updateItem({
|
||||
deActions: checkedArr,
|
||||
}, actionAuth.id);
|
||||
}
|
||||
if (!checkedArr.length && actionAuth) {
|
||||
methods.removeItem(actionAuth.id);
|
||||
}
|
||||
}}/>);
|
||||
},
|
||||
},
|
||||
]} pagination={false}></Table>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
justifyContent: 'flex-end',
|
||||
padding: 8,
|
||||
}}>
|
||||
<Button disabled={!path} type="primary" onClick={() => {
|
||||
methods.execute();
|
||||
onClose();
|
||||
}}>
|
||||
保存并关闭
|
||||
</Button>
|
||||
</div>
|
||||
</Space>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
|
|
@ -16,5 +17,5 @@ export default function render(props: WebComponentProps<ED, keyof ED, false, {
|
|||
}, {
|
||||
onActionsSelected: (actions: string[]) => void;
|
||||
onRelationsSelected: (relationIds: string[]) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Row, Col, Tabs, Checkbox } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
|
|
@ -13,20 +12,22 @@ export default function render(props) {
|
|||
{
|
||||
label: 'deduceRelation',
|
||||
key: 'deduceRelation',
|
||||
children: (_jsxs("div", { style: {
|
||||
children: (<div style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: 600,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}, children: ["\u5BF9\u8C61\u7684actionAuth\u5DF2\u88ABdeduce\u5230[", _jsx("b", { children: deduceRelationAttr }), "]\u5C5E\u6027\u4E0A"] }))
|
||||
}}>
|
||||
对象的actionAuth已被deduce到[<b>{deduceRelationAttr}</b>]属性上
|
||||
</div>)
|
||||
},
|
||||
] : [
|
||||
{
|
||||
label: 'actionAuth',
|
||||
key: 'actionAuth',
|
||||
children: (_jsx(ActionAuth, { entity: entity, oakPath: oakFullpath && `${oakFullpath}.actionAuths`, actions: checkedActions }))
|
||||
children: (<ActionAuth entity={entity} oakPath={oakFullpath && `${oakFullpath}.actionAuths`} actions={checkedActions}/>)
|
||||
}
|
||||
];
|
||||
/* if (hasDirectActionAuth) {
|
||||
|
|
@ -76,15 +77,38 @@ export default function render(props) {
|
|||
// }
|
||||
// );
|
||||
// }
|
||||
const ActionSelector = actions && (_jsxs(Row, { style: { width: '100%' }, justify: "center", align: "middle", children: [_jsxs(Text, { strong: true, children: [t('action'), ":"] }), _jsx(Row, { style: { flex: 1, marginLeft: 10 }, justify: "start", align: "middle", wrap: true, children: _jsx(Checkbox.Group, { options: actions, value: checkedActions, onChange: (value) => onActionsSelected(value), style: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
} }) })] }));
|
||||
const RelationSelector = relations && (_jsxs(Row, { style: { width: '100%' }, justify: "center", align: "middle", children: [_jsxs(Text, { strong: true, children: [t('relation'), ":"] }), _jsx(Row, { style: { flex: 1, marginLeft: 10 }, justify: "start", align: "middle", wrap: true, children: _jsx(Checkbox.Group, { options: relations.map(ele => ({ label: ele.name, value: ele.id })), value: relationIds, onChange: (value) => onRelationsSelected(value), style: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
} }) })] }));
|
||||
const ActionSelector = actions && (<Row style={{ width: '100%' }} justify="center" align="middle">
|
||||
<Text strong>{t('action')}:</Text>
|
||||
<Row style={{ flex: 1, marginLeft: 10 }} justify="start" align="middle" wrap>
|
||||
<Checkbox.Group options={actions} value={checkedActions} onChange={(value) => onActionsSelected(value)} style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}}/>
|
||||
</Row>
|
||||
</Row>);
|
||||
const RelationSelector = relations && (<Row style={{ width: '100%' }} justify="center" align="middle">
|
||||
<Text strong>{t('relation')}:</Text>
|
||||
<Row style={{ flex: 1, marginLeft: 10 }} justify="start" align="middle" wrap>
|
||||
<Checkbox.Group options={relations.map(ele => ({ label: ele.name, value: ele.id }))} value={relationIds} onChange={(value) => onRelationsSelected(value)} style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}}/>
|
||||
</Row>
|
||||
</Row>);
|
||||
const showActionSelector = ['actionAuth', 'directActionAuth'].includes(tab);
|
||||
const showRelationSelector = ['relationAuth', 'directRelationAuth'].includes(tab);
|
||||
return (_jsxs("div", { className: Styles.container, children: [_jsxs(Row, { justify: "center", style: { margin: 20, padding: 10, minHeight: 100 }, align: "middle", children: [_jsx(Col, { span: 8, children: _jsxs(Row, { style: { width: '100%' }, justify: "center", align: "middle", children: [_jsxs(Text, { strong: true, children: [t('actionAuth:attr.destEntity'), ":"] }), _jsx(Text, { code: true, style: { marginLeft: 10 }, children: entity })] }) }), _jsx(Col, { span: 12, children: showActionSelector ? ActionSelector : (showRelationSelector && RelationSelector) })] }), _jsx(Tabs, { defaultActiveKey: "1", type: "card", size: "large", items: items, onChange: (key) => setTab(key) })] }));
|
||||
return (<div className={Styles.container}>
|
||||
<Row justify="center" style={{ margin: 20, padding: 10, minHeight: 100 }} align="middle">
|
||||
<Col span={8}>
|
||||
<Row style={{ width: '100%' }} justify="center" align="middle">
|
||||
<Text strong>{t('actionAuth:attr.destEntity')}:</Text>
|
||||
<Text code style={{ marginLeft: 10 }}>{entity}</Text>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
{showActionSelector ? ActionSelector : (showRelationSelector && RelationSelector)}
|
||||
</Col>
|
||||
</Row>
|
||||
<Tabs defaultActiveKey="1" type="card" size="large" items={items} onChange={(key) => setTab(key)}/>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -14,5 +15,5 @@ export default function render(props: WebComponentProps<ED, keyof ED, true, {
|
|||
}>;
|
||||
}, {
|
||||
onEntityClicked: (entity: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Switch, Input, Form } from 'antd';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import { useState } from 'react';
|
||||
|
|
@ -37,54 +36,68 @@ export default function render(props) {
|
|||
});
|
||||
}
|
||||
}
|
||||
return (_jsxs("div", { className: Styles.container, children: [_jsxs(Form, { style: {
|
||||
margin: 20,
|
||||
}, children: [_jsx(Form.Item, { label: "filter", children: _jsx(_Fragment, { children: _jsx(Input, { onChange: ({ currentTarget }) => setSearch(currentTarget.value), allowClear: true }) }) }), _jsx(Form.Item, { label: "strict mode", children: _jsx(_Fragment, { children: _jsx(Switch, { checked: strict, onChange: (checked) => setStrict(checked) }) }) })] }), _jsx(ReactEcharts, { style: { width: '100%', height: '100%', minHeight: 750 }, option: {
|
||||
tooltip: {},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
force: {
|
||||
initLayout: 'circular',
|
||||
gravity: 0,
|
||||
repulsion: [10, 80],
|
||||
edgeLength: [10, 50]
|
||||
},
|
||||
data: data2,
|
||||
links: links2,
|
||||
lineStyle: {
|
||||
opacity: 0.9,
|
||||
width: 2,
|
||||
curveness: 0
|
||||
},
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
autoCurveness: true,
|
||||
roam: true,
|
||||
draggable: true,
|
||||
edgeSymbol: ['none', 'arrow'],
|
||||
edgeSymbolSize: 7,
|
||||
emphasis: {
|
||||
scale: true,
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
width: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
}, notMerge: true, lazyUpdate: false, onEvents: {
|
||||
click: (info) => {
|
||||
const { data, dataType } = info;
|
||||
if (dataType === 'node') {
|
||||
const { name } = data;
|
||||
onEntityClicked(name);
|
||||
}
|
||||
return (<div className={Styles.container}>
|
||||
<Form style={{
|
||||
margin: 20,
|
||||
}}>
|
||||
<Form.Item label="filter">
|
||||
<>
|
||||
<Input onChange={({ currentTarget }) => setSearch(currentTarget.value)} allowClear/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="strict mode">
|
||||
<>
|
||||
<Switch checked={strict} onChange={(checked) => setStrict(checked)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<ReactEcharts style={{ width: '100%', height: '100%', minHeight: 750 }} option={{
|
||||
tooltip: {},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
force: {
|
||||
initLayout: 'circular',
|
||||
gravity: 0,
|
||||
repulsion: [10, 80],
|
||||
edgeLength: [10, 50]
|
||||
},
|
||||
} })] }));
|
||||
data: data2,
|
||||
links: links2,
|
||||
lineStyle: {
|
||||
opacity: 0.9,
|
||||
width: 2,
|
||||
curveness: 0
|
||||
},
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
autoCurveness: true,
|
||||
roam: true,
|
||||
draggable: true,
|
||||
edgeSymbol: ['none', 'arrow'],
|
||||
edgeSymbolSize: 7,
|
||||
emphasis: {
|
||||
scale: true,
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
width: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
}} notMerge={true} lazyUpdate={false} onEvents={{
|
||||
click: (info) => {
|
||||
const { data, dataType } = info;
|
||||
if (dataType === 'node') {
|
||||
const { name } = data;
|
||||
onEntityClicked(name);
|
||||
}
|
||||
},
|
||||
}}/>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { RowWithActions, WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -9,5 +10,5 @@ export default function render(props: WebComponentProps<ED, 'relation', true, {
|
|||
onClicked: (relationId: string) => any;
|
||||
}, {
|
||||
setEntityFilter: (filter: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): import("react").JSX.Element | null;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { List, Tag, Input } from 'antd-mobile';
|
||||
import Styles from './web.module.less';
|
||||
export default function render(props) {
|
||||
const { entities, entity, relations, onClicked } = props.data;
|
||||
const { t, setEntityFilter } = props.methods;
|
||||
if (entities) {
|
||||
return (_jsxs(_Fragment, { children: [!entity &&
|
||||
_jsx(_Fragment, { children: _jsx("div", { className: Styles.inputDiv, children: _jsx(Input, { placeholder: t('searchTip'), clearable: true, onChange: (val) => setEntityFilter(val) }) }) }), entities.map((e) => {
|
||||
const rs = relations.filter(ele => ele.entity === e);
|
||||
return (_jsx(List, { header: t(`${e}:name`) + ` (${e})`, children: rs.map((r) => (_jsx(List.Item, { extra: r.entityId && _jsx(Tag, { color: 'primary', fill: 'outline', children: t('hasEntityId') }), onClick: () => onClicked(r.id), children: t(`${e}:r.${r.name}`) + ` (${r.name})` }))) }));
|
||||
})] }));
|
||||
return (<>
|
||||
{!entity &&
|
||||
<>
|
||||
<div className={Styles.inputDiv}>
|
||||
<Input placeholder={t('searchTip')} clearable onChange={(val) => setEntityFilter(val)}/>
|
||||
</div>
|
||||
</>}
|
||||
{entities.map((e) => {
|
||||
const rs = relations.filter(ele => ele.entity === e);
|
||||
return (<List header={t(`${e}:name`) + ` (${e})`}>
|
||||
{rs.map((r) => (<List.Item extra={r.entityId && <Tag color='primary' fill='outline'>{t('hasEntityId')}</Tag>} onClick={() => onClicked(r.id)}>
|
||||
{t(`${e}:r.${r.name}`) + ` (${r.name})`}
|
||||
</List.Item>))}
|
||||
</List>);
|
||||
})}
|
||||
</>);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { RowWithActions, WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -9,5 +10,5 @@ export default function render(props: WebComponentProps<ED, 'relation', true, {
|
|||
onClicked: (relationId: string) => any;
|
||||
}, {
|
||||
setEntityFilter: (filter: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
}>): React.JSX.Element | null;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,26 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Card, Button, Input } from 'antd';
|
||||
import Styles from './web.pc.module.less';
|
||||
export default function render(props) {
|
||||
const { entities, entity, relations, onClicked } = props.data;
|
||||
const { t, setEntityFilter } = props.methods;
|
||||
if (entities) {
|
||||
return (_jsxs(_Fragment, { children: [!entity &&
|
||||
_jsx(_Fragment, { children: _jsx("div", { className: Styles.inputDiv, children: _jsx(Input, { placeholder: t('searchTip'), allowClear: true, onChange: ({ currentTarget }) => setEntityFilter(currentTarget.value) }) }) }), entities.map((e) => {
|
||||
const rs = relations.filter(ele => ele.entity === e);
|
||||
return (_jsx(Card, { title: t(`${e}:name`) + ` (${e})`, style: { margin: 10 }, children: rs.map((r) => (_jsx(Button, { type: r.entityId ? 'primary' : 'link', onClick: () => onClicked(r.id), children: t(`${e}:r.${r.name}`) + ` (${r.name})` }))) }));
|
||||
})] }));
|
||||
return (<>
|
||||
{!entity &&
|
||||
<>
|
||||
<div className={Styles.inputDiv}>
|
||||
<Input placeholder={t('searchTip')} allowClear onChange={({ currentTarget }) => setEntityFilter(currentTarget.value)}/>
|
||||
</div>
|
||||
</>}
|
||||
{entities.map((e) => {
|
||||
const rs = relations.filter(ele => ele.entity === e);
|
||||
return (<Card title={t(`${e}:name`) + ` (${e})`} style={{ margin: 10 }}>
|
||||
{rs.map((r) => (<Button type={r.entityId ? 'primary' : 'link'} onClick={() => onClicked(r.id)}>
|
||||
{t(`${e}:r.${r.name}`) + ` (${r.name})`}
|
||||
</Button>))}
|
||||
</Card>);
|
||||
})}
|
||||
</>);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -10,5 +11,5 @@ export default function render(props: WebComponentProps<ED, 'relationAuth', true
|
|||
}, {
|
||||
onChange: (checked: boolean, relationId: string, path: string, relationAuths?: ED['relationAuth']['OpSchema'][]) => void;
|
||||
confirm: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { Table, Checkbox, Button, Row } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
|
|
@ -6,52 +5,66 @@ import { intersection, difference } from 'oak-domain/lib/utils/lodash';
|
|||
export default function render(props) {
|
||||
const { relationIds, relationAuths, oakDirty, auths, sourceRelations } = props.data;
|
||||
const { onChange, t, clean, confirm } = props.methods;
|
||||
return (_jsxs(_Fragment, { children: [_jsx(Table, { columns: [
|
||||
{
|
||||
key: '1',
|
||||
title: t('relationAuth:attr.sourceEntity'),
|
||||
width: 100,
|
||||
render: (value, record) => record[2],
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: t('relationAuth:attr.path'),
|
||||
width: 200,
|
||||
render: (value, record) => record[1],
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: t('grantedRoles'),
|
||||
key: 'roles',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const sourceEntity = record[2];
|
||||
const relations = sourceRelations.filter(ele => ele.entity === sourceEntity && !relationIds.includes(ele.id));
|
||||
return (_jsx("div", { style: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}, children: relations?.map((r) => {
|
||||
const disabled = relationIds.length === 0;
|
||||
let checked = false, indeterminate = false;
|
||||
if (!disabled && relationAuths) {
|
||||
const includedRelationIds = [];
|
||||
for (const auth of relationAuths) {
|
||||
if (!auth.$$deleteAt$$ && auth.sourceRelationId === r.id /* && auth.path === record[1] */) {
|
||||
includedRelationIds.push(auth.destRelationId);
|
||||
}
|
||||
}
|
||||
checked = difference(relationIds, includedRelationIds).length === 0;
|
||||
indeterminate = !checked && intersection(relationIds, includedRelationIds).length > 0;
|
||||
return (<>
|
||||
<Table columns={[
|
||||
{
|
||||
key: '1',
|
||||
title: t('relationAuth:attr.sourceEntity'),
|
||||
width: 100,
|
||||
render: (value, record) => record[2],
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: t('relationAuth:attr.path'),
|
||||
width: 200,
|
||||
render: (value, record) => record[1],
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: t('grantedRoles'),
|
||||
key: 'roles',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const sourceEntity = record[2];
|
||||
const relations = sourceRelations.filter(ele => ele.entity === sourceEntity && !relationIds.includes(ele.id));
|
||||
return (<div style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
{relations?.map((r) => {
|
||||
const disabled = relationIds.length === 0;
|
||||
let checked = false, indeterminate = false;
|
||||
if (!disabled && relationAuths) {
|
||||
const includedRelationIds = [];
|
||||
for (const auth of relationAuths) {
|
||||
if (!auth.$$deleteAt$$ && auth.sourceRelationId === r.id /* && auth.path === record[1] */) {
|
||||
includedRelationIds.push(auth.destRelationId);
|
||||
}
|
||||
return (_jsx(Checkbox, { disabled: disabled, checked: checked, indeterminate: indeterminate, onChange: ({ target }) => {
|
||||
const { checked } = target;
|
||||
const refRelationAuths = relationAuths?.filter(ele => ele.sourceRelationId === r.id /*&& ele.path === record[1] */
|
||||
&& relationIds.includes(ele.destRelationId));
|
||||
onChange(checked, r.id, record[1], refRelationAuths);
|
||||
}, children: r.name }));
|
||||
}) }));
|
||||
}
|
||||
}
|
||||
], dataSource: auths, pagination: false }), _jsxs(Row, { justify: "end", style: { marginTop: 20, padding: 5 }, children: [_jsx(Button, { style: { marginRight: 10 }, type: 'primary', disabled: !oakDirty, onClick: () => confirm(), children: t("confirm") }), _jsx(Button, { disabled: !oakDirty, onClick: () => clean(), children: t("reset") })] })] }));
|
||||
}
|
||||
checked = difference(relationIds, includedRelationIds).length === 0;
|
||||
indeterminate = !checked && intersection(relationIds, includedRelationIds).length > 0;
|
||||
}
|
||||
return (<Checkbox disabled={disabled} checked={checked} indeterminate={indeterminate} onChange={({ target }) => {
|
||||
const { checked } = target;
|
||||
const refRelationAuths = relationAuths?.filter(ele => ele.sourceRelationId === r.id /*&& ele.path === record[1] */
|
||||
&& relationIds.includes(ele.destRelationId));
|
||||
onChange(checked, r.id, record[1], refRelationAuths);
|
||||
}}>
|
||||
{r.name}
|
||||
</Checkbox>);
|
||||
})}
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
]} dataSource={auths} pagination={false}/>
|
||||
<Row justify="end" style={{ marginTop: 20, padding: 5 }}>
|
||||
<Button style={{ marginRight: 10 }} type='primary' disabled={!oakDirty} onClick={() => confirm()}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
<Button disabled={!oakDirty} onClick={() => clean()}>
|
||||
{t("reset")}
|
||||
</Button>
|
||||
</Row>
|
||||
</>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
|
|
@ -14,5 +15,5 @@ export default function render(props: WebComponentProps<ED, 'relationAuth', true
|
|||
}, {
|
||||
onChange: (relationId: string, checked: boolean, relationAuthId?: string, path?: string) => void;
|
||||
confirm: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,72 +1,98 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Table, Checkbox, Button, Row } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
export default function render(props) {
|
||||
const { cascadeEntityRelations, oakDirty, entity, relationName } = props.data;
|
||||
const { onChange, t, clean, confirm } = props.methods;
|
||||
return (_jsxs("div", { style: {
|
||||
return (<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch',
|
||||
width: '100%'
|
||||
}, children: [_jsxs(Row, { justify: "center", style: { margin: 20, padding: 10 }, children: [_jsxs(Row, { style: { marginRight: 10 }, children: [_jsx(Title, { level: 4, children: "\u5F53\u524D\u5BF9\u8C61\uFF1A" }), _jsx(Text, { code: true, children: entity })] }), _jsxs(Row, { children: [_jsx(Title, { level: 4, children: "\u5F53\u524D\u89D2\u8272\uFF1A" }), _jsx(Text, { code: true, children: relationName })] })] }), _jsx(Table, { columns: [
|
||||
{
|
||||
key: '1',
|
||||
title: '对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { entity } = record;
|
||||
return entity;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path;
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '角色',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const { relations, authedRelations, path } = record;
|
||||
// 可能存在定制的relation
|
||||
const customizedRelationsAuthed = [];
|
||||
const relationIdAuthed = [];
|
||||
authedRelations.forEach((ele) => {
|
||||
if (!ele.$$deleteAt$$) {
|
||||
if (relations.find(ele2 => ele2.id === ele.destRelationId)) {
|
||||
relationIdAuthed.push(ele.destRelationId);
|
||||
}}>
|
||||
<Row justify="center" style={{ margin: 20, padding: 10 }}>
|
||||
<Row style={{ marginRight: 10 }}>
|
||||
<Title level={4}>当前对象:</Title>
|
||||
<Text code>{entity}</Text>
|
||||
</Row>
|
||||
<Row>
|
||||
<Title level={4}>当前角色:</Title>
|
||||
<Text code>{relationName}</Text>
|
||||
</Row>
|
||||
</Row>
|
||||
<Table columns={[
|
||||
{
|
||||
key: '1',
|
||||
title: '对象',
|
||||
width: 100,
|
||||
render: (value, record) => {
|
||||
const { entity } = record;
|
||||
return entity;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
title: '路径',
|
||||
width: 200,
|
||||
render: (value, record) => {
|
||||
const { path } = record;
|
||||
return path;
|
||||
},
|
||||
},
|
||||
{
|
||||
fixed: 'right',
|
||||
title: '角色',
|
||||
key: 'operation',
|
||||
width: 300,
|
||||
render: (value, record) => {
|
||||
const { relations, authedRelations, path } = record;
|
||||
// 可能存在定制的relation
|
||||
const customizedRelationsAuthed = [];
|
||||
const relationIdAuthed = [];
|
||||
authedRelations.forEach((ele) => {
|
||||
if (!ele.$$deleteAt$$) {
|
||||
if (relations.find(ele2 => ele2.id === ele.destRelationId)) {
|
||||
relationIdAuthed.push(ele.destRelationId);
|
||||
}
|
||||
else {
|
||||
customizedRelationsAuthed.push(ele.destRelation);
|
||||
}
|
||||
}
|
||||
});
|
||||
return (<div style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
{relations.map((ele) => {
|
||||
const authed = relationIdAuthed.includes(ele.id);
|
||||
return (<Checkbox key={ele.id} checked={authed} onChange={({ target }) => {
|
||||
const { checked } = target;
|
||||
const relationAuth = authedRelations.find(ele2 => ele2.destRelationId === ele.id);
|
||||
if (relationAuth) {
|
||||
onChange(ele.id, checked, relationAuth.id);
|
||||
}
|
||||
else {
|
||||
customizedRelationsAuthed.push(ele.destRelation);
|
||||
onChange(ele.id, checked, undefined, path);
|
||||
}
|
||||
}
|
||||
});
|
||||
return (_jsxs("div", { style: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
}, children: [relations.map((ele) => {
|
||||
const authed = relationIdAuthed.includes(ele.id);
|
||||
return (_jsx(Checkbox, { checked: authed, onChange: ({ target }) => {
|
||||
const { checked } = target;
|
||||
const relationAuth = authedRelations.find(ele2 => ele2.destRelationId === ele.id);
|
||||
if (relationAuth) {
|
||||
onChange(ele.id, checked, relationAuth.id);
|
||||
}
|
||||
else {
|
||||
onChange(ele.id, checked, undefined, path);
|
||||
}
|
||||
}, children: ele.display || ele.name }, ele.id));
|
||||
}), customizedRelationsAuthed.map((ele) => _jsx(Checkbox, { checked: true, disabled: true, children: ele.display || ele.name }, ele.id))] }));
|
||||
}
|
||||
}
|
||||
], dataSource: cascadeEntityRelations, pagination: false }), _jsxs(Row, { justify: "end", style: { marginTop: 20, padding: 5 }, children: [_jsx(Button, { style: { marginRight: 10 }, type: 'primary', disabled: !oakDirty, onClick: () => confirm(), children: t("confirm") }), _jsx(Button, { disabled: !oakDirty, onClick: () => clean(), children: t("reset") })] })] }));
|
||||
}}>
|
||||
{ele.display || ele.name}
|
||||
</Checkbox>);
|
||||
})}
|
||||
{customizedRelationsAuthed.map((ele) => <Checkbox key={ele.id} checked={true} disabled={true}>
|
||||
{ele.display || ele.name}
|
||||
</Checkbox>)}
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
]} dataSource={cascadeEntityRelations} pagination={false}/>
|
||||
<Row justify="end" style={{ marginTop: 20, padding: 5 }}>
|
||||
<Button style={{ marginRight: 10 }} type='primary' disabled={!oakDirty} onClick={() => confirm()}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
<Button disabled={!oakDirty} onClick={() => clean()}>
|
||||
{t("reset")}
|
||||
</Button>
|
||||
</Row>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="react" />
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { WebComponentProps } from '../../../types/Page';
|
||||
|
|
@ -10,5 +11,5 @@ export default function render(props: WebComponentProps<ED, keyof ED, false, {
|
|||
getNodes: (entity: keyof ED) => void;
|
||||
checkSelectRelation: () => boolean;
|
||||
resolveP: (path: string) => string;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): import("react").JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { Row, Col, Space, Button, Modal, Breadcrumb, Tag } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
const { Title, Text } = Typography;
|
||||
|
|
@ -10,42 +9,91 @@ export default function render(props) {
|
|||
const { getNodes, checkSelectRelation, resolveP } = methods;
|
||||
const [open, setOpen] = useState(false);
|
||||
const [breadcrumbItems, setBreadcrumbItems] = useState([]);
|
||||
return (_jsxs(Space, { direction: "vertical", style: { width: '100%' }, children: [_jsx(Button, { onClick: () => setOpen(true), children: "\u8BBE\u7F6E" }), _jsx(Modal, { title: `权限设置`, open: open, destroyOnClose: true, footer: null, onCancel: () => {
|
||||
setBreadcrumbItems([]);
|
||||
setOpen(false);
|
||||
}, width: 900, children: _jsxs(Space, { direction: "vertical", style: { width: '100%', marginTop: 16 }, size: 16, children: [_jsxs(Space, { direction: "vertical", children: [_jsx(Text, { style: { fontSize: 16 }, children: "\u8DEF\u5F84" }), _jsx(Space, { style: { width: '100%' }, wrap: true, children: (breadcrumbItems && breadcrumbItems.length > 0) ? (_jsxs(_Fragment, { children: [_jsx(Breadcrumb, { items: breadcrumbItems.map((ele, index) => ({
|
||||
title: (_jsx("a", { onClick: () => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
const newItems = breadcrumbItems.slice(0, index + 1);
|
||||
setBreadcrumbItems(newItems);
|
||||
const entity = ele.includes('$') ? ele.split('$')[0] : ele;
|
||||
getNodes(entity);
|
||||
}, children: ele }))
|
||||
})) }), _jsx(Button, { size: "small", type: "link", onClick: () => {
|
||||
setBreadcrumbItems([]);
|
||||
getNodes(entity);
|
||||
}, children: "\u6E05\u7A7A" })] })) : (_jsx(Text, { type: "secondary", children: "\u8BF7\u5148\u9009\u62E9\u7ED3\u70B9" })) })] }), _jsx(Space, { direction: "vertical", style: { width: '100%' }, children: _jsxs(Space, { direction: "vertical", style: { width: '100%' }, children: [_jsx(Text, { style: { fontSize: 16 }, children: "\u7ED3\u70B9" }), _jsxs(Row, { gutter: 24, children: [_jsx(Col, { span: 2, children: _jsx(Text, { style: { whiteSpace: 'nowrap' }, children: "\u5916\u952E" }) }), _jsx(Col, { span: 22, children: _jsx(Space, { wrap: true, children: entityDNode.map((ele) => (_jsx(Tag, { style: { cursor: 'pointer' }, color: "processing", bordered: false, onClick: () => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
breadcrumbItems.push(ele);
|
||||
setBreadcrumbItems(breadcrumbItems);
|
||||
const path = breadcrumbItems.join('.');
|
||||
const entity = resolveP(path);
|
||||
getNodes(entity);
|
||||
}, children: ele }))) }) })] }), _jsxs(Row, { gutter: 24, children: [_jsx(Col, { span: 2, children: _jsx(Text, { style: { whiteSpace: 'nowrap', marginRight: 16 }, children: "\u53CD\u6307\u7ED3\u70B9" }) }), _jsx(Col, { span: 22, children: _jsx(Space, { wrap: true, children: entitySNode.map((ele) => (_jsx(Tag, { style: { cursor: 'pointer' }, color: "cyan", bordered: false, onClick: () => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
const preNode = breadcrumbItems[breadcrumbItems.length - 1] || entity;
|
||||
const parentEntity = preNode.includes('$') ? preNode.split('$')[0] : preNode;
|
||||
breadcrumbItems.push(`${ele}$${parentEntity}`);
|
||||
setBreadcrumbItems(breadcrumbItems);
|
||||
getNodes(ele);
|
||||
}, children: ele }))) }) })] })] }) }), _jsx(ActionAuthList, { oakPath: "$actionAuthList-cpn", entity: entity, path: breadcrumbItems.join('.'), onClose: () => {
|
||||
setBreadcrumbItems([]);
|
||||
setOpen(false);
|
||||
}, oakAutoUnmount: true })] }) })] }));
|
||||
return (<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Button onClick={() => setOpen(true)}>设置</Button>
|
||||
<Modal title={`权限设置`} open={open} destroyOnClose={true} footer={null} onCancel={() => {
|
||||
setBreadcrumbItems([]);
|
||||
setOpen(false);
|
||||
}} width={900}>
|
||||
<Space direction="vertical" style={{ width: '100%', marginTop: 16 }} size={16}>
|
||||
<Space direction="vertical">
|
||||
<Text style={{ fontSize: 16 }}>路径</Text>
|
||||
<Space style={{ width: '100%' }} wrap>
|
||||
{(breadcrumbItems && breadcrumbItems.length > 0) ? (<>
|
||||
<Breadcrumb items={breadcrumbItems.map((ele, index) => ({
|
||||
title: (<a onClick={() => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
const newItems = breadcrumbItems.slice(0, index + 1);
|
||||
setBreadcrumbItems(newItems);
|
||||
const entity = ele.includes('$') ? ele.split('$')[0] : ele;
|
||||
getNodes(entity);
|
||||
}}>
|
||||
{ele}
|
||||
</a>)
|
||||
}))}/>
|
||||
<Button size="small" type="link" onClick={() => {
|
||||
setBreadcrumbItems([]);
|
||||
getNodes(entity);
|
||||
}}>
|
||||
清空
|
||||
</Button>
|
||||
</>) : (<Text type="secondary">请先选择结点</Text>)}
|
||||
</Space>
|
||||
</Space>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Text style={{ fontSize: 16 }}>结点</Text>
|
||||
<Row gutter={24}>
|
||||
<Col span={2}>
|
||||
<Text style={{ whiteSpace: 'nowrap' }}>外键</Text>
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<Space wrap>
|
||||
{entityDNode.map((ele) => (<Tag style={{ cursor: 'pointer' }} color="processing" bordered={false} onClick={() => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
breadcrumbItems.push(ele);
|
||||
setBreadcrumbItems(breadcrumbItems);
|
||||
const path = breadcrumbItems.join('.');
|
||||
const entity = resolveP(path);
|
||||
getNodes(entity);
|
||||
}}>
|
||||
{ele}
|
||||
</Tag>))}
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={2}>
|
||||
<Text style={{ whiteSpace: 'nowrap', marginRight: 16 }}>反指结点</Text>
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<Space wrap>
|
||||
{entitySNode.map((ele) => (<Tag style={{ cursor: 'pointer' }} color={"cyan"} bordered={false} onClick={() => {
|
||||
if (checkSelectRelation()) {
|
||||
return;
|
||||
}
|
||||
const preNode = breadcrumbItems[breadcrumbItems.length - 1] || entity;
|
||||
const parentEntity = preNode.includes('$') ? preNode.split('$')[0] : preNode;
|
||||
breadcrumbItems.push(`${ele}$${parentEntity}`);
|
||||
setBreadcrumbItems(breadcrumbItems);
|
||||
getNodes(ele);
|
||||
}}>
|
||||
{ele}
|
||||
</Tag>))}
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</Space>
|
||||
</Space>
|
||||
<ActionAuthList oakPath="$actionAuthList-cpn" entity={entity} path={breadcrumbItems.join('.')} onClose={() => {
|
||||
setBreadcrumbItems([]);
|
||||
setOpen(false);
|
||||
}} oakAutoUnmount={true}/>
|
||||
</Space>
|
||||
</Modal>
|
||||
</Space>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
|
|
@ -8,4 +9,4 @@ export default function Render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
searchChange: (value: string) => void;
|
||||
searchConfirm: (value: string) => void;
|
||||
searchClear: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { SearchBar } from 'antd-mobile';
|
||||
export default function Render(props) {
|
||||
const { methods, data } = props;
|
||||
const { t, searchChange, searchConfirm, searchClear } = methods;
|
||||
const { searchValue, placeholder = '请输入' } = data;
|
||||
return (_jsx(SearchBar, { value: searchValue, placeholder: placeholder, showCancelButton: true, onChange: searchChange, onSearch: searchConfirm, onClear: () => searchClear() }));
|
||||
return (<SearchBar value={searchValue} placeholder={placeholder} showCancelButton onChange={searchChange} onSearch={searchConfirm} onClear={() => searchClear()}/>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { WebComponentProps } from '../../types/Page';
|
||||
import { ED } from '../../types/AbstractComponent';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
|
|
@ -6,4 +7,4 @@ export default function Render(props: WebComponentProps<ED, keyof EntityDict, fa
|
|||
}, {
|
||||
searchChange: (value: string) => void;
|
||||
searchConfirm: (value: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { Input, } from 'antd';
|
||||
const { Search } = Input;
|
||||
export default function Render(props) {
|
||||
const { methods, data } = props;
|
||||
const { t, searchChange, searchConfirm } = methods;
|
||||
const { searchValue, oakLoading, } = data;
|
||||
return (_jsx(Search, { loading: oakLoading, value: searchValue, onChange: ({ target: { value } }) => searchChange(value), onSearch: (value) => searchConfirm(value), placeholder: "", allowClear: true }));
|
||||
return (<Search loading={oakLoading} value={searchValue} onChange={({ target: { value } }) => searchChange(value)} onSearch={(value) => searchConfirm(value)} placeholder="" allowClear/>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
type ED = EntityDict & BaseEntityDict;
|
||||
|
|
@ -10,5 +11,5 @@ export default function render<T extends keyof ED>(props: WebComponentProps<ED,
|
|||
layout?: 'horizontal' | 'vertical';
|
||||
mode?: 'default' | 'card';
|
||||
children: any;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, TextArea, DatePicker, Grid, Popup, Radio, Stepper, Switch, Button, } from 'antd-mobile';
|
||||
import OakIcon from '../icon';
|
||||
import RefAttr from '../refAttr';
|
||||
|
|
@ -16,17 +15,17 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
case 'varchar':
|
||||
case 'char':
|
||||
case 'poiName': {
|
||||
return (_jsx(Input, { clearable: !required, placeholder: placeholder || `请输入${label}`, value: value, defaultValue: defaultValue, maxLength: maxLength, onChange: (value) => {
|
||||
return (<Input clearable={!required} placeholder={placeholder || `请输入${label}`} value={value} defaultValue={defaultValue} maxLength={maxLength} onChange={(value) => {
|
||||
onValueChange(value);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'text': {
|
||||
return (_jsx(TextArea, { autoSize: true, placeholder: `请输入${label}`, defaultValue: defaultValue, value: value || '', rows: 6, showCount: true, maxLength: maxLength || 1000, onChange: (value) => {
|
||||
return (<TextArea autoSize={true} placeholder={`请输入${label}`} defaultValue={defaultValue} value={value || ''} rows={6} showCount={true} maxLength={maxLength || 1000} onChange={(value) => {
|
||||
onValueChange(value);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'int': {
|
||||
return (_jsx(Stepper, { min: min, max: max, defaultValue: defaultValue, value: value, digits: 0, onChange: (value) => onValueChange(value) }));
|
||||
return (<Stepper min={min} max={max} defaultValue={defaultValue} value={value} digits={0} onChange={(value) => onValueChange(value)}/>);
|
||||
}
|
||||
case 'decimal': {
|
||||
const precision = params?.precision || 10;
|
||||
|
|
@ -36,13 +35,13 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
const threshold = Math.pow(10, precision - scale);
|
||||
const max = threshold - scaleValue; // 小数在这里可能会有bug
|
||||
const min = 0 - max; */
|
||||
return (_jsx(Stepper, { min: min, max: max, defaultValue: defaultValue, value: value, digits: scale, step: scaleValue, onChange: (value) => onValueChange(value) }));
|
||||
return (<Stepper min={min} max={max} defaultValue={defaultValue} value={value} digits={scale} step={scaleValue} onChange={(value) => onValueChange(value)}/>);
|
||||
}
|
||||
case 'money': {
|
||||
// money在数据上统一用分来存储
|
||||
const valueShowed = parseFloat((value / 100).toFixed(2));
|
||||
const defaultValueShowed = parseFloat((defaultValue / 100).toFixed(2));
|
||||
return (_jsx(Stepper, { min: 0, defaultValue: defaultValueShowed, value: valueShowed, digits: 2, step: 0.01, formatter: value => `¥ ${value}`, parser: text => parseFloat(text.replace('¥', '')), onChange: (value) => {
|
||||
return (<Stepper min={0} defaultValue={defaultValueShowed} value={valueShowed} digits={2} step={0.01} formatter={value => `¥ ${value}`} parser={text => parseFloat(text.replace('¥', ''))} onChange={(value) => {
|
||||
if (value !== null) {
|
||||
const v2 = Math.round(value * 100);
|
||||
onValueChange(v2);
|
||||
|
|
@ -50,57 +49,83 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
else {
|
||||
onValueChange(value);
|
||||
}
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'datetime':
|
||||
case 'date': {
|
||||
const precision = type === 'date' ? 'day' : 'second';
|
||||
const format = type === 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss';
|
||||
return (_jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [_jsx(DatePicker, { visible: dt, onClose: () => setDt(false), precision: precision, value: new Date(value), defaultValue: new Date(), min: min ? new Date(min) : undefined, max: max ? new Date(max) : undefined, children: value => dayjs(value).format(format) }), _jsx(Button, { onClick: () => setDt(true), children: type === 'date' ? t('chooseDate') : t('chooseDatetime') })] }));
|
||||
return (<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<DatePicker visible={dt} onClose={() => setDt(false)} precision={precision} value={new Date(value)} defaultValue={new Date()} min={min ? new Date(min) : undefined} max={max ? new Date(max) : undefined}>
|
||||
{value => dayjs(value).format(format)}
|
||||
</DatePicker>
|
||||
<Button onClick={() => setDt(true)}>
|
||||
{type === 'date' ? t('chooseDate') : t('chooseDatetime')}
|
||||
</Button>
|
||||
</div>);
|
||||
}
|
||||
case 'time': {
|
||||
return (_jsx("div", { children: "\u5F85\u5B9E\u73B0" }));
|
||||
return (<div>待实现</div>);
|
||||
}
|
||||
case 'boolean': {
|
||||
return (_jsx(Switch, { checkedText: _jsx(OakIcon, { name: "right" }), uncheckedText: _jsx(OakIcon, { name: "close" }), checked: value, onChange: (checked) => {
|
||||
return (<Switch checkedText={<OakIcon name="right"/>} uncheckedText={<OakIcon name="close"/>} checked={value} onChange={(checked) => {
|
||||
onValueChange(checked);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'enum': {
|
||||
return (_jsx(Radio.Group, { value: value, onChange: (value) => onValueChange(value), children: enumeration.map(({ label, value }) => (_jsx(Radio, { value: value, children: t(label) }))) }));
|
||||
return (<Radio.Group value={value} onChange={(value) => onValueChange(value)}>
|
||||
{enumeration.map(({ label, value }) => (<Radio value={value}>{t(label)}</Radio>))}
|
||||
</Radio.Group>);
|
||||
}
|
||||
case 'ref': {
|
||||
return (_jsx(RefAttr, { multiple: false, entityId: value, pickerRender: attrRender, onChange: (value) => { onValueChange(value[0]); } }));
|
||||
return (<RefAttr multiple={false} entityId={value} pickerRender={attrRender} onChange={(value) => { onValueChange(value[0]); }}/>);
|
||||
}
|
||||
case 'coordinate': {
|
||||
const { coordinate } = value || {};
|
||||
const { extra } = attrRender;
|
||||
const poiNameAttr = extra?.poiName || 'poiName';
|
||||
const areaIdAttr = extra?.areaId || 'areaId';
|
||||
return (_jsxs(_Fragment, { children: [_jsxs(Popup, { closeOnMaskClick: true, destroyOnClose: true, position: 'bottom', visible: sl, onClose: () => setSl(false), bodyStyle: {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch',
|
||||
}, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(Location, { coordinate: coordinate, onLocated: (poi) => setPoi(poi) }) }), _jsxs(Grid, { columns: 2, gap: 8, children: [_jsx(Button, { block: true, color: "primary", disabled: !poi, onClick: () => {
|
||||
if (poi) {
|
||||
const { poiName, coordinate, areaId } = poi;
|
||||
onValueChange({
|
||||
type: 'point',
|
||||
coordinate,
|
||||
}, {
|
||||
[poiNameAttr]: poiName,
|
||||
[areaIdAttr]: areaId,
|
||||
});
|
||||
}
|
||||
setSl(false);
|
||||
}, children: t('common::action.confirm') }), _jsx(Button, { block: true, fill: "outline", onClick: () => {
|
||||
setSl(false);
|
||||
}, children: t('common::action.cancel') })] })] }), _jsx("div", { style: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
}, onClick: () => setSl(true), children: _jsx(Map, { undragable: true, unzoomable: true, zoom: 13, disableWheelZoom: true, style: { height: 200, flex: 1 }, autoLocate: true, center: coordinate, markers: coordinate ? [coordinate] : undefined }) })] }));
|
||||
return (<>
|
||||
<Popup closeOnMaskClick={true} destroyOnClose={true} position='bottom' visible={sl} onClose={() => setSl(false)} bodyStyle={{
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch',
|
||||
}}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Location coordinate={coordinate} onLocated={(poi) => setPoi(poi)}/>
|
||||
</div>
|
||||
<Grid columns={2} gap={8}>
|
||||
<Button block color="primary" disabled={!poi} onClick={() => {
|
||||
if (poi) {
|
||||
const { poiName, coordinate, areaId } = poi;
|
||||
onValueChange({
|
||||
type: 'point',
|
||||
coordinate,
|
||||
}, {
|
||||
[poiNameAttr]: poiName,
|
||||
[areaIdAttr]: areaId,
|
||||
});
|
||||
}
|
||||
setSl(false);
|
||||
}}>
|
||||
{t('common::action.confirm')}
|
||||
</Button>
|
||||
<Button block fill="outline" onClick={() => {
|
||||
setSl(false);
|
||||
}}>
|
||||
{t('common::action.cancel')}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Popup>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
}} onClick={() => setSl(true)}>
|
||||
<Map undragable={true} unzoomable={true} zoom={13} disableWheelZoom={true} style={{ height: 200, flex: 1 }} autoLocate={true} center={coordinate} markers={coordinate ? [coordinate] : undefined}/>
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`【Abstract Update】无法支持的数据类别${type}的渲染`);
|
||||
|
|
@ -110,7 +135,8 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
export default function render(props) {
|
||||
const { renderData = [], helps, layout = 'horizontal', mode = 'default', entity } = props.data;
|
||||
const { update, t } = props.methods;
|
||||
return (_jsx(Form, { layout: layout, mode: mode, children: renderData.map((ele) => {
|
||||
return (<Form layout={layout} mode={mode}>
|
||||
{renderData.map((ele) => {
|
||||
// 因为i18n渲染机制的缘故,t必须放到这里来计算
|
||||
const { label, attr, type, required } = ele;
|
||||
let label2 = label;
|
||||
|
|
@ -129,16 +155,21 @@ export default function render(props) {
|
|||
label2 = t(`${entity}:attr.${attr}`);
|
||||
}
|
||||
}
|
||||
return (_jsx(Form.Item, { label: label2, rules: [
|
||||
return (<Form.Item label={label2} rules={[
|
||||
{
|
||||
required: !!required,
|
||||
},
|
||||
], help: helps && helps[attr], children: _jsx(_Fragment, { children: makeAttrInput(ele, (value, extra) => {
|
||||
const { attr } = ele;
|
||||
update({
|
||||
[attr]: value,
|
||||
...extra,
|
||||
});
|
||||
}, t, label2) }) }));
|
||||
}) }));
|
||||
]} help={helps && helps[attr]}>
|
||||
<>
|
||||
{makeAttrInput(ele, (value, extra) => {
|
||||
const { attr } = ele;
|
||||
update({
|
||||
[attr]: value,
|
||||
...extra,
|
||||
});
|
||||
}, t, label2)}
|
||||
</>
|
||||
</Form.Item>);
|
||||
})}
|
||||
</Form>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import React from 'react';
|
||||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { AttrUpsertRender } from '../../types/AbstractComponent';
|
||||
|
|
@ -9,5 +10,5 @@ export default function render<T extends keyof ED>(props: WebComponentProps<ED,
|
|||
helps?: Record<string, string>;
|
||||
layout?: 'horizontal' | 'vertical';
|
||||
children: any;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
}>): React.JSX.Element;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, InputNumber, Radio, Modal, Button, DatePicker, Space, Switch, } from 'antd';
|
||||
import OakIcon from '../icon';
|
||||
const { TextArea } = Input;
|
||||
|
|
@ -16,14 +15,14 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
case 'varchar':
|
||||
case 'char':
|
||||
case 'poiName': {
|
||||
return (_jsx(Input, { allowClear: !required, placeholder: placeholder || `请输入${label}`, value: value, defaultValue: defaultValue, maxLength: maxLength, onChange: ({ target: { value } }) => {
|
||||
return (<Input allowClear={!required} placeholder={placeholder || `请输入${label}`} value={value} defaultValue={defaultValue} maxLength={maxLength} onChange={({ target: { value } }) => {
|
||||
onValueChange(value);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'text': {
|
||||
return (_jsx(TextArea, { allowClear: !required, placeholder: `请输入${label}`, defaultValue: defaultValue, value: value, rows: 6, maxLength: maxLength || 1000, onChange: ({ target: { value } }) => {
|
||||
return (<TextArea allowClear={!required} placeholder={`请输入${label}`} defaultValue={defaultValue} value={value} rows={6} maxLength={maxLength || 1000} onChange={({ target: { value } }) => {
|
||||
onValueChange(value);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'int': {
|
||||
/* const SIGNED_THRESHOLDS = {
|
||||
|
|
@ -38,7 +37,7 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
4: [0, 4294967295],
|
||||
8: [0, Number.MAX_SAFE_INTEGER],
|
||||
}; */
|
||||
return (_jsx(InputNumber, { min: min, max: max, keyboard: true, defaultValue: defaultValue, value: value, precision: 0, onChange: (value) => onValueChange(value) }));
|
||||
return (<InputNumber min={min} max={max} keyboard={true} defaultValue={defaultValue} value={value} precision={0} onChange={(value) => onValueChange(value)}/>);
|
||||
}
|
||||
case 'decimal': {
|
||||
const precision = params?.precision || 10;
|
||||
|
|
@ -48,13 +47,13 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
const threshold = Math.pow(10, precision - scale);
|
||||
const max = threshold - scaleValue; // 小数在这里可能会有bug
|
||||
const min = 0 - max; */
|
||||
return (_jsx(InputNumber, { min: min, max: max, keyboard: true, defaultValue: defaultValue, value: value, precision: scale, step: scaleValue, onChange: (value) => onValueChange(value) }));
|
||||
return (<InputNumber min={min} max={max} keyboard={true} defaultValue={defaultValue} value={value} precision={scale} step={scaleValue} onChange={(value) => onValueChange(value)}/>);
|
||||
}
|
||||
case 'money': {
|
||||
// money在数据上统一用分来存储
|
||||
const valueShowed = parseFloat((value / 100).toFixed(2));
|
||||
const defaultValueShowed = parseFloat((defaultValue / 100).toFixed(2));
|
||||
return (_jsx(InputNumber, { min: 0, keyboard: true, defaultValue: defaultValueShowed, value: valueShowed, precision: 2, step: 0.01, addonAfter: "\uFFE5", onChange: (value) => {
|
||||
return (<InputNumber min={0} keyboard={true} defaultValue={defaultValueShowed} value={valueShowed} precision={2} step={0.01} addonAfter="¥" onChange={(value) => {
|
||||
if (value !== null) {
|
||||
const v2 = Math.round(value * 100);
|
||||
onValueChange(v2);
|
||||
|
|
@ -62,64 +61,82 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
else {
|
||||
onValueChange(value);
|
||||
}
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'datetime':
|
||||
case 'date':
|
||||
case 'time': {
|
||||
const mode = type === 'time' ? 'time' : 'date';
|
||||
return (_jsx(DatePicker, { allowClear: !required, showTime: type === 'datetime', placeholder: placeholder, format: "YYYY-MM-DD HH:mm:ss", mode: mode, value: dayjs(value), onChange: (value) => {
|
||||
return (<DatePicker allowClear={!required} showTime={type === 'datetime'} placeholder={placeholder} format="YYYY-MM-DD HH:mm:ss" mode={mode} value={dayjs(value)} onChange={(value) => {
|
||||
if (value) {
|
||||
onValueChange(value.valueOf());
|
||||
}
|
||||
else {
|
||||
onValueChange(null);
|
||||
}
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'boolean': {
|
||||
return (_jsx(Switch, { checkedChildren: _jsx(OakIcon, { name: "right" }), unCheckedChildren: _jsx(OakIcon, { name: "close" }), checked: value, onChange: (checked) => {
|
||||
return (<Switch checkedChildren={<OakIcon name="right"/>} unCheckedChildren={<OakIcon name="close"/>} checked={value} onChange={(checked) => {
|
||||
onValueChange(checked);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'enum': {
|
||||
return (_jsx(Radio.Group, { value: value, onChange: ({ target }) => onValueChange(target.value), children: enumeration.map(({ label, value }) => (_jsx(Radio, { value: value, children: t(label) }))) }));
|
||||
return (<Radio.Group value={value} onChange={({ target }) => onValueChange(target.value)}>
|
||||
{enumeration.map(({ label, value }) => (<Radio value={value}>{t(label)}</Radio>))}
|
||||
</Radio.Group>);
|
||||
}
|
||||
case 'ref': {
|
||||
return (_jsx(RefAttr, { multiple: false, entityId: value, pickerRender: attrRender, onChange: (value) => {
|
||||
return (<RefAttr multiple={false} entityId={value} pickerRender={attrRender} onChange={(value) => {
|
||||
onValueChange(value[0]);
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
case 'coordinate': {
|
||||
const { coordinate } = value || {};
|
||||
const { extra } = attrRender;
|
||||
const poiNameAttr = extra?.poiName || 'poiName';
|
||||
const areaIdAttr = extra?.areaId || 'areaId';
|
||||
return (_jsxs(_Fragment, { children: [_jsx(Modal, { width: "80vw", open: sl, closable: false, onCancel: () => setSl(false), okText: "\u786E\u8BA4", cancelText: "\u53D6\u6D88", okButtonProps: {
|
||||
disabled: !poi,
|
||||
}, onOk: () => {
|
||||
if (poi) {
|
||||
const { poiName, coordinate, areaId } = poi;
|
||||
onValueChange({
|
||||
type: 'point',
|
||||
coordinate,
|
||||
}, {
|
||||
[poiNameAttr]: poiName,
|
||||
[areaIdAttr]: areaId,
|
||||
});
|
||||
}
|
||||
setSl(false);
|
||||
}, children: _jsx(Location, { coordinate: coordinate, onLocated: (poi) => setPoi(poi) }) }), _jsx("div", { style: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}, children: _jsxs(Space, { direction: "vertical", size: 8, children: [_jsx(Space, { align: "center", children: _jsx(Button, { type: "dashed", onClick: () => {
|
||||
setSl(true);
|
||||
}, children: value ? '重选位置' : '选择位置' }) }), _jsx("div", { style: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}, children: _jsx(Map, { undragable: true, disableWheelZoom: true, style: { height: 300 }, autoLocate: true, center: coordinate, markers: coordinate ? [coordinate] : undefined }) })] }) })] }));
|
||||
return (<>
|
||||
<Modal width="80vw" open={sl} closable={false} onCancel={() => setSl(false)} okText="确认" cancelText="取消" okButtonProps={{
|
||||
disabled: !poi,
|
||||
}} onOk={() => {
|
||||
if (poi) {
|
||||
const { poiName, coordinate, areaId } = poi;
|
||||
onValueChange({
|
||||
type: 'point',
|
||||
coordinate,
|
||||
}, {
|
||||
[poiNameAttr]: poiName,
|
||||
[areaIdAttr]: areaId,
|
||||
});
|
||||
}
|
||||
setSl(false);
|
||||
}}>
|
||||
<Location coordinate={coordinate} onLocated={(poi) => setPoi(poi)}/>
|
||||
</Modal>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}}>
|
||||
<Space direction="vertical" size={8}>
|
||||
<Space align="center">
|
||||
<Button type="dashed" onClick={() => {
|
||||
setSl(true);
|
||||
}}>
|
||||
{value ? '重选位置' : '选择位置'}
|
||||
</Button>
|
||||
</Space>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}}>
|
||||
<Map undragable={true} disableWheelZoom={true} style={{ height: 300 }} autoLocate={true} center={coordinate} markers={coordinate ? [coordinate] : undefined}/>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`【Abstract Update】无法支持的数据类别${type}的渲染`);
|
||||
|
|
@ -129,7 +146,8 @@ function makeAttrInput(attrRender, onValueChange, t, label) {
|
|||
export default function render(props) {
|
||||
const { renderData = [], helps, entity } = props.data;
|
||||
const { update, t } = props.methods;
|
||||
return (_jsx(Form, { labelCol: { span: 4 }, layout: "horizontal", children: renderData.map((ele) => {
|
||||
return (<Form labelCol={{ span: 4 }} layout="horizontal">
|
||||
{renderData.map((ele) => {
|
||||
// 因为i18n渲染机制的缘故,t必须放到这里来计算
|
||||
const { label, attr, type, required } = ele;
|
||||
let label2 = label;
|
||||
|
|
@ -147,16 +165,21 @@ export default function render(props) {
|
|||
// label2 = t(`${entity}:attr.${attr}`);
|
||||
// }
|
||||
// }
|
||||
return (_jsx(Form.Item, { label: label2, rules: [
|
||||
return (<Form.Item label={label2} rules={[
|
||||
{
|
||||
required: !!required,
|
||||
},
|
||||
], help: helps && helps[attr], name: required ? attr : '', children: _jsx(_Fragment, { children: makeAttrInput(ele, (value, extra) => {
|
||||
const { attr } = ele;
|
||||
update({
|
||||
[attr]: value,
|
||||
...extra,
|
||||
});
|
||||
}, t, label2) }) }));
|
||||
}) }));
|
||||
]} help={helps && helps[attr]} name={required ? attr : ''}>
|
||||
<>
|
||||
{makeAttrInput(ele, (value, extra) => {
|
||||
const { attr } = ele;
|
||||
update({
|
||||
[attr]: value,
|
||||
...extra,
|
||||
});
|
||||
}, t, label2)}
|
||||
</>
|
||||
</Form.Item>);
|
||||
})}
|
||||
</Form>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ class ListNode extends Node {
|
|||
this.filters = filters || [];
|
||||
this.sorters = sorters || [];
|
||||
this.getTotal = getTotal;
|
||||
this.sr = {};
|
||||
this.pagination = pagination ? {
|
||||
...pagination,
|
||||
currentPage: pagination.currentPage - 1,
|
||||
|
|
@ -661,7 +662,7 @@ class ListNode extends Node {
|
|||
};
|
||||
}
|
||||
else {
|
||||
this.sr = data;
|
||||
this.sr = data || {};
|
||||
}
|
||||
for (const k in this.children) {
|
||||
const child = this.children[k];
|
||||
|
|
@ -1091,19 +1092,23 @@ class SingleNode extends Node {
|
|||
for (const k of keys) {
|
||||
const child = this.children[k];
|
||||
const rel = this.judgeRelation(k);
|
||||
if (rel === 2 && value.entityId) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId]: this.sr[k] || {},
|
||||
});
|
||||
if (rel === 2) {
|
||||
if (value?.entityId) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId]: this.sr[k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string' && value[`${k}Id`]) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`]]: this.sr[k] || {},
|
||||
});
|
||||
else if (typeof rel === 'string') {
|
||||
if (value && value[`${k}Id`]) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`]]: this.sr[k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(rel instanceof Array);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { Feature } from './types/Feature';
|
||||
import { DataOption, OakComponentOption } from './types/Page';
|
||||
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>> & FD): void;
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import { createComponent as createReactComponent } from './page.react';
|
||||
const DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
export function createComponent(option, features) {
|
||||
const BaseComponent = createReactComponent(option, features);
|
||||
class Component extends BaseComponent {
|
||||
scrollEvent = () => {
|
||||
this.checkReachBottom();
|
||||
};
|
||||
registerPageScroll() {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
unregisterPageScroll() {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
checkReachBottom() {
|
||||
if (!this.supportPullDownRefresh()) {
|
||||
return;
|
||||
}
|
||||
const isCurrentReachBottom = document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
if (!this.isReachBottom && isCurrentReachBottom && option.isList) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
this.loadMore();
|
||||
return;
|
||||
}
|
||||
this.isReachBottom = isCurrentReachBottom;
|
||||
}
|
||||
async componentDidMount() {
|
||||
this.registerPageScroll();
|
||||
await super.componentDidMount();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.unregisterPageScroll();
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
render() {
|
||||
const { oakPullDownRefreshLoading } = this.state;
|
||||
const Render = super.render();
|
||||
return Render;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import React from 'react';
|
||||
import { get } from 'oak-domain/lib/utils/lodash';
|
||||
|
|
@ -617,11 +616,11 @@ export function createComponent(option, features) {
|
|||
if (this.oakOption.entity && !this.state.oakFullpath) {
|
||||
return null;
|
||||
}
|
||||
return (_jsx(Render, { methods: this.methodProps, data: {
|
||||
return (<Render methods={this.methodProps} data={{
|
||||
...this.defaultProperties,
|
||||
...this.state,
|
||||
...this.props,
|
||||
} }));
|
||||
}}/>);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import { withRouter, PullToRefresh } from './platforms/web';
|
||||
import { createComponent as createReactComponent } from './page.react';
|
||||
const DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
|
|
@ -41,7 +41,7 @@ export function createComponent(option, features) {
|
|||
const { oakPullDownRefreshLoading } = this.state;
|
||||
const Render = super.render();
|
||||
if (this.supportPullDownRefresh()) {
|
||||
return (_jsx(PullToRefresh, { onRefresh: async () => {
|
||||
return (<PullToRefresh onRefresh={async () => {
|
||||
this.setState({
|
||||
oakPullDownRefreshLoading: true,
|
||||
});
|
||||
|
|
@ -49,7 +49,7 @@ export function createComponent(option, features) {
|
|||
this.setState({
|
||||
oakPullDownRefreshLoading: false,
|
||||
});
|
||||
}, refreshing: oakPullDownRefreshLoading, distanceToRefresh: DEFAULT_REACH_BOTTOM_DISTANCE, indicator: {
|
||||
}} refreshing={oakPullDownRefreshLoading} distanceToRefresh={DEFAULT_REACH_BOTTOM_DISTANCE} indicator={{
|
||||
activate: this.t('common::ptrActivate', {
|
||||
'#oakModule': 'oak-frontend-base',
|
||||
}),
|
||||
|
|
@ -62,7 +62,9 @@ export function createComponent(option, features) {
|
|||
finish: this.t('common::ptrFinish', {
|
||||
'#oakModule': 'oak-frontend-base',
|
||||
}),
|
||||
}, children: Render }));
|
||||
}}>
|
||||
{Render}
|
||||
</PullToRefresh>);
|
||||
}
|
||||
return Render;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
import PullToRefresh from 'rmc-pull-to-refresh';
|
||||
import './PullToRefresh.css';
|
||||
const OakPullToRefresh = (props) => {
|
||||
return _jsx(PullToRefresh, { ...props, prefixCls: "oak-pull-to-refresh" });
|
||||
return <PullToRefresh {...props} prefixCls="oak-pull-to-refresh"/>;
|
||||
};
|
||||
export default OakPullToRefresh;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import React from 'react';
|
||||
// @ts-ignore
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
|
|
@ -83,8 +82,8 @@ const withRouter = (Component, { path, properties }) => {
|
|||
params = Object.assign(params, getParams(location, properties), routerParams);
|
||||
routeMatch = true;
|
||||
}
|
||||
return (_jsx(Component, { ...rest, ...params, width: width, location: location, ref: forwardedRef, routeMatch: routeMatch }));
|
||||
return (<Component {...rest} {...params} width={width} location={location} ref={forwardedRef} routeMatch={routeMatch}/>);
|
||||
};
|
||||
return React.forwardRef((props, ref) => _jsx(ComponentWithRouterProp, { ...props, forwardedRef: ref }));
|
||||
return React.forwardRef((props, ref) => <ComponentWithRouterProp {...props} forwardedRef={ref}/>);
|
||||
};
|
||||
export default withRouter;
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ class ListNode extends Node {
|
|||
this.filters = filters || [];
|
||||
this.sorters = sorters || [];
|
||||
this.getTotal = getTotal;
|
||||
this.sr = {};
|
||||
this.pagination = pagination ? {
|
||||
...pagination,
|
||||
currentPage: pagination.currentPage - 1,
|
||||
|
|
@ -664,7 +665,7 @@ class ListNode extends Node {
|
|||
};
|
||||
}
|
||||
else {
|
||||
this.sr = data;
|
||||
this.sr = data || {};
|
||||
}
|
||||
for (const k in this.children) {
|
||||
const child = this.children[k];
|
||||
|
|
@ -1094,19 +1095,23 @@ class SingleNode extends Node {
|
|||
for (const k of keys) {
|
||||
const child = this.children[k];
|
||||
const rel = this.judgeRelation(k);
|
||||
if (rel === 2 && value.entityId) {
|
||||
(0, assert_1.assert)(child instanceof SingleNode);
|
||||
(0, assert_1.assert)(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId]: this.sr[k] || {},
|
||||
});
|
||||
if (rel === 2) {
|
||||
if (value?.entityId) {
|
||||
(0, assert_1.assert)(child instanceof SingleNode);
|
||||
(0, assert_1.assert)(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId]: this.sr[k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string' && value[`${k}Id`]) {
|
||||
(0, assert_1.assert)(child instanceof SingleNode);
|
||||
(0, assert_1.assert)(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`]]: this.sr[k] || {},
|
||||
});
|
||||
else if (typeof rel === 'string') {
|
||||
if (value && value[`${k}Id`]) {
|
||||
(0, assert_1.assert)(child instanceof SingleNode);
|
||||
(0, assert_1.assert)(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`]]: this.sr[k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
(0, assert_1.assert)(rel instanceof Array);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { Feature } from './types/Feature';
|
||||
import { DataOption, OakComponentOption } from './types/Page';
|
||||
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
export declare function createComponent<IsList extends boolean, ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature>, FormedData extends Record<string, any>, TData extends Record<string, any> = {}, TProperty extends DataOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>> & FD): void;
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createComponent = void 0;
|
||||
const page_react_1 = require("./page.react");
|
||||
const DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
function createComponent(option, features) {
|
||||
const BaseComponent = (0, page_react_1.createComponent)(option, features);
|
||||
class Component extends BaseComponent {
|
||||
scrollEvent = () => {
|
||||
this.checkReachBottom();
|
||||
};
|
||||
registerPageScroll() {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
unregisterPageScroll() {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
checkReachBottom() {
|
||||
if (!this.supportPullDownRefresh()) {
|
||||
return;
|
||||
}
|
||||
const isCurrentReachBottom = document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
if (!this.isReachBottom && isCurrentReachBottom && option.isList) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
this.loadMore();
|
||||
return;
|
||||
}
|
||||
this.isReachBottom = isCurrentReachBottom;
|
||||
}
|
||||
async componentDidMount() {
|
||||
this.registerPageScroll();
|
||||
await super.componentDidMount();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.unregisterPageScroll();
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
render() {
|
||||
const { oakPullDownRefreshLoading } = this.state;
|
||||
const Render = super.render();
|
||||
return Render;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.createComponent = createComponent;
|
||||
|
|
@ -385,6 +385,7 @@ class ListNode<
|
|||
this.filters = filters || [];
|
||||
this.sorters = sorters || [];
|
||||
this.getTotal = getTotal;
|
||||
this.sr = {};
|
||||
this.pagination = pagination ? {
|
||||
...pagination,
|
||||
currentPage: pagination.currentPage - 1,
|
||||
|
|
@ -825,7 +826,7 @@ class ListNode<
|
|||
};
|
||||
}
|
||||
else {
|
||||
this.sr = data;
|
||||
this.sr = data || {};
|
||||
}
|
||||
for (const k in this.children) {
|
||||
const child = this.children[k];
|
||||
|
|
@ -1320,19 +1321,23 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
for (const k of keys) {
|
||||
const child = this.children[k]!;
|
||||
const rel = this.judgeRelation(k);
|
||||
if (rel === 2 && value.entityId) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId!]: this.sr![k] || {},
|
||||
});
|
||||
if (rel === 2) {
|
||||
if (value?.entityId) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(value.entity === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value.entityId!]: this.sr![k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string' && value[`${k}Id`]) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`] as string]: this.sr![k] || {},
|
||||
});
|
||||
else if (typeof rel === 'string') {
|
||||
if (value && value[`${k}Id`]) {
|
||||
assert(child instanceof SingleNode);
|
||||
assert(rel === child.getEntity());
|
||||
child.saveRefreshResult({
|
||||
[value[`${k}Id`] as string]: this.sr![k] || {},
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert (rel instanceof Array);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
import React from 'react';
|
||||
import { RefreshControl, View, StyleSheet, } from 'react-native';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { Feature } from './types/Feature';
|
||||
import {
|
||||
DataOption,
|
||||
OakComponentOption,
|
||||
} from './types/Page';
|
||||
|
||||
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import { createComponent as createReactComponent } from './page.react';
|
||||
|
||||
const DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
|
||||
export function createComponent<
|
||||
IsList extends boolean,
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends AsyncContext<ED>,
|
||||
FrontCxt extends SyncContext<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature>,
|
||||
FormedData extends Record<string, any>,
|
||||
TData extends Record<string, any> = {},
|
||||
TProperty extends DataOption = {},
|
||||
TMethod extends Record<string, Function> = {}
|
||||
>(
|
||||
option: OakComponentOption<
|
||||
IsList,
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
FrontCxt,
|
||||
AD,
|
||||
FD,
|
||||
FormedData,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>,
|
||||
features: BasicFeatures<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
) {
|
||||
const BaseComponent = createReactComponent<
|
||||
IsList, ED, T, Cxt, FrontCxt, AD, FD, FormedData, TData, TProperty, TMethod
|
||||
>(option, features);
|
||||
|
||||
class Component extends BaseComponent {
|
||||
private scrollEvent = () => {
|
||||
this.checkReachBottom();
|
||||
};
|
||||
|
||||
private registerPageScroll() {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
|
||||
private unregisterPageScroll() {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
|
||||
private checkReachBottom() {
|
||||
if (!this.supportPullDownRefresh()) {
|
||||
return;
|
||||
}
|
||||
const isCurrentReachBottom =
|
||||
document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
|
||||
if (!this.isReachBottom && isCurrentReachBottom && option.isList) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
this.loadMore();
|
||||
return;
|
||||
}
|
||||
|
||||
this.isReachBottom = isCurrentReachBottom;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.registerPageScroll();
|
||||
await super.componentDidMount();
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
this.unregisterPageScroll();
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
const { oakPullDownRefreshLoading } = this.state;
|
||||
const Render = super.render();
|
||||
|
||||
return Render;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue