Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(filterrules): support part disabled and part edit #436

Merged
merged 2 commits into from Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/filterRules/demos/constants.ts
Expand Up @@ -12,6 +12,44 @@ export const INIT_DATA = {
},
};

export const INIT_CHECK_DATA = {
key: shortid(),
level: 0,
type: 1,
children: [
{
rowValues: {
input: '',
},
disabled: true,
key: shortid(),
level: 1,
},
{
key: shortid(),
type: 1,
level: 2,
disabled: true,
children: [
{
rowValues: {
input: '',
},
key: shortid(),
level: 2,
},
{
key: shortid(),
rowValues: {
input: '',
},
level: 2,
},
],
},
],
};

export const MORE_INIT_DATA = {
key: shortid(),
level: 1,
Expand Down
33 changes: 33 additions & 0 deletions src/filterRules/demos/editCheck.tsx
@@ -0,0 +1,33 @@
import React, { useState } from 'react';
import { Alert, Input } from 'antd';
import { FilterRules } from 'dt-react-component';
import { IComponentProps } from 'dt-react-component/filterRules';

import { INIT_CHECK_DATA, INIT_ROW_VALUES, IRow } from './constants';

const MyInput = ({ rowValues: { input }, disabled, rowKey, onChange }: IComponentProps<IRow>) => (
<Input
value={input}
disabled={disabled}
onChange={(e) => onChange?.(rowKey, { input: e.target.value })}
/>
);

export default () => {
const [data, setData] = useState(INIT_CHECK_DATA);

return (
<>
<Alert
message="适用于部分数据禁用且可以编辑其他数据。常见业务情景:上一次保存的数据不可修改,但需要在当前基础上继续新增数据。"
style={{ marginBottom: 16 }}
/>
<FilterRules<IRow>
component={(props) => <MyInput {...props} />}
value={data}
onChange={(value: any) => setData(value)}
initValues={INIT_ROW_VALUES}
/>
</>
);
};
16 changes: 9 additions & 7 deletions src/filterRules/index.md
Expand Up @@ -21,6 +21,7 @@ demo:
<code src="./demos/basicUnController.tsx" >非受控方式使用</code>
<code src="./demos/basicCheck.tsx" >查看数据</code>
<code src="./demos/basicMaxSize.tsx" >最大子节点示例</code>
<code src="./demos/editCheck.tsx" >查看编辑示例</code>

## API

Expand All @@ -39,13 +40,14 @@ demo:

### IFilterValue

| 参数 | 说明 | 类型 | 默认值 |
| --------- | -------------------------- | ------------------- | ------ |
| key | 唯一标识 | `string` | - |
| level | 节点层级 | `boolean` | - |
| type | 条件节点类型 | `1|2` | - |
| rowValues | 节点数据 | `T` | - |
| children | 子节点(存在条件节点时存在) | `IFilterValue<T>[]` | - |
| 参数 | 说明 | 类型 | 默认值 |
| --------- | -------------------------- | -------------------- | ------ |
| key | 唯一标识 | `string` | - |
| level | 节点层级 | `number` | - |
| type | 条件节点类型 | `1|2(1: 且, 2: 或)` | |
| disabled | 当前编辑/查看状态 | `boolean` | |
| rowValues | 节点数据 | `T` | - |
| children | 子节点(存在条件节点时存在) | `IFilterValue<T>[]` | - |

### IComponentProps

Expand Down
13 changes: 7 additions & 6 deletions src/filterRules/index.tsx
Expand Up @@ -27,6 +27,7 @@ export interface IFilterValue<T> {
key: string;
level?: number; // 当前节点的层级,用于判断一些按钮的展示
type?: number; // 当前节点的条件关系,1 | 2
disabled?: boolean; // 当前节点禁用
rowValues?: T; // Form 节点的相关的信息(子节点无条件节点时才有)
children?: IFilterValue<T>[]; // 子节点的信息(子节点存在条件节点时才有)
}
Expand Down Expand Up @@ -65,7 +66,7 @@ const FilterRules = <T,>(props: IProps<T>) => {
} = (!isDisabled(props) && props) as INormalProps<T>;

// 查找当前操作的节点
const finRelationNode = (
const findRelationNode = (
parentData: IFilterValue<T>,
targetKey: string,
needCurrent?: boolean
Expand All @@ -76,7 +77,7 @@ const FilterRules = <T,>(props: IProps<T>) => {
for (let i = 0; i < parentDataTemp.children.length; i++) {
const current = parentDataTemp.children[i];
if (current.key === targetKey) return needCurrent ? current : parentDataTemp;
const node: IFilterValue<T> | null | undefined = finRelationNode(
const node: IFilterValue<T> | null | undefined = findRelationNode(
current,
targetKey,
needCurrent
Expand All @@ -87,7 +88,7 @@ const FilterRules = <T,>(props: IProps<T>) => {

const handleAddCondition = (keyObj: { key: string; isOut?: boolean }) => {
const cloneData = clone(value);
const appendNode = finRelationNode(cloneData as IFilterValue<T>, keyObj.key, keyObj.isOut);
const appendNode = findRelationNode(cloneData as IFilterValue<T>, keyObj.key, keyObj.isOut);
addCondition(appendNode, keyObj, initValues as T);
onChange?.(cloneData);
};
Expand Down Expand Up @@ -148,7 +149,7 @@ const FilterRules = <T,>(props: IProps<T>) => {

const handleDeleteCondition = (key: string) => {
const cloneData = clone(value);
const deleteNode = finRelationNode(cloneData as IFilterValue<T>, key, false);
const deleteNode = findRelationNode(cloneData as IFilterValue<T>, key, false);
if (notEmpty.data && !deleteNode?.children) return message.info(notEmpty.message);
if (!notEmpty.data && !deleteNode?.children) {
return onChange?.(undefined);
Expand Down Expand Up @@ -190,7 +191,7 @@ const FilterRules = <T,>(props: IProps<T>) => {
// 更改条件节点的条件
const handleChangeCondition = (key: string, type: ROW_PERMISSION_RELATION) => {
const cloneData = clone(value);
const changeNode = finRelationNode(
const changeNode = findRelationNode(
cloneData as IFilterValue<T>,
key,
true
Expand All @@ -205,7 +206,7 @@ const FilterRules = <T,>(props: IProps<T>) => {
// 改变节点的的数据
const handleChangeRowValues = (key: string, values: T) => {
const cloneData = clone(value);
const changeNode = finRelationNode(
const changeNode = findRelationNode(
cloneData as IFilterValue<T>,
key,
true
Expand Down
3 changes: 2 additions & 1 deletion src/filterRules/ruleController/index.scss
Expand Up @@ -37,7 +37,7 @@
color: #1D78FF;
text-align: center;
line-height: 26px;
z-index: 10;
z-index: 1;
&.disabled {
cursor: not-allowed;
color: #3D446E;
Expand Down Expand Up @@ -90,6 +90,7 @@
width: 10%;
margin-left: 12px;
margin-top: 7px;
min-width: 55px;
.icon {
cursor: pointer;
color: #1D78FF;
Expand Down
33 changes: 21 additions & 12 deletions src/filterRules/ruleController/index.tsx
Expand Up @@ -48,13 +48,14 @@ export const RulesController = <T,>(props: IProps<T>) => {

// 计算每个节点的高度(height)/线条高度(lineHeight)/距离底部高度(bottom)
const calculateTreeItemHeight = (item: IFilterValue<T>, disabled: boolean) => {
const composeDisabled = disabled || !!item.disabled;
if (!item?.children)
return weakMap.set(item, { height: ITEM_HEIGHT + MARGIN, lineHeight: ITEM_HEIGHT });
item.children.map((child) => calculateTreeItemHeight(child, disabled));
item.children.map((child) => calculateTreeItemHeight(child, composeDisabled));
const isLastCondition = !item.children.some(isCondition);
const firstNodeIsCondition = isCondition(item.children[0]);
// 编辑模式下计算
if (!disabled) {
if (!composeDisabled) {
const height = item.children.reduce(
(prev, curr) => prev + weakMap.get(curr).height,
ITEM_HEIGHT
Expand Down Expand Up @@ -123,6 +124,8 @@ export const RulesController = <T,>(props: IProps<T>) => {
namePath: InternalNamePath,
disabled: boolean
) => {
const composeDisabled = disabled || !!item.disabled;

// 渲染条件节点和线条
if (item?.children?.length) {
const childrenPath = (index: number) => {
Expand All @@ -140,15 +143,16 @@ export const RulesController = <T,>(props: IProps<T>) => {
>
<div
className={classnames('condition__box', {
disabled,
disabled: composeDisabled,
})}
style={{ height: lineHeight, bottom: bottom ?? MARGIN }}
>
<span
className={classnames('condition__box--name', {
disabled,
disabled: composeDisabled,
})}
onClick={() =>
!composeDisabled &&
onChangeCondition(item.key, item?.type as ROW_PERMISSION_RELATION)
}
>
Expand All @@ -163,9 +167,9 @@ export const RulesController = <T,>(props: IProps<T>) => {
)}
</div>
{item.children.map((d: IFilterValue<T>, index: number) =>
renderCondition(d, childrenPath(index), disabled)
renderCondition(d, childrenPath(index), composeDisabled)
)}
{!disabled && (
{!composeDisabled && (
<div className="condition__add">
<span className="condition__add--line" />
<PlusCircleOutlined
Expand Down Expand Up @@ -200,20 +204,18 @@ export const RulesController = <T,>(props: IProps<T>) => {
<div className="ruleController__item--component">
{component({
rowKey: item.key,
disabled,
disabled: composeDisabled,
name: [...namePath, 'rowValues'],
rowValues: item.rowValues as T,
onChange: onChangeRowValues,
})}
</div>
{!disabled && (
{!composeDisabled && (
<div className="ruleController__item--operation">
{item.level === maxLevel ? null : (
<PlusCircleOutlined
className="icon"
onClick={() => {
onAddCondition({ key: item.key });
}}
onClick={() => onAddCondition({ key: item.key })}
/>
)}
<MinusCircleOutlined
Expand All @@ -225,7 +227,14 @@ export const RulesController = <T,>(props: IProps<T>) => {
</div>
);
};

if (!value) return null;

calculateTreeItemHeight(value, !!disabled);
return <div className="ruleController">{renderCondition(value, [], !!disabled)}</div>;

return (
<div className="ruleController">
{renderCondition(value, [], !!disabled || !!value.disabled)}
</div>
);
};