feat: upgrade formily (#1880)
* feat: upgrade formily * fix: upgrade @formily/json-schema * fix: optimizing performance * fix: performance code * refactor: `React.memo` and `observer` component add `displayName` property * fix: add cache to Schema.compile * feat: 优化代码 * fix: 修复卡顿最终的问题 * Update SchemaComponentProvider.tsx * feat: 再次优化代码 * feat: optimized code --------- Co-authored-by: dream2023 <1098626505@qq.com>
This commit is contained in:
		
							parent
							
								
									36d16bc015
								
							
						
					
					
						commit
						e6a2a292b3
					
				@ -42,6 +42,7 @@ const HelloProvider = React.memo((props) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return <>{props.children}</>
 | 
					  return <>{props.children}</>
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					HelloProvider.displayName = 'HelloProvider'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(HelloProvider);
 | 
					app.use(HelloProvider);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			|||||||
import { Table, TableColumnType } from 'antd';
 | 
					import { Table, TableColumnType } from 'antd';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ArrayTable = observer((props: any) => {
 | 
					const ArrayTable = observer(
 | 
				
			||||||
  const { rowKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const { rowKey } = props;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
    if (s['x-component'] === 'ArrayTable.Column') {
 | 
					    const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      buf.push(s);
 | 
					      if (s['x-component'] === 'ArrayTable.Column') {
 | 
				
			||||||
    }
 | 
					        buf.push(s);
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  }, []);
 | 
					      return buf;
 | 
				
			||||||
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const columns = columnSchemas.map((s) => {
 | 
					    const columns = columnSchemas.map((s) => {
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      render: (value, record) => {
 | 
					        render: (value, record) => {
 | 
				
			||||||
        return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
					          return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
    } as TableColumnType<any>;
 | 
					      } as TableColumnType<any>;
 | 
				
			||||||
  });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					    return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ArrayTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
 | 
				
			|||||||
@ -180,11 +180,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -240,7 +240,7 @@ const useDragEnd = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
					  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Draggable(props) {
 | 
					function Draggable(props) {
 | 
				
			||||||
  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
					  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
				
			||||||
@ -289,7 +289,7 @@ const Block = observer((props) => {
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Droppable>
 | 
					    </Droppable>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Block' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -316,7 +316,7 @@ export default function App() {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
## Applications of `x-designer` 
 | 
					## Applications of `x-designer`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`x-designer` is usually used only in wrapper components such as BlockItem, CardItem, FormItem, etc.
 | 
					`x-designer` is usually used only in wrapper components such as BlockItem, CardItem, FormItem, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -51,13 +51,13 @@ const ReadPretty = (props) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SingleText = connect(
 | 
					const SingleText = connect(
 | 
				
			||||||
  Input, 
 | 
					  Input,
 | 
				
			||||||
  mapProps((props, field) => {
 | 
					  mapProps((props, field) => {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      ...props,
 | 
					      ...props,
 | 
				
			||||||
      suffix: '后缀',
 | 
					      suffix: '后缀',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }), 
 | 
					  }),
 | 
				
			||||||
  mapReadPretty(ReadPretty),
 | 
					  mapReadPretty(ReadPretty),
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,7 +103,7 @@ const SingleText = connect(Input);
 | 
				
			|||||||
const UsedObserver = observer((props) => {
 | 
					const UsedObserver = observer((props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
  return <div>UsedObserver: {form.values.t1}</div>
 | 
					  return <div>UsedObserver: {form.values.t1}</div>
 | 
				
			||||||
});
 | 
					}, { displayName: 'UsedObserver' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NotUsedObserver = (props) => {
 | 
					const NotUsedObserver = (props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
@ -192,7 +192,7 @@ export default () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Comparison of rendering results by property type 
 | 
					Comparison of rendering results by property type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```tsx
 | 
					```tsx
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
@ -310,7 +310,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      </ul>
 | 
					      </ul>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -367,7 +367,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      })}
 | 
					      })}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -432,7 +432,7 @@ const ArrayTable = observer((props: any) => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayTable' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
 | 
				
			|||||||
@ -116,11 +116,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -182,6 +182,7 @@ const HelloProvider = React.memo((props) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return <>{props.children}</>
 | 
					  return <>{props.children}</>
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					HelloProvider.displayName = 'HelloProvider'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(HelloProvider);
 | 
					app.use(HelloProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			|||||||
import { Table, TableColumnType } from 'antd';
 | 
					import { Table, TableColumnType } from 'antd';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ArrayTable = observer((props: any) => {
 | 
					const ArrayTable = observer(
 | 
				
			||||||
  const { rowKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const { rowKey } = props;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
    if (s['x-component'] === 'ArrayTable.Column') {
 | 
					    const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      buf.push(s);
 | 
					      if (s['x-component'] === 'ArrayTable.Column') {
 | 
				
			||||||
    }
 | 
					        buf.push(s);
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  }, []);
 | 
					      return buf;
 | 
				
			||||||
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const columns = columnSchemas.map((s) => {
 | 
					    const columns = columnSchemas.map((s) => {
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      render: (value, record) => {
 | 
					        render: (value, record) => {
 | 
				
			||||||
        return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
					          return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
    } as TableColumnType<any>;
 | 
					      } as TableColumnType<any>;
 | 
				
			||||||
  });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					    return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ArrayTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
 | 
				
			|||||||
@ -183,11 +183,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -243,7 +243,7 @@ const useDragEnd = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
					  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Draggable(props) {
 | 
					function Draggable(props) {
 | 
				
			||||||
  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
					  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
				
			||||||
@ -292,7 +292,7 @@ const Block = observer((props) => {
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Droppable>
 | 
					    </Droppable>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Block' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -51,13 +51,13 @@ const ReadPretty = (props) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SingleText = connect(
 | 
					const SingleText = connect(
 | 
				
			||||||
  Input, 
 | 
					  Input,
 | 
				
			||||||
  mapProps((props, field) => {
 | 
					  mapProps((props, field) => {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      ...props,
 | 
					      ...props,
 | 
				
			||||||
      suffix: '后缀',
 | 
					      suffix: '后缀',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }), 
 | 
					  }),
 | 
				
			||||||
  mapReadPretty(ReadPretty),
 | 
					  mapReadPretty(ReadPretty),
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,7 +103,7 @@ const SingleText = connect(Input);
 | 
				
			|||||||
const UsedObserver = observer((props) => {
 | 
					const UsedObserver = observer((props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
  return <div>UsedObserver: {form.values.t1}</div>
 | 
					  return <div>UsedObserver: {form.values.t1}</div>
 | 
				
			||||||
});
 | 
					}, { displayName: 'UsedObserver' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NotUsedObserver = (props) => {
 | 
					const NotUsedObserver = (props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
@ -193,7 +193,7 @@ export default () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
各类型 properties 渲染结果对比 
 | 
					各类型 properties 渲染结果对比
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```tsx
 | 
					```tsx
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
@ -312,7 +312,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      </ul>
 | 
					      </ul>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -369,7 +369,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      })}
 | 
					      })}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -434,7 +434,7 @@ const ArrayTable = observer((props: any) => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayTable' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
@ -515,4 +515,4 @@ export default () => {
 | 
				
			|||||||
    </SchemaComponentProvider>
 | 
					    </SchemaComponentProvider>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -116,11 +116,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@ const HelloProvider = React.memo((props) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return <>{props.children}</>
 | 
					  return <>{props.children}</>
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					HelloProvider.displayName = 'HelloProvider'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(HelloProvider);
 | 
					app.use(HelloProvider);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			|||||||
import { Table, TableColumnType } from 'antd';
 | 
					import { Table, TableColumnType } from 'antd';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ArrayTable = observer((props: any) => {
 | 
					const ArrayTable = observer(
 | 
				
			||||||
  const { rowKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const { rowKey } = props;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
    if (s['x-component'] === 'ArrayTable.Column') {
 | 
					    const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      buf.push(s);
 | 
					      if (s['x-component'] === 'ArrayTable.Column') {
 | 
				
			||||||
    }
 | 
					        buf.push(s);
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  }, []);
 | 
					      return buf;
 | 
				
			||||||
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const columns = columnSchemas.map((s) => {
 | 
					    const columns = columnSchemas.map((s) => {
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      render: (value, record) => {
 | 
					        render: (value, record) => {
 | 
				
			||||||
        return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
					          return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
    } as TableColumnType<any>;
 | 
					      } as TableColumnType<any>;
 | 
				
			||||||
  });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					    return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ArrayTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
 | 
				
			|||||||
@ -183,11 +183,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -243,7 +243,7 @@ const useDragEnd = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
					  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Draggable(props) {
 | 
					function Draggable(props) {
 | 
				
			||||||
  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
					  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
				
			||||||
@ -292,7 +292,7 @@ const Block = observer((props) => {
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Droppable>
 | 
					    </Droppable>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Block' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -51,13 +51,13 @@ const ReadPretty = (props) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SingleText = connect(
 | 
					const SingleText = connect(
 | 
				
			||||||
  Input, 
 | 
					  Input,
 | 
				
			||||||
  mapProps((props, field) => {
 | 
					  mapProps((props, field) => {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      ...props,
 | 
					      ...props,
 | 
				
			||||||
      suffix: '后缀',
 | 
					      suffix: '后缀',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }), 
 | 
					  }),
 | 
				
			||||||
  mapReadPretty(ReadPretty),
 | 
					  mapReadPretty(ReadPretty),
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,7 +103,7 @@ const SingleText = connect(Input);
 | 
				
			|||||||
const UsedObserver = observer((props) => {
 | 
					const UsedObserver = observer((props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
  return <div>UsedObserver: {form.values.t1}</div>
 | 
					  return <div>UsedObserver: {form.values.t1}</div>
 | 
				
			||||||
});
 | 
					}, { displayName: 'UsedObserver' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NotUsedObserver = (props) => {
 | 
					const NotUsedObserver = (props) => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
@ -193,7 +193,7 @@ export default () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
各类型 properties 渲染结果对比 
 | 
					各类型 properties 渲染结果对比
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```tsx
 | 
					```tsx
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
@ -312,7 +312,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      </ul>
 | 
					      </ul>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -369,7 +369,7 @@ const ArrayList = observer((props) => {
 | 
				
			|||||||
      })}
 | 
					      })}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayList' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>
 | 
					  return <li>value: {props.value}</li>
 | 
				
			||||||
@ -434,7 +434,7 @@ const ArrayTable = observer((props: any) => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					  return <Table rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					}, { displayName: 'ArrayTable' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
@ -515,4 +515,4 @@ export default () => {
 | 
				
			|||||||
    </SchemaComponentProvider>
 | 
					    </SchemaComponentProvider>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -116,11 +116,11 @@ const Hello = observer((props) => {
 | 
				
			|||||||
      <div style={{ margin: 50 }}>{props.children}</div>
 | 
					      <div style={{ margin: 50 }}>{props.children}</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello'  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					  return <div>{props.children}</div>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -176,6 +176,7 @@ const HelloProvider = React.memo((props) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return <>{props.children}</>
 | 
					  return <>{props.children}</>
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					HelloProvider.displayName = 'HelloProvider'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(HelloProvider);
 | 
					app.use(HelloProvider);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default React.memo((props) => {
 | 
					const CommonMemo = React.memo((props) => {
 | 
				
			||||||
  return <>{props.children}</>;
 | 
					  return <>{props.children}</>;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					CommonMemo.displayName = 'CommonMemo';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default CommonMemo;
 | 
				
			||||||
 | 
				
			|||||||
@ -168,11 +168,11 @@ const App: React.FC = () => {
 | 
				
			|||||||
      <Button type="primary" onClick={showDrawer}>
 | 
					      <Button type="primary" onClick={showDrawer}>
 | 
				
			||||||
        Open
 | 
					        Open
 | 
				
			||||||
      </Button>
 | 
					      </Button>
 | 
				
			||||||
      <Drawer 
 | 
					      <Drawer
 | 
				
			||||||
        title="Basic Drawer" 
 | 
					        title="Basic Drawer"
 | 
				
			||||||
        placement="right" 
 | 
					        placement="right"
 | 
				
			||||||
        onClose={onClose} 
 | 
					        onClose={onClose}
 | 
				
			||||||
        visible={visible} 
 | 
					        visible={visible}
 | 
				
			||||||
        footer={
 | 
					        footer={
 | 
				
			||||||
          <Button onClick={onClose}>关闭</Button>
 | 
					          <Button onClick={onClose}>关闭</Button>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -262,8 +262,8 @@ export default function App() {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SchemaComponentProvider 
 | 
					    <SchemaComponentProvider
 | 
				
			||||||
      form={form} 
 | 
					      form={form}
 | 
				
			||||||
      components={{ Drawer, Button }}
 | 
					      components={{ Drawer, Button }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SchemaComponent schema={schema} scope={{ showDrawer, onClose }} />
 | 
					      <SchemaComponent schema={schema} scope={{ showDrawer, onClose }} />
 | 
				
			||||||
@ -374,7 +374,7 @@ const Action: any = observer((props: any) => {
 | 
				
			|||||||
      <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />
 | 
					      <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />
 | 
				
			||||||
    </VisibleContext.Provider>
 | 
					    </VisibleContext.Provider>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Action' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Action.Drawer = observer((props: any) => {
 | 
					Action.Drawer = observer((props: any) => {
 | 
				
			||||||
  const [visible, setVisible] = useContext(VisibleContext);
 | 
					  const [visible, setVisible] = useContext(VisibleContext);
 | 
				
			||||||
@ -411,13 +411,13 @@ Action.Drawer = observer((props: any) => {
 | 
				
			|||||||
      )}
 | 
					      )}
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Action.Drawer' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Action.Drawer.Footer = observer((props: any) => {
 | 
					Action.Drawer.Footer = observer((props: any) => {
 | 
				
			||||||
  const field = useField();
 | 
					  const field = useField();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
					  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Action.Drawer.Footer' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const schema: ISchema = {
 | 
					const schema: ISchema = {
 | 
				
			||||||
  type: 'object',
 | 
					  type: 'object',
 | 
				
			||||||
@ -500,7 +500,7 @@ const Hello = observer(({ name }) => {
 | 
				
			|||||||
      >更新</Button>
 | 
					      >更新</Button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
});
 | 
					}, { displayName: 'Hello' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const RouteSchemaComponent = (props) => {
 | 
					const RouteSchemaComponent = (props) => {
 | 
				
			||||||
  const route = useRoute();
 | 
					  const route = useRoute();
 | 
				
			||||||
@ -678,7 +678,7 @@ const useDragEnd = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Page = observer((props) => {
 | 
					const Page = observer((props) => {
 | 
				
			||||||
  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
					  return <DndContext onDragEnd={useDragEnd()}>{props.children}</DndContext>;
 | 
				
			||||||
});
 | 
					}, { displayName: 'Page' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Draggable(props) {
 | 
					function Draggable(props) {
 | 
				
			||||||
  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
					  const { attributes, listeners, setNodeRef, transform } = useDraggable({
 | 
				
			||||||
@ -727,7 +727,7 @@ const Block = observer((props) => {
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Droppable>
 | 
					    </Droppable>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					}, { displayName: 'Block' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -856,4 +856,4 @@ await respond(ctx);
 | 
				
			|||||||
- Provider 的顺序怎么处理
 | 
					- Provider 的顺序怎么处理
 | 
				
			||||||
- 如何动态的加载前端模块
 | 
					- 如何动态的加载前端模块
 | 
				
			||||||
 | 
					
 | 
				
			||||||
未完待续...
 | 
					未完待续...
 | 
				
			||||||
 | 
				
			|||||||
@ -10,9 +10,9 @@
 | 
				
			|||||||
    "@dnd-kit/core": "^5.0.1",
 | 
					    "@dnd-kit/core": "^5.0.1",
 | 
				
			||||||
    "@dnd-kit/sortable": "^6.0.0",
 | 
					    "@dnd-kit/sortable": "^6.0.0",
 | 
				
			||||||
    "@emotion/css": "^11.7.1",
 | 
					    "@emotion/css": "^11.7.1",
 | 
				
			||||||
    "@formily/antd": "2.0.20",
 | 
					    "@formily/antd": "2.2.24",
 | 
				
			||||||
    "@formily/core": "2.0.20",
 | 
					    "@formily/core": "2.2.24",
 | 
				
			||||||
    "@formily/react": "2.0.20",
 | 
					    "@formily/react": "2.2.24",
 | 
				
			||||||
    "@nocobase/evaluators": "0.9.4-alpha.2",
 | 
					    "@nocobase/evaluators": "0.9.4-alpha.2",
 | 
				
			||||||
    "@nocobase/sdk": "0.9.4-alpha.2",
 | 
					    "@nocobase/sdk": "0.9.4-alpha.2",
 | 
				
			||||||
    "@nocobase/utils": "0.9.4-alpha.2",
 | 
					    "@nocobase/utils": "0.9.4-alpha.2",
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,8 @@ const App = React.memo((props: any) => {
 | 
				
			|||||||
  return <C />;
 | 
					  return <C />;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					App.displayName = 'App';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Application {
 | 
					export class Application {
 | 
				
			||||||
  providers = [];
 | 
					  providers = [];
 | 
				
			||||||
  mainComponent = null;
 | 
					  mainComponent = null;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,18 +3,21 @@ import { useDesignable } from '@nocobase/client';
 | 
				
			|||||||
import { Button } from 'antd';
 | 
					import { Button } from 'antd';
 | 
				
			||||||
import { observer } from '@formily/react';
 | 
					import { observer } from '@formily/react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Hello: React.FC<any> = observer(({ name }) => {
 | 
					export const Hello: React.FC<any> = observer(
 | 
				
			||||||
  const { patch, remove } = useDesignable();
 | 
					  ({ name }) => {
 | 
				
			||||||
  return (
 | 
					    const { patch, remove } = useDesignable();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <h1>Hello {name}!</h1>
 | 
					      <div>
 | 
				
			||||||
      <Button
 | 
					        <h1>Hello {name}!</h1>
 | 
				
			||||||
        onClick={() => {
 | 
					        <Button
 | 
				
			||||||
          patch('x-component-props.name', Math.random());
 | 
					          onClick={() => {
 | 
				
			||||||
        }}
 | 
					            patch('x-component-props.name', Math.random());
 | 
				
			||||||
      >
 | 
					          }}
 | 
				
			||||||
        更新
 | 
					        >
 | 
				
			||||||
      </Button>
 | 
					          更新
 | 
				
			||||||
    </div>
 | 
					        </Button>
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Hello' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -31,36 +31,39 @@ const useDef = (options, props) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CollectionFieldsTable: React.FC<TableVoidProps> = observer((props) => {
 | 
					export const CollectionFieldsTable: React.FC<TableVoidProps> = observer(
 | 
				
			||||||
  const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props;
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const form = useMemo(() => createForm(), []);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const f = useAttach(form.createArrayField({ ...field.props, basePath: '' }));
 | 
					    const form = useMemo(() => createForm(), []);
 | 
				
			||||||
  const result = useDataSource(
 | 
					    const f = useAttach(form.createArrayField({ ...field.props, basePath: '' }));
 | 
				
			||||||
    {
 | 
					    const result = useDataSource(
 | 
				
			||||||
      uid: fieldSchema['x-uid'],
 | 
					      {
 | 
				
			||||||
      onSuccess(data) {
 | 
					        uid: fieldSchema['x-uid'],
 | 
				
			||||||
        form.setValues({
 | 
					        onSuccess(data) {
 | 
				
			||||||
          [fieldSchema.name]: data?.data,
 | 
					          form.setValues({
 | 
				
			||||||
        });
 | 
					            [fieldSchema.name]: data?.data,
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      props,
 | 
				
			||||||
    props,
 | 
					    );
 | 
				
			||||||
  );
 | 
					    return (
 | 
				
			||||||
  return (
 | 
					      <AsyncDataProvider value={result}>
 | 
				
			||||||
    <AsyncDataProvider value={result}>
 | 
					        <FormContext.Provider value={form}>
 | 
				
			||||||
      <FormContext.Provider value={form}>
 | 
					          <FieldContext.Provider value={f}>
 | 
				
			||||||
        <FieldContext.Provider value={f}>
 | 
					            <CollectionFieldsTableArray
 | 
				
			||||||
          <CollectionFieldsTableArray
 | 
					              {...props}
 | 
				
			||||||
            {...props}
 | 
					              rowKey={rowKey}
 | 
				
			||||||
            rowKey={rowKey}
 | 
					              loading={result?.['loading']}
 | 
				
			||||||
            loading={result?.['loading']}
 | 
					              useSelectedRowKeys={useSelectedRowKeys}
 | 
				
			||||||
            useSelectedRowKeys={useSelectedRowKeys}
 | 
					              pagination={false}
 | 
				
			||||||
            pagination={false}
 | 
					            />
 | 
				
			||||||
          />
 | 
					          </FieldContext.Provider>
 | 
				
			||||||
        </FieldContext.Provider>
 | 
					        </FormContext.Provider>
 | 
				
			||||||
      </FormContext.Provider>
 | 
					      </AsyncDataProvider>
 | 
				
			||||||
    </AsyncDataProvider>
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'CollectionFieldsTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -79,149 +79,150 @@ interface CategorizeDataItem {
 | 
				
			|||||||
  data: Array<any>;
 | 
					  data: Array<any>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CollectionFieldsTableArray: React.FC<any> = observer((props) => {
 | 
					export const CollectionFieldsTableArray: React.FC<any> = observer(
 | 
				
			||||||
  const sortKeyArr: Array<CategorizeKey> = ['primaryAndForeignKey', 'relation', 'basic', 'systemInfo'];
 | 
					  (props) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const sortKeyArr: Array<CategorizeKey> = ['primaryAndForeignKey', 'relation', 'basic', 'systemInfo'];
 | 
				
			||||||
  const { name } = useRecord();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const { name } = useRecord();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  const { getInterface, getInheritCollections, getCollection, getCurrentCollectionFields, getInheritedFields } =
 | 
					    const compile = useCompile();
 | 
				
			||||||
    useCollectionManager();
 | 
					    const { getInterface, getInheritCollections, getCollection, getCurrentCollectionFields, getInheritedFields } =
 | 
				
			||||||
  const {
 | 
					      useCollectionManager();
 | 
				
			||||||
    showIndex = true,
 | 
					    const {
 | 
				
			||||||
    useSelectedRowKeys = useDef,
 | 
					      showIndex = true,
 | 
				
			||||||
    useDataSource = useDefDataSource,
 | 
					      useSelectedRowKeys = useDef,
 | 
				
			||||||
    onChange,
 | 
					      useDataSource = useDefDataSource,
 | 
				
			||||||
    ...others
 | 
					      onChange,
 | 
				
			||||||
  } = props;
 | 
					      ...others
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
 | 
					    } = props;
 | 
				
			||||||
  const [categorizeData, setCategorizeData] = useState<Array<CategorizeDataItem>>([]);
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
 | 
				
			||||||
  const [expandedKeys, setExpendedKeys] = useState(selectedRowKeys);
 | 
					    const [categorizeData, setCategorizeData] = useState<Array<CategorizeDataItem>>([]);
 | 
				
			||||||
  const inherits = getInheritCollections(name);
 | 
					    const [expandedKeys, setExpendedKeys] = useState(selectedRowKeys);
 | 
				
			||||||
  const currentFields = getCurrentCollectionFields(name);
 | 
					    const inherits = getInheritCollections(name);
 | 
				
			||||||
  useDataSource({
 | 
					    const currentFields = getCurrentCollectionFields(name);
 | 
				
			||||||
    onSuccess(data) {
 | 
					    useDataSource({
 | 
				
			||||||
      field.value = data?.data || [];
 | 
					      onSuccess(data) {
 | 
				
			||||||
      const tmpData: Array<CategorizeDataItem> = [];
 | 
					        field.value = data?.data || [];
 | 
				
			||||||
      const categorizeMap = new Map<CategorizeKey, any>();
 | 
					        const tmpData: Array<CategorizeDataItem> = [];
 | 
				
			||||||
      const addCategorizeVal = (categorizeKey: CategorizeKey, val) => {
 | 
					        const categorizeMap = new Map<CategorizeKey, any>();
 | 
				
			||||||
        let fieldArr = categorizeMap.get(categorizeKey);
 | 
					        const addCategorizeVal = (categorizeKey: CategorizeKey, val) => {
 | 
				
			||||||
        if (!fieldArr) {
 | 
					          let fieldArr = categorizeMap.get(categorizeKey);
 | 
				
			||||||
          fieldArr = [];
 | 
					          if (!fieldArr) {
 | 
				
			||||||
        }
 | 
					            fieldArr = [];
 | 
				
			||||||
        fieldArr.push(val);
 | 
					          }
 | 
				
			||||||
        categorizeMap.set(categorizeKey, fieldArr);
 | 
					          fieldArr.push(val);
 | 
				
			||||||
      };
 | 
					          categorizeMap.set(categorizeKey, fieldArr);
 | 
				
			||||||
      field.value.forEach((item) => {
 | 
					        };
 | 
				
			||||||
        const itemInterface = getInterface(item?.interface);
 | 
					        field.value.forEach((item) => {
 | 
				
			||||||
        if (item?.primaryKey || item.isForeignKey) {
 | 
					          const itemInterface = getInterface(item?.interface);
 | 
				
			||||||
          addCategorizeVal('primaryAndForeignKey', item);
 | 
					          if (item?.primaryKey || item.isForeignKey) {
 | 
				
			||||||
          return;
 | 
					            addCategorizeVal('primaryAndForeignKey', item);
 | 
				
			||||||
        }
 | 
					            return;
 | 
				
			||||||
        const group = itemInterface?.group as CategorizeKey;
 | 
					          }
 | 
				
			||||||
        switch (group) {
 | 
					          const group = itemInterface?.group as CategorizeKey;
 | 
				
			||||||
          case 'systemInfo':
 | 
					          switch (group) {
 | 
				
			||||||
          case 'relation':
 | 
					            case 'systemInfo':
 | 
				
			||||||
            addCategorizeVal(group, item);
 | 
					            case 'relation':
 | 
				
			||||||
            break;
 | 
					              addCategorizeVal(group, item);
 | 
				
			||||||
          default:
 | 
					              break;
 | 
				
			||||||
            addCategorizeVal('basic', item);
 | 
					            default:
 | 
				
			||||||
        }
 | 
					              addCategorizeVal('basic', item);
 | 
				
			||||||
      });
 | 
					          }
 | 
				
			||||||
      if (inherits) {
 | 
					 | 
				
			||||||
        inherits.forEach((v) => {
 | 
					 | 
				
			||||||
          sortKeyArr.push(v);
 | 
					 | 
				
			||||||
          const parentCollection = getCollection(v);
 | 
					 | 
				
			||||||
          parentCollection.fields.map((k) => {
 | 
					 | 
				
			||||||
            if (k.interface) {
 | 
					 | 
				
			||||||
              addCategorizeVal(v, new Proxy(k, {}));
 | 
					 | 
				
			||||||
              field.value.push(new Proxy(k, {}));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					        if (inherits) {
 | 
				
			||||||
      sortKeyArr.forEach((key) => {
 | 
					          inherits.forEach((v) => {
 | 
				
			||||||
        if (categorizeMap.get(key)?.length > 0) {
 | 
					            sortKeyArr.push(v);
 | 
				
			||||||
          const parentCollection = getCollection(key);
 | 
					            const parentCollection = getCollection(v);
 | 
				
			||||||
          tmpData.push({
 | 
					            parentCollection.fields.map((k) => {
 | 
				
			||||||
            key,
 | 
					              if (k.interface) {
 | 
				
			||||||
            name:
 | 
					                addCategorizeVal(v, new Proxy(k, {}));
 | 
				
			||||||
              t(CategorizeKeyNameMap.get(key)) ||
 | 
					                field.value.push(new Proxy(k, {}));
 | 
				
			||||||
              t(`Parent collection fields`) + `(${compile(parentCollection.title)})`,
 | 
					              }
 | 
				
			||||||
            data: categorizeMap.get(key),
 | 
					            });
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      });
 | 
					        sortKeyArr.forEach((key) => {
 | 
				
			||||||
      setExpendedKeys(sortKeyArr);
 | 
					          if (categorizeMap.get(key)?.length > 0) {
 | 
				
			||||||
      setCategorizeData(tmpData);
 | 
					            const parentCollection = getCollection(key);
 | 
				
			||||||
    },
 | 
					            tmpData.push({
 | 
				
			||||||
  });
 | 
					              key,
 | 
				
			||||||
  const useTableColumns = () => {
 | 
					              name:
 | 
				
			||||||
    const schema = useFieldSchema();
 | 
					                t(CategorizeKeyNameMap.get(key)) ||
 | 
				
			||||||
    const { exists, render } = useSchemaInitializer(schema['x-initializer']);
 | 
					                t(`Parent collection fields`) + `(${compile(parentCollection.title)})`,
 | 
				
			||||||
    const columns = schema
 | 
					              data: categorizeMap.get(key),
 | 
				
			||||||
      .reduceProperties((buf, s) => {
 | 
					            });
 | 
				
			||||||
        if (isColumnComponent(s)) {
 | 
					          }
 | 
				
			||||||
          return buf.concat([s]);
 | 
					        });
 | 
				
			||||||
        }
 | 
					        setExpendedKeys(sortKeyArr);
 | 
				
			||||||
      }, [])
 | 
					        setCategorizeData(tmpData);
 | 
				
			||||||
      .map((s: Schema) => {
 | 
					      },
 | 
				
			||||||
        return {
 | 
					 | 
				
			||||||
          title: <RecursionField name={s.name} schema={s} onlyRenderSelf />,
 | 
					 | 
				
			||||||
          dataIndex: s.name,
 | 
					 | 
				
			||||||
          key: s.name,
 | 
					 | 
				
			||||||
          render: (v, record) => {
 | 
					 | 
				
			||||||
            const index = findIndex(field.value, record);
 | 
					 | 
				
			||||||
            return (
 | 
					 | 
				
			||||||
              <RecordIndexProvider index={index}>
 | 
					 | 
				
			||||||
                <RecordProvider record={record}>
 | 
					 | 
				
			||||||
                  <RecursionField schema={s} name={index} onlyRenderProperties />
 | 
					 | 
				
			||||||
                </RecordProvider>
 | 
					 | 
				
			||||||
              </RecordIndexProvider>
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        } as TableColumnProps<any>;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    if (!exists) {
 | 
					 | 
				
			||||||
      return columns;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return columns.concat({
 | 
					 | 
				
			||||||
      title: render(),
 | 
					 | 
				
			||||||
      dataIndex: 'TABLE_COLUMN_INITIALIZER',
 | 
					 | 
				
			||||||
      key: 'TABLE_COLUMN_INITIALIZER',
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					    const useTableColumns = () => {
 | 
				
			||||||
 | 
					      const schema = useFieldSchema();
 | 
				
			||||||
  const ExpandedRowRender = (record: CategorizeDataItem, index, indent, expanded) => {
 | 
					      const { exists, render } = useSchemaInitializer(schema['x-initializer']);
 | 
				
			||||||
    const columns = useTableColumns();
 | 
					      const columns = schema
 | 
				
			||||||
    if (!props.loading) {
 | 
					        .reduceProperties((buf, s) => {
 | 
				
			||||||
      if (inherits.includes(record.key)) {
 | 
					          if (isColumnComponent(s)) {
 | 
				
			||||||
        columns.pop();
 | 
					            return buf.concat([s]);
 | 
				
			||||||
        columns.push({
 | 
					          }
 | 
				
			||||||
          title: <RecursionField name={'column4'} schema={overridingSchema as Schema} onlyRenderSelf />,
 | 
					        }, [])
 | 
				
			||||||
          dataIndex: 'column4',
 | 
					        .map((s: Schema) => {
 | 
				
			||||||
          key: 'column4',
 | 
					          return {
 | 
				
			||||||
          render: (v, record) => {
 | 
					            title: <RecursionField name={s.name} schema={s} onlyRenderSelf />,
 | 
				
			||||||
            const index = findIndex(field.value, record);
 | 
					            dataIndex: s.name,
 | 
				
			||||||
            return (
 | 
					            key: s.name,
 | 
				
			||||||
              <RecordIndexProvider index={index}>
 | 
					            render: (v, record) => {
 | 
				
			||||||
                <RecordProvider record={record}>
 | 
					              const index = findIndex(field.value, record);
 | 
				
			||||||
                  <SchemaComponent
 | 
					              return (
 | 
				
			||||||
                    scope={{ currentCollection: name }}
 | 
					                <RecordIndexProvider index={index}>
 | 
				
			||||||
                    schema={overridingSchema as Schema}
 | 
					                  <RecordProvider record={record}>
 | 
				
			||||||
                    name={index}
 | 
					                    <RecursionField schema={s} name={index} onlyRenderProperties />
 | 
				
			||||||
                    onlyRenderProperties
 | 
					                  </RecordProvider>
 | 
				
			||||||
                  />
 | 
					                </RecordIndexProvider>
 | 
				
			||||||
                </RecordProvider>
 | 
					              );
 | 
				
			||||||
              </RecordIndexProvider>
 | 
					            },
 | 
				
			||||||
            );
 | 
					          } as TableColumnProps<any>;
 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					      if (!exists) {
 | 
				
			||||||
 | 
					        return columns;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      const restProps = {
 | 
					      return columns.concat({
 | 
				
			||||||
        rowSelection:
 | 
					        title: render(),
 | 
				
			||||||
          props.rowSelection && !inherits.includes(record.key)
 | 
					        dataIndex: 'TABLE_COLUMN_INITIALIZER',
 | 
				
			||||||
            ? {
 | 
					        key: 'TABLE_COLUMN_INITIALIZER',
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ExpandedRowRender = (record: CategorizeDataItem, index, indent, expanded) => {
 | 
				
			||||||
 | 
					      const columns = useTableColumns();
 | 
				
			||||||
 | 
					      if (!props.loading) {
 | 
				
			||||||
 | 
					        if (inherits.includes(record.key)) {
 | 
				
			||||||
 | 
					          columns.pop();
 | 
				
			||||||
 | 
					          columns.push({
 | 
				
			||||||
 | 
					            title: <RecursionField name={'column4'} schema={overridingSchema as Schema} onlyRenderSelf />,
 | 
				
			||||||
 | 
					            dataIndex: 'column4',
 | 
				
			||||||
 | 
					            key: 'column4',
 | 
				
			||||||
 | 
					            render: (v, record) => {
 | 
				
			||||||
 | 
					              const index = findIndex(field.value, record);
 | 
				
			||||||
 | 
					              return (
 | 
				
			||||||
 | 
					                <RecordIndexProvider index={index}>
 | 
				
			||||||
 | 
					                  <RecordProvider record={record}>
 | 
				
			||||||
 | 
					                    <SchemaComponent
 | 
				
			||||||
 | 
					                      scope={{ currentCollection: name }}
 | 
				
			||||||
 | 
					                      schema={overridingSchema as Schema}
 | 
				
			||||||
 | 
					                      name={index}
 | 
				
			||||||
 | 
					                      onlyRenderProperties
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                  </RecordProvider>
 | 
				
			||||||
 | 
					                </RecordIndexProvider>
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const restProps = {
 | 
				
			||||||
 | 
					          rowSelection:
 | 
				
			||||||
 | 
					            props.rowSelection && !inherits.includes(record.key)
 | 
				
			||||||
 | 
					              ? {
 | 
				
			||||||
                type: 'checkbox',
 | 
					                type: 'checkbox',
 | 
				
			||||||
                selectedRowKeys,
 | 
					                selectedRowKeys,
 | 
				
			||||||
                onChange(selectedRowKeys: any[]) {
 | 
					                onChange(selectedRowKeys: any[]) {
 | 
				
			||||||
@ -229,52 +230,54 @@ export const CollectionFieldsTableArray: React.FC<any> = observer((props) => {
 | 
				
			|||||||
                },
 | 
					                },
 | 
				
			||||||
                ...props.rowSelection,
 | 
					                ...props.rowSelection,
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            : undefined,
 | 
					              : undefined,
 | 
				
			||||||
      };
 | 
					        };
 | 
				
			||||||
      return (
 | 
					        return (
 | 
				
			||||||
        <Table
 | 
					          <Table
 | 
				
			||||||
          {...others}
 | 
					            {...others}
 | 
				
			||||||
          {...restProps}
 | 
					            {...restProps}
 | 
				
			||||||
          components={components}
 | 
					            components={components}
 | 
				
			||||||
          showHeader={true}
 | 
					            showHeader={true}
 | 
				
			||||||
          columns={columns}
 | 
					            columns={columns}
 | 
				
			||||||
          dataSource={record.data}
 | 
					            dataSource={record.data}
 | 
				
			||||||
          pagination={false}
 | 
					            pagination={false}
 | 
				
			||||||
        />
 | 
					          />
 | 
				
			||||||
      );
 | 
					        );
 | 
				
			||||||
    }
 | 
					      }
 | 
				
			||||||
  };
 | 
					    };
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div
 | 
					      <div
 | 
				
			||||||
      className={css`
 | 
					        className={css`
 | 
				
			||||||
        .ant-table {
 | 
					          .ant-table {
 | 
				
			||||||
          overflow-x: auto;
 | 
					            overflow-x: auto;
 | 
				
			||||||
          overflow-y: hidden;
 | 
					            overflow-y: hidden;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      `}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <Table
 | 
					 | 
				
			||||||
        showHeader={false}
 | 
					 | 
				
			||||||
        loading={props?.loading}
 | 
					 | 
				
			||||||
        columns={groupColumns}
 | 
					 | 
				
			||||||
        dataSource={categorizeData}
 | 
					 | 
				
			||||||
        pagination={false}
 | 
					 | 
				
			||||||
        expandable={{
 | 
					 | 
				
			||||||
          expandedRowRender: ExpandedRowRender,
 | 
					 | 
				
			||||||
          expandedRowKeys: expandedKeys,
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        onExpand={(expanded, record) => {
 | 
					 | 
				
			||||||
          let keys = [];
 | 
					 | 
				
			||||||
          if (expanded) {
 | 
					 | 
				
			||||||
            keys = expandedKeys.concat([record.key]);
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            keys = expandedKeys.filter((v) => {
 | 
					 | 
				
			||||||
              return v !== record.key;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          setExpendedKeys(keys);
 | 
					        `}
 | 
				
			||||||
        }}
 | 
					      >
 | 
				
			||||||
      />
 | 
					        <Table
 | 
				
			||||||
    </div>
 | 
					          showHeader={false}
 | 
				
			||||||
  );
 | 
					          loading={props?.loading}
 | 
				
			||||||
});
 | 
					          columns={groupColumns}
 | 
				
			||||||
 | 
					          dataSource={categorizeData}
 | 
				
			||||||
 | 
					          pagination={false}
 | 
				
			||||||
 | 
					          expandable={{
 | 
				
			||||||
 | 
					            expandedRowRender: ExpandedRowRender,
 | 
				
			||||||
 | 
					            expandedRowKeys: expandedKeys,
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          onExpand={(expanded, record) => {
 | 
				
			||||||
 | 
					            let keys = [];
 | 
				
			||||||
 | 
					            if (expanded) {
 | 
				
			||||||
 | 
					              keys = expandedKeys.concat([record.key]);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              keys = expandedKeys.filter((v) => {
 | 
				
			||||||
 | 
					                return v !== record.key;
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            setExpendedKeys(keys);
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'CollectionFieldsTableArray' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -50,17 +50,20 @@ function Droppable(props) {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TabTitle = observer(({ item }: { item: any }) => {
 | 
					const TabTitle = observer(
 | 
				
			||||||
  return (
 | 
					  ({ item }: { item: any }) => {
 | 
				
			||||||
    <Droppable id={item.id.toString()} data={item}>
 | 
					    return (
 | 
				
			||||||
      <div>
 | 
					      <Droppable id={item.id.toString()} data={item}>
 | 
				
			||||||
        <Draggable id={item.id.toString()} data={item}>
 | 
					        <div>
 | 
				
			||||||
          <TabBar item={item} />
 | 
					          <Draggable id={item.id.toString()} data={item}>
 | 
				
			||||||
        </Draggable>
 | 
					            <TabBar item={item} />
 | 
				
			||||||
      </div>
 | 
					          </Draggable>
 | 
				
			||||||
    </Droppable>
 | 
					        </div>
 | 
				
			||||||
  );
 | 
					      </Droppable>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TabTitle' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TabBar = ({ item }) => {
 | 
					const TabBar = ({ item }) => {
 | 
				
			||||||
  const compile = useCompile();
 | 
					  const compile = useCompile();
 | 
				
			||||||
@ -71,45 +74,48 @@ const TabBar = ({ item }) => {
 | 
				
			|||||||
    </span>
 | 
					    </span>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const DndProvider = observer((props) => {
 | 
					const DndProvider = observer(
 | 
				
			||||||
  const [activeTab, setActiveId] = useState(null);
 | 
					  (props) => {
 | 
				
			||||||
  const { refresh } = useContext(CollectionCategroriesContext);
 | 
					    const [activeTab, setActiveId] = useState(null);
 | 
				
			||||||
  const { refresh: refreshCM } = useResourceActionContext();
 | 
					    const { refresh } = useContext(CollectionCategroriesContext);
 | 
				
			||||||
  const api = useAPIClient();
 | 
					    const { refresh: refreshCM } = useResourceActionContext();
 | 
				
			||||||
  const onDragEnd = async (props: DragEndEvent) => {
 | 
					    const api = useAPIClient();
 | 
				
			||||||
    const { active, over } = props;
 | 
					    const onDragEnd = async (props: DragEndEvent) => {
 | 
				
			||||||
    setTimeout(() => {
 | 
					      const { active, over } = props;
 | 
				
			||||||
      setActiveId(null);
 | 
					      setTimeout(() => {
 | 
				
			||||||
    });
 | 
					        setActiveId(null);
 | 
				
			||||||
    if (over && over.id !== active.id) {
 | 
					 | 
				
			||||||
      await api.resource('collectionCategories').move({
 | 
					 | 
				
			||||||
        sourceId: active.id,
 | 
					 | 
				
			||||||
        targetId: over.id,
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      await refresh();
 | 
					      if (over && over.id !== active.id) {
 | 
				
			||||||
      await refreshCM();
 | 
					        await api.resource('collectionCategories').move({
 | 
				
			||||||
 | 
					          sourceId: active.id,
 | 
				
			||||||
 | 
					          targetId: over.id,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        await refresh();
 | 
				
			||||||
 | 
					        await refreshCM();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function onDragStart(event) {
 | 
				
			||||||
 | 
					      setActiveId(event.active?.data.current);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function onDragStart(event) {
 | 
					    const mouseSensor = useSensor(MouseSensor, {
 | 
				
			||||||
    setActiveId(event.active?.data.current);
 | 
					      activationConstraint: {
 | 
				
			||||||
  }
 | 
					        distance: 10,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
  const mouseSensor = useSensor(MouseSensor, {
 | 
					    });
 | 
				
			||||||
    activationConstraint: {
 | 
					    const sensors = useSensors(mouseSensor);
 | 
				
			||||||
      distance: 10,
 | 
					    return (
 | 
				
			||||||
    },
 | 
					      <DndContext sensors={sensors} onDragEnd={onDragEnd} onDragStart={onDragStart}>
 | 
				
			||||||
  });
 | 
					        {props.children}
 | 
				
			||||||
  const sensors = useSensors(mouseSensor);
 | 
					        <DragOverlay>
 | 
				
			||||||
  return (
 | 
					          {activeTab ? <span style={{ whiteSpace: 'nowrap' }}>{<TabBar item={activeTab} />}</span> : null}
 | 
				
			||||||
    <DndContext sensors={sensors} onDragEnd={onDragEnd} onDragStart={onDragStart}>
 | 
					        </DragOverlay>
 | 
				
			||||||
      {props.children}
 | 
					      </DndContext>
 | 
				
			||||||
      <DragOverlay>
 | 
					    );
 | 
				
			||||||
        {activeTab ? <span style={{ whiteSpace: 'nowrap' }}>{<TabBar item={activeTab} />}</span> : null}
 | 
					  },
 | 
				
			||||||
      </DragOverlay>
 | 
					  { displayName: 'DndProvider' },
 | 
				
			||||||
    </DndContext>
 | 
					);
 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
export const ConfigurationTabs = () => {
 | 
					export const ConfigurationTabs = () => {
 | 
				
			||||||
  const { data, refresh } = useContext(CollectionCategroriesContext);
 | 
					  const { data, refresh } = useContext(CollectionCategroriesContext);
 | 
				
			||||||
  const { refresh: refreshCM, run, defaultRequest, setState } = useResourceActionContext();
 | 
					  const { refresh: refreshCM, run, defaultRequest, setState } = useResourceActionContext();
 | 
				
			||||||
 | 
				
			|||||||
@ -3,14 +3,17 @@ import { Tag } from 'antd';
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CollectionCategory = observer((props: any) => {
 | 
					export const CollectionCategory = observer(
 | 
				
			||||||
  const { value } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { value } = props;
 | 
				
			||||||
  return (
 | 
					    const compile = useCompile();
 | 
				
			||||||
    <>
 | 
					    return (
 | 
				
			||||||
      {value.map((item) => {
 | 
					      <>
 | 
				
			||||||
        return <Tag color={item.color}>{compile(item?.name)}</Tag>;
 | 
					        {value.map((item) => {
 | 
				
			||||||
      })}
 | 
					          return <Tag color={item.color}>{compile(item?.name)}</Tag>;
 | 
				
			||||||
    </>
 | 
					        })}
 | 
				
			||||||
  );
 | 
					      </>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'CollectionCategory' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,13 +4,16 @@ import React from 'react';
 | 
				
			|||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
import { useCollectionManager } from '../../hooks';
 | 
					import { useCollectionManager } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CollectionFieldInterface = observer((props: any) => {
 | 
					export const CollectionFieldInterface = observer(
 | 
				
			||||||
  const { value } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { getInterface } = useCollectionManager();
 | 
					    const { value } = props;
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { getInterface } = useCollectionManager();
 | 
				
			||||||
  const schema = getInterface(value);
 | 
					    const compile = useCompile();
 | 
				
			||||||
 | 
					    const schema = getInterface(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!schema) return null;
 | 
					    if (!schema) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Tag>{compile(schema.title)}</Tag>;
 | 
					    return <Tag>{compile(schema.title)}</Tag>;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'CollectionFieldInterface' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,14 @@ import React from 'react';
 | 
				
			|||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
import { useCollectionManager } from '../../hooks';
 | 
					import { useCollectionManager } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CollectionTemplate = observer((props: any) => {
 | 
					export const CollectionTemplate = observer(
 | 
				
			||||||
  const { value } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { getTemplate } = useCollectionManager();
 | 
					    const { value } = props;
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { getTemplate } = useCollectionManager();
 | 
				
			||||||
  const schema = getTemplate(value);
 | 
					    const compile = useCompile();
 | 
				
			||||||
 | 
					    const schema = getTemplate(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Tag>{compile(schema?.title || '{{t("General collection")}}')}</Tag>;
 | 
					    return <Tag>{compile(schema?.title || '{{t("General collection")}}')}</Tag>;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'CollectionTemplate' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,36 +6,39 @@ import { useTranslation } from 'react-i18next';
 | 
				
			|||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
import { useCollectionManager } from '../../hooks';
 | 
					import { useCollectionManager } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FieldSummary = observer((props: any) => {
 | 
					export const FieldSummary = observer(
 | 
				
			||||||
  const { schemaKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { getInterface } = useCollectionManager();
 | 
					    const { schemaKey } = props;
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { getInterface } = useCollectionManager();
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const schema = getInterface(schemaKey);
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
 | 
					    const schema = getInterface(schemaKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!schema) return null;
 | 
					    if (!schema) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div
 | 
					      <div
 | 
				
			||||||
      className={css`
 | 
					        className={css`
 | 
				
			||||||
        background: #f6f6f6;
 | 
					          background: #f6f6f6;
 | 
				
			||||||
        margin-bottom: 24px;
 | 
					          margin-bottom: 24px;
 | 
				
			||||||
        padding: 16px;
 | 
					          padding: 16px;
 | 
				
			||||||
      `}
 | 
					        `}
 | 
				
			||||||
    >
 | 
					      >
 | 
				
			||||||
      <div className={css``}>
 | 
					        <div className={css``}>
 | 
				
			||||||
        {t('Field interface')}: <Tag>{compile(schema.title)}</Tag>
 | 
					          {t('Field interface')}: <Tag>{compile(schema.title)}</Tag>
 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      {schema.description ? (
 | 
					 | 
				
			||||||
        <div
 | 
					 | 
				
			||||||
          className={css`
 | 
					 | 
				
			||||||
            margin-top: 8px;
 | 
					 | 
				
			||||||
            color: rgba(0, 0, 0, 0.45);
 | 
					 | 
				
			||||||
          `}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {compile(schema.description)}
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      ) : null}
 | 
					        {schema.description ? (
 | 
				
			||||||
    </div>
 | 
					          <div
 | 
				
			||||||
  );
 | 
					            className={css`
 | 
				
			||||||
});
 | 
					              margin-top: 8px;
 | 
				
			||||||
 | 
					              color: rgba(0, 0, 0, 0.45);
 | 
				
			||||||
 | 
					            `}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {compile(schema.description)}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        ) : null}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'FieldSummary' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,36 +6,39 @@ import { useTranslation } from 'react-i18next';
 | 
				
			|||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
import { useCollectionManager } from '../../hooks';
 | 
					import { useCollectionManager } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TemplateSummay = observer((props: any) => {
 | 
					export const TemplateSummay = observer(
 | 
				
			||||||
  const { schemaKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { getTemplate } = useCollectionManager();
 | 
					    const { schemaKey } = props;
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { getTemplate } = useCollectionManager();
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const schema = getTemplate(schemaKey);
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
 | 
					    const schema = getTemplate(schemaKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!schema) return null;
 | 
					    if (!schema) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div
 | 
					      <div
 | 
				
			||||||
      className={css`
 | 
					        className={css`
 | 
				
			||||||
        background: #f6f6f6;
 | 
					          background: #f6f6f6;
 | 
				
			||||||
        margin-bottom: 24px;
 | 
					          margin-bottom: 24px;
 | 
				
			||||||
        padding: 16px;
 | 
					          padding: 16px;
 | 
				
			||||||
      `}
 | 
					        `}
 | 
				
			||||||
    >
 | 
					      >
 | 
				
			||||||
      <div className={css``}>
 | 
					        <div className={css``}>
 | 
				
			||||||
        {t('Collection template')}: <Tag>{compile(schema.title)}</Tag>
 | 
					          {t('Collection template')}: <Tag>{compile(schema.title)}</Tag>
 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      {schema.description ? (
 | 
					 | 
				
			||||||
        <div
 | 
					 | 
				
			||||||
          className={css`
 | 
					 | 
				
			||||||
            margin-top: 8px;
 | 
					 | 
				
			||||||
            color: rgba(0, 0, 0, 0.45);
 | 
					 | 
				
			||||||
          `}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {compile(schema.description)}
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      ) : null}
 | 
					        {schema.description ? (
 | 
				
			||||||
    </div>
 | 
					          <div
 | 
				
			||||||
  );
 | 
					            className={css`
 | 
				
			||||||
});
 | 
					              margin-top: 8px;
 | 
				
			||||||
 | 
					              color: rgba(0, 0, 0, 0.45);
 | 
				
			||||||
 | 
					            `}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {compile(schema.description)}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        ) : null}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TemplateSummay' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,109 +6,127 @@ import { useRecord } from '../../../record-provider';
 | 
				
			|||||||
import { useCompile } from '../../../schema-component';
 | 
					import { useCompile } from '../../../schema-component';
 | 
				
			||||||
import { useCollectionManager } from '../../hooks';
 | 
					import { useCollectionManager } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SourceForeignKey = observer(() => {
 | 
					export const SourceForeignKey = observer(
 | 
				
			||||||
  const record = useRecord();
 | 
					  () => {
 | 
				
			||||||
  const { getCollection } = useCollectionManager();
 | 
					    const record = useRecord();
 | 
				
			||||||
  const collection = record?.collectionName ? getCollection(record.collectionName) : record;
 | 
					    const { getCollection } = useCollectionManager();
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const collection = record?.collectionName ? getCollection(record.collectionName) : record;
 | 
				
			||||||
  const form = useForm();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const { getCollectionFields } = useCollectionManager();
 | 
					    const form = useForm();
 | 
				
			||||||
  return (
 | 
					    const { getCollectionFields } = useCollectionManager();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select
 | 
					      <div>
 | 
				
			||||||
        allowClear
 | 
					        <Select
 | 
				
			||||||
        placeholder={'留空时,自动生成 FK 字段'}
 | 
					          allowClear
 | 
				
			||||||
        disabled={field.disabled}
 | 
					          placeholder={'留空时,自动生成 FK 字段'}
 | 
				
			||||||
        value={field.value}
 | 
					          disabled={field.disabled}
 | 
				
			||||||
        options={getCollectionFields(collection.name)
 | 
					          value={field.value}
 | 
				
			||||||
          .filter((field) => field.type)
 | 
					          options={getCollectionFields(collection.name)
 | 
				
			||||||
          .map((field) => {
 | 
					            .filter((field) => field.type)
 | 
				
			||||||
            return {
 | 
					            .map((field) => {
 | 
				
			||||||
              label: field?.uiSchema?.title || field.name,
 | 
					              return {
 | 
				
			||||||
              value: field.name,
 | 
					                label: field?.uiSchema?.title || field.name,
 | 
				
			||||||
            };
 | 
					                value: field.name,
 | 
				
			||||||
          })}
 | 
					              };
 | 
				
			||||||
      />
 | 
					            })}
 | 
				
			||||||
    </div>
 | 
					        />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'SourceForeignKey' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ThroughForeignKey = observer(() => {
 | 
					export const ThroughForeignKey = observer(
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  () => {
 | 
				
			||||||
  const form = useForm();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const { getCollectionFields } = useCollectionManager();
 | 
					    const form = useForm();
 | 
				
			||||||
  return (
 | 
					    const { getCollectionFields } = useCollectionManager();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select
 | 
					      <div>
 | 
				
			||||||
        allowClear
 | 
					        <Select
 | 
				
			||||||
        placeholder={'留空时,自动生成 FK 字段'}
 | 
					          allowClear
 | 
				
			||||||
        disabled={field.disabled}
 | 
					          placeholder={'留空时,自动生成 FK 字段'}
 | 
				
			||||||
        value={field.value}
 | 
					          disabled={field.disabled}
 | 
				
			||||||
        options={getCollectionFields(form.values.through)
 | 
					          value={field.value}
 | 
				
			||||||
          .filter((field) => field.type)
 | 
					          options={getCollectionFields(form.values.through)
 | 
				
			||||||
          .map((field) => {
 | 
					            .filter((field) => field.type)
 | 
				
			||||||
            return {
 | 
					            .map((field) => {
 | 
				
			||||||
              label: field?.uiSchema?.title || field.name,
 | 
					              return {
 | 
				
			||||||
              value: field.name,
 | 
					                label: field?.uiSchema?.title || field.name,
 | 
				
			||||||
            };
 | 
					                value: field.name,
 | 
				
			||||||
          })}
 | 
					              };
 | 
				
			||||||
      />
 | 
					            })}
 | 
				
			||||||
    </div>
 | 
					        />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ThroughForeignKey' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TargetForeignKey = observer(() => {
 | 
					export const TargetForeignKey = observer(
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  () => {
 | 
				
			||||||
  const form = useForm();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const { getCollectionFields } = useCollectionManager();
 | 
					    const form = useForm();
 | 
				
			||||||
  return (
 | 
					    const { getCollectionFields } = useCollectionManager();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select
 | 
					      <div>
 | 
				
			||||||
        allowClear
 | 
					        <Select
 | 
				
			||||||
        placeholder={'留空时,自动生成 FK 字段'}
 | 
					          allowClear
 | 
				
			||||||
        disabled={field.disabled}
 | 
					          placeholder={'留空时,自动生成 FK 字段'}
 | 
				
			||||||
        value={field.value}
 | 
					          disabled={field.disabled}
 | 
				
			||||||
        options={getCollectionFields(form.values.target)
 | 
					          value={field.value}
 | 
				
			||||||
          .filter((field) => field.type)
 | 
					          options={getCollectionFields(form.values.target)
 | 
				
			||||||
          .map((field) => {
 | 
					            .filter((field) => field.type)
 | 
				
			||||||
            return {
 | 
					            .map((field) => {
 | 
				
			||||||
              label: field?.uiSchema?.title || field.name,
 | 
					              return {
 | 
				
			||||||
              value: field.name,
 | 
					                label: field?.uiSchema?.title || field.name,
 | 
				
			||||||
            };
 | 
					                value: field.name,
 | 
				
			||||||
          })}
 | 
					              };
 | 
				
			||||||
      />
 | 
					            })}
 | 
				
			||||||
    </div>
 | 
					        />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TargetForeignKey' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SourceCollection = observer(() => {
 | 
					export const SourceCollection = observer(
 | 
				
			||||||
  const record = useRecord();
 | 
					  () => {
 | 
				
			||||||
  const { getCollection } = useCollectionManager();
 | 
					    const record = useRecord();
 | 
				
			||||||
  const collection = record?.collectionName ? getCollection(record.collectionName) : record;
 | 
					    const { getCollection } = useCollectionManager();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const collection = record?.collectionName ? getCollection(record.collectionName) : record;
 | 
				
			||||||
  return (
 | 
					    const compile = useCompile();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select
 | 
					      <div>
 | 
				
			||||||
        disabled
 | 
					        <Select
 | 
				
			||||||
        value={collection.name}
 | 
					          disabled
 | 
				
			||||||
        options={[{ value: collection.name, label: compile(collection.title) }]}
 | 
					          value={collection.name}
 | 
				
			||||||
      />
 | 
					          options={[{ value: collection.name, label: compile(collection.title) }]}
 | 
				
			||||||
    </div>
 | 
					        />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'SourceCollection' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SourceKey = observer(() => {
 | 
					export const SourceKey = observer(
 | 
				
			||||||
  return (
 | 
					  () => {
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select disabled value={'id'} options={[{ value: 'id', label: 'ID' }]} />
 | 
					      <div>
 | 
				
			||||||
    </div>
 | 
					        <Select disabled value={'id'} options={[{ value: 'id', label: 'ID' }]} />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'SourceKey' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TargetKey = observer(() => {
 | 
					export const TargetKey = observer(
 | 
				
			||||||
  return (
 | 
					  () => {
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Select disabled value={'id'} options={[{ value: 'id', label: 'ID' }]} />
 | 
					      <div>
 | 
				
			||||||
    </div>
 | 
					        <Select disabled value={'id'} options={[{ value: 'id', label: 'ID' }]} />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TargetKey' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -166,107 +166,113 @@ export const ds = {
 | 
				
			|||||||
  useDestroyAction,
 | 
					  useDestroyAction,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SubFieldDataSourceProvider = observer((props) => {
 | 
					export const SubFieldDataSourceProvider = observer(
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
					  (props) => {
 | 
				
			||||||
  const [dataSource, setDataSource] = useState([]);
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
				
			||||||
  const record = useRecord();
 | 
					    const [dataSource, setDataSource] = useState([]);
 | 
				
			||||||
  const api = useAPIClient();
 | 
					    const record = useRecord();
 | 
				
			||||||
  const service = useRequest(
 | 
					    const api = useAPIClient();
 | 
				
			||||||
    () => {
 | 
					    const service = useRequest(
 | 
				
			||||||
      if (record.interface === 'subTable') {
 | 
					      () => {
 | 
				
			||||||
        if (record?.children?.length) {
 | 
					        if (record.interface === 'subTable') {
 | 
				
			||||||
          return Promise.resolve({
 | 
					          if (record?.children?.length) {
 | 
				
			||||||
            data: record?.children || [],
 | 
					            return Promise.resolve({
 | 
				
			||||||
          });
 | 
					              data: record?.children || [],
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return api
 | 
				
			||||||
 | 
					            .resource('fields')
 | 
				
			||||||
 | 
					            .list({
 | 
				
			||||||
 | 
					              paginate: false,
 | 
				
			||||||
 | 
					              // appends: ['uiSchema'],
 | 
				
			||||||
 | 
					              sort: 'sort',
 | 
				
			||||||
 | 
					              filter: {
 | 
				
			||||||
 | 
					                parentKey: record.key,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .then((res) => res?.data);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return api
 | 
					        return Promise.resolve({
 | 
				
			||||||
          .resource('fields')
 | 
					          data: [],
 | 
				
			||||||
          .list({
 | 
					        });
 | 
				
			||||||
            paginate: false,
 | 
					 | 
				
			||||||
            // appends: ['uiSchema'],
 | 
					 | 
				
			||||||
            sort: 'sort',
 | 
					 | 
				
			||||||
            filter: {
 | 
					 | 
				
			||||||
              parentKey: record.key,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          })
 | 
					 | 
				
			||||||
          .then((res) => res?.data);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return Promise.resolve({
 | 
					 | 
				
			||||||
        data: [],
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      onSuccess(data) {
 | 
					 | 
				
			||||||
        console.log('dataSource1', data?.data);
 | 
					 | 
				
			||||||
        setDataSource(data?.data);
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      {
 | 
				
			||||||
  );
 | 
					        onSuccess(data) {
 | 
				
			||||||
  return (
 | 
					          console.log('dataSource1', data?.data);
 | 
				
			||||||
    <CollectionProvider collection={collection}>
 | 
					          setDataSource(data?.data);
 | 
				
			||||||
      <DataSourceContext.Provider
 | 
					        },
 | 
				
			||||||
        value={{
 | 
					      },
 | 
				
			||||||
          rowKey: 'name',
 | 
					    );
 | 
				
			||||||
          service,
 | 
					    return (
 | 
				
			||||||
          dataSource,
 | 
					      <CollectionProvider collection={collection}>
 | 
				
			||||||
          setDataSource,
 | 
					        <DataSourceContext.Provider
 | 
				
			||||||
          selectedRowKeys,
 | 
					          value={{
 | 
				
			||||||
          setSelectedRowKeys,
 | 
					            rowKey: 'name',
 | 
				
			||||||
        }}
 | 
					            service,
 | 
				
			||||||
      >
 | 
					            dataSource,
 | 
				
			||||||
        {props.children}
 | 
					            setDataSource,
 | 
				
			||||||
      </DataSourceContext.Provider>
 | 
					            selectedRowKeys,
 | 
				
			||||||
    </CollectionProvider>
 | 
					            setSelectedRowKeys,
 | 
				
			||||||
  );
 | 
					          }}
 | 
				
			||||||
});
 | 
					        >
 | 
				
			||||||
 | 
					          {props.children}
 | 
				
			||||||
 | 
					        </DataSourceContext.Provider>
 | 
				
			||||||
 | 
					      </CollectionProvider>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'SubFieldDataSourceProvider' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const DataSourceProvider = observer((props: any) => {
 | 
					export const DataSourceProvider = observer(
 | 
				
			||||||
  const { rowKey, collection, association } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
					    const { rowKey, collection, association } = props;
 | 
				
			||||||
  const [dataSource, setDataSource] = useState([]);
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
				
			||||||
  const record = useRecord();
 | 
					    const [dataSource, setDataSource] = useState([]);
 | 
				
			||||||
  const api = useAPIClient();
 | 
					    const record = useRecord();
 | 
				
			||||||
  const { getCollection } = useCollectionManager();
 | 
					    const api = useAPIClient();
 | 
				
			||||||
  const coll = getCollection(collection);
 | 
					    const { getCollection } = useCollectionManager();
 | 
				
			||||||
  const resourceOf = record?.[association.targetKey || 'id'];
 | 
					    const coll = getCollection(collection);
 | 
				
			||||||
  const service = useRequest(
 | 
					    const resourceOf = record?.[association.targetKey || 'id'];
 | 
				
			||||||
    () => {
 | 
					    const service = useRequest(
 | 
				
			||||||
      if (resourceOf) {
 | 
					      () => {
 | 
				
			||||||
        return api
 | 
					        if (resourceOf) {
 | 
				
			||||||
          .request({
 | 
					          return api
 | 
				
			||||||
            resource: `${association.collectionName}.${association.name}`,
 | 
					            .request({
 | 
				
			||||||
            resourceOf,
 | 
					              resource: `${association.collectionName}.${association.name}`,
 | 
				
			||||||
            action: 'list',
 | 
					              resourceOf,
 | 
				
			||||||
            params: {
 | 
					              action: 'list',
 | 
				
			||||||
              appends: coll?.fields?.filter((field) => field.target)?.map((field) => field.name),
 | 
					              params: {
 | 
				
			||||||
            },
 | 
					                appends: coll?.fields?.filter((field) => field.target)?.map((field) => field.name),
 | 
				
			||||||
          })
 | 
					              },
 | 
				
			||||||
          .then((res) => res.data);
 | 
					            })
 | 
				
			||||||
      }
 | 
					            .then((res) => res.data);
 | 
				
			||||||
      return Promise.resolve({
 | 
					        }
 | 
				
			||||||
        data: record?.[association.name] || [],
 | 
					        return Promise.resolve({
 | 
				
			||||||
      });
 | 
					          data: record?.[association.name] || [],
 | 
				
			||||||
    },
 | 
					        });
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      onSuccess(data) {
 | 
					 | 
				
			||||||
        setDataSource(data?.data);
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      {
 | 
				
			||||||
  );
 | 
					        onSuccess(data) {
 | 
				
			||||||
  return (
 | 
					          setDataSource(data?.data);
 | 
				
			||||||
    <CollectionProvider collection={coll}>
 | 
					        },
 | 
				
			||||||
      <DataSourceContext.Provider
 | 
					      },
 | 
				
			||||||
        value={{
 | 
					    );
 | 
				
			||||||
          rowKey,
 | 
					    return (
 | 
				
			||||||
          service,
 | 
					      <CollectionProvider collection={coll}>
 | 
				
			||||||
          dataSource,
 | 
					        <DataSourceContext.Provider
 | 
				
			||||||
          setDataSource,
 | 
					          value={{
 | 
				
			||||||
          selectedRowKeys,
 | 
					            rowKey,
 | 
				
			||||||
          setSelectedRowKeys,
 | 
					            service,
 | 
				
			||||||
        }}
 | 
					            dataSource,
 | 
				
			||||||
      >
 | 
					            setDataSource,
 | 
				
			||||||
        {props.children}
 | 
					            selectedRowKeys,
 | 
				
			||||||
      </DataSourceContext.Provider>
 | 
					            setSelectedRowKeys,
 | 
				
			||||||
    </CollectionProvider>
 | 
					          }}
 | 
				
			||||||
  );
 | 
					        >
 | 
				
			||||||
});
 | 
					          {props.children}
 | 
				
			||||||
 | 
					        </DataSourceContext.Provider>
 | 
				
			||||||
 | 
					      </CollectionProvider>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'DataSourceProvider' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -217,3 +217,4 @@ function areEqual(prevProps, nextProps) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const PreviewFields = React.memo(PreviewCom, areEqual);
 | 
					export const PreviewFields = React.memo(PreviewCom, areEqual);
 | 
				
			||||||
 | 
					PreviewFields.displayName = 'PreviewFields';
 | 
				
			||||||
 | 
				
			|||||||
@ -6,21 +6,27 @@ import { ActionModal } from './Action.Modal';
 | 
				
			|||||||
import { ActionPage } from './Action.Page';
 | 
					import { ActionPage } from './Action.Page';
 | 
				
			||||||
import { ComposedActionDrawer } from './types';
 | 
					import { ComposedActionDrawer } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ActionContainer: ComposedActionDrawer = observer((props: any) => {
 | 
					export const ActionContainer: ComposedActionDrawer = observer(
 | 
				
			||||||
  const { openMode } = useActionContext();
 | 
					  (props: any) => {
 | 
				
			||||||
  if (openMode === 'drawer') {
 | 
					    const { openMode } = useActionContext();
 | 
				
			||||||
    return <ActionDrawer footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
					    if (openMode === 'drawer') {
 | 
				
			||||||
  }
 | 
					      return <ActionDrawer footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
				
			||||||
  if (openMode === 'modal') {
 | 
					    }
 | 
				
			||||||
    return <ActionModal footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
					    if (openMode === 'modal') {
 | 
				
			||||||
  }
 | 
					      return <ActionModal footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
				
			||||||
  return <ActionPage footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
					    }
 | 
				
			||||||
});
 | 
					    return <ActionPage footerNodeName={'Action.Container.Footer'} {...props} />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionContainer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActionContainer.Footer = observer(() => {
 | 
					ActionContainer.Footer = observer(
 | 
				
			||||||
  const field = useField();
 | 
					  () => {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField();
 | 
				
			||||||
  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
});
 | 
					    return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionContainer.Footer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ActionContainer;
 | 
					export default ActionContainer;
 | 
				
			||||||
 | 
				
			|||||||
@ -14,111 +14,117 @@ const openSizeWidthMap = new Map<OpenSize, string>([
 | 
				
			|||||||
  ['middle', '50%'],
 | 
					  ['middle', '50%'],
 | 
				
			||||||
  ['large', '70%'],
 | 
					  ['large', '70%'],
 | 
				
			||||||
]);
 | 
					]);
 | 
				
			||||||
export const ActionDrawer: ComposedActionDrawer = observer((props) => {
 | 
					export const ActionDrawer: ComposedActionDrawer = observer(
 | 
				
			||||||
  const { footerNodeName = 'Action.Drawer.Footer', ...others } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const { footerNodeName = 'Action.Drawer.Footer', ...others } = props;
 | 
				
			||||||
  const { visible, setVisible, openSize = 'middle' } = useActionContext();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const { visible, setVisible, openSize = 'middle' } = useActionContext();
 | 
				
			||||||
  const field = useField();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const openSizeFromParent = schema.parent?.['x-component-props']?.['openSize'];
 | 
					    const field = useField();
 | 
				
			||||||
  const finalOpenSize = openSizeFromParent || openSize;
 | 
					    const openSizeFromParent = schema.parent?.['x-component-props']?.['openSize'];
 | 
				
			||||||
  const footerSchema = schema.reduceProperties((buf, s) => {
 | 
					    const finalOpenSize = openSizeFromParent || openSize;
 | 
				
			||||||
    if (s['x-component'] === footerNodeName) {
 | 
					    const footerSchema = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      return s;
 | 
					      if (s['x-component'] === footerNodeName) {
 | 
				
			||||||
    }
 | 
					        return s;
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  });
 | 
					      return buf;
 | 
				
			||||||
  return (
 | 
					    });
 | 
				
			||||||
    <>
 | 
					    return (
 | 
				
			||||||
      {createPortal(
 | 
					      <>
 | 
				
			||||||
        <div
 | 
					        {createPortal(
 | 
				
			||||||
          onClick={(e) => {
 | 
					          <div
 | 
				
			||||||
            e.stopPropagation();
 | 
					            onClick={(e) => {
 | 
				
			||||||
          }}
 | 
					              e.stopPropagation();
 | 
				
			||||||
        >
 | 
					            }}
 | 
				
			||||||
          <Drawer
 | 
					 | 
				
			||||||
            width={openSizeWidthMap.get(finalOpenSize)}
 | 
					 | 
				
			||||||
            title={field.title}
 | 
					 | 
				
			||||||
            {...others}
 | 
					 | 
				
			||||||
            destroyOnClose
 | 
					 | 
				
			||||||
            open={visible}
 | 
					 | 
				
			||||||
            onClose={() => setVisible(false, true)}
 | 
					 | 
				
			||||||
            className={classNames(
 | 
					 | 
				
			||||||
              others.className,
 | 
					 | 
				
			||||||
              css`
 | 
					 | 
				
			||||||
                &.nb-action-popup {
 | 
					 | 
				
			||||||
                  .ant-drawer-header {
 | 
					 | 
				
			||||||
                    display: none;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  .ant-drawer-body {
 | 
					 | 
				
			||||||
                    padding-top: 14px;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  .ant-drawer-content {
 | 
					 | 
				
			||||||
                    background: #f0f2f5;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                &.nb-record-picker-selector {
 | 
					 | 
				
			||||||
                  .nb-block-item {
 | 
					 | 
				
			||||||
                    margin-bottom: 24px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    .general-schema-designer {
 | 
					 | 
				
			||||||
                      top: -8px;
 | 
					 | 
				
			||||||
                      bottom: -8px;
 | 
					 | 
				
			||||||
                      left: -8px;
 | 
					 | 
				
			||||||
                      right: -8px;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              `,
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            footer={
 | 
					 | 
				
			||||||
              footerSchema && (
 | 
					 | 
				
			||||||
                <div
 | 
					 | 
				
			||||||
                  className={css`
 | 
					 | 
				
			||||||
                    display: flex;
 | 
					 | 
				
			||||||
                    justify-content: flex-end;
 | 
					 | 
				
			||||||
                    width: 100%;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    .ant-btn {
 | 
					 | 
				
			||||||
                      margin-right: 8px;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                  `}
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                  <RecursionField
 | 
					 | 
				
			||||||
                    basePath={field.address}
 | 
					 | 
				
			||||||
                    schema={schema}
 | 
					 | 
				
			||||||
                    onlyRenderProperties
 | 
					 | 
				
			||||||
                    filterProperties={(s) => {
 | 
					 | 
				
			||||||
                      return s['x-component'] === footerNodeName;
 | 
					 | 
				
			||||||
                    }}
 | 
					 | 
				
			||||||
                  />
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <RecursionField
 | 
					            <Drawer
 | 
				
			||||||
              basePath={field.address}
 | 
					              width={openSizeWidthMap.get(finalOpenSize)}
 | 
				
			||||||
              schema={schema}
 | 
					              title={field.title}
 | 
				
			||||||
              onlyRenderProperties
 | 
					              {...others}
 | 
				
			||||||
              filterProperties={(s) => {
 | 
					              destroyOnClose
 | 
				
			||||||
                return s['x-component'] !== footerNodeName;
 | 
					              open={visible}
 | 
				
			||||||
              }}
 | 
					              onClose={() => setVisible(false, true)}
 | 
				
			||||||
            />
 | 
					              className={classNames(
 | 
				
			||||||
          </Drawer>
 | 
					                others.className,
 | 
				
			||||||
        </div>,
 | 
					                css`
 | 
				
			||||||
        document.body,
 | 
					                  &.nb-action-popup {
 | 
				
			||||||
      )}
 | 
					                    .ant-drawer-header {
 | 
				
			||||||
    </>
 | 
					                      display: none;
 | 
				
			||||||
  );
 | 
					                    }
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActionDrawer.Footer = observer(() => {
 | 
					                    .ant-drawer-body {
 | 
				
			||||||
  const field = useField();
 | 
					                      padding-top: 14px;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					                    }
 | 
				
			||||||
  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
					
 | 
				
			||||||
});
 | 
					                    .ant-drawer-content {
 | 
				
			||||||
 | 
					                      background: #f0f2f5;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  &.nb-record-picker-selector {
 | 
				
			||||||
 | 
					                    .nb-block-item {
 | 
				
			||||||
 | 
					                      margin-bottom: 24px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      .general-schema-designer {
 | 
				
			||||||
 | 
					                        top: -8px;
 | 
				
			||||||
 | 
					                        bottom: -8px;
 | 
				
			||||||
 | 
					                        left: -8px;
 | 
				
			||||||
 | 
					                        right: -8px;
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                `,
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					              footer={
 | 
				
			||||||
 | 
					                footerSchema && (
 | 
				
			||||||
 | 
					                  <div
 | 
				
			||||||
 | 
					                    className={css`
 | 
				
			||||||
 | 
					                      display: flex;
 | 
				
			||||||
 | 
					                      justify-content: flex-end;
 | 
				
			||||||
 | 
					                      width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      .ant-btn {
 | 
				
			||||||
 | 
					                        margin-right: 8px;
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    `}
 | 
				
			||||||
 | 
					                  >
 | 
				
			||||||
 | 
					                    <RecursionField
 | 
				
			||||||
 | 
					                      basePath={field.address}
 | 
				
			||||||
 | 
					                      schema={schema}
 | 
				
			||||||
 | 
					                      onlyRenderProperties
 | 
				
			||||||
 | 
					                      filterProperties={(s) => {
 | 
				
			||||||
 | 
					                        return s['x-component'] === footerNodeName;
 | 
				
			||||||
 | 
					                      }}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <RecursionField
 | 
				
			||||||
 | 
					                basePath={field.address}
 | 
				
			||||||
 | 
					                schema={schema}
 | 
				
			||||||
 | 
					                onlyRenderProperties
 | 
				
			||||||
 | 
					                filterProperties={(s) => {
 | 
				
			||||||
 | 
					                  return s['x-component'] !== footerNodeName;
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </Drawer>
 | 
				
			||||||
 | 
					          </div>,
 | 
				
			||||||
 | 
					          document.body,
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					      </>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionDrawer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ActionDrawer.Footer = observer(
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
 | 
					    return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionDrawer.Footer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ActionDrawer;
 | 
					export default ActionDrawer;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,9 @@ import React from 'react';
 | 
				
			|||||||
import Action from './Action';
 | 
					import Action from './Action';
 | 
				
			||||||
import { ComposedAction } from './types';
 | 
					import { ComposedAction } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ActionLink: ComposedAction = observer((props: any) => {
 | 
					export const ActionLink: ComposedAction = observer(
 | 
				
			||||||
  return <Action {...props} component={'a'} className={'nb-action-link'} />;
 | 
					  (props: any) => {
 | 
				
			||||||
});
 | 
					    return <Action {...props} component={'a'} className={'nb-action-link'} />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionLink' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -12,104 +12,110 @@ const openSizeWidthMap = new Map<OpenSize, string>([
 | 
				
			|||||||
  ['middle', '60%'],
 | 
					  ['middle', '60%'],
 | 
				
			||||||
  ['large', '80%'],
 | 
					  ['large', '80%'],
 | 
				
			||||||
]);
 | 
					]);
 | 
				
			||||||
export const ActionModal: ComposedActionDrawer<ModalProps> = observer((props) => {
 | 
					export const ActionModal: ComposedActionDrawer<ModalProps> = observer(
 | 
				
			||||||
  const { footerNodeName = 'Action.Modal.Footer', width, ...others } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const { visible, setVisible, openSize = 'large' } = useActionContext();
 | 
					    const { footerNodeName = 'Action.Modal.Footer', width, ...others } = props;
 | 
				
			||||||
  const actualWidth = width ?? openSizeWidthMap.get(openSize);
 | 
					    const { visible, setVisible, openSize = 'large' } = useActionContext();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const actualWidth = width ?? openSizeWidthMap.get(openSize);
 | 
				
			||||||
  const field = useField();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const footerSchema = schema.reduceProperties((buf, s) => {
 | 
					    const field = useField();
 | 
				
			||||||
    if (s['x-component'] === footerNodeName) {
 | 
					    const footerSchema = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      return s;
 | 
					      if (s['x-component'] === footerNodeName) {
 | 
				
			||||||
    }
 | 
					        return s;
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  });
 | 
					      return buf;
 | 
				
			||||||
  return (
 | 
					    });
 | 
				
			||||||
    <>
 | 
					    return (
 | 
				
			||||||
      {createPortal(
 | 
					      <>
 | 
				
			||||||
        <div
 | 
					        {createPortal(
 | 
				
			||||||
          onClick={(e) => {
 | 
					          <div
 | 
				
			||||||
            e.stopPropagation();
 | 
					            onClick={(e) => {
 | 
				
			||||||
          }}
 | 
					              e.stopPropagation();
 | 
				
			||||||
        >
 | 
					            }}
 | 
				
			||||||
          <Modal
 | 
					 | 
				
			||||||
            width={actualWidth}
 | 
					 | 
				
			||||||
            title={field.title}
 | 
					 | 
				
			||||||
            {...(others as ModalProps)}
 | 
					 | 
				
			||||||
            destroyOnClose
 | 
					 | 
				
			||||||
            visible={visible}
 | 
					 | 
				
			||||||
            onCancel={() => setVisible(false, true)}
 | 
					 | 
				
			||||||
            className={classNames(
 | 
					 | 
				
			||||||
              others.className,
 | 
					 | 
				
			||||||
              css`
 | 
					 | 
				
			||||||
                &.nb-action-popup {
 | 
					 | 
				
			||||||
                  .ant-modal-header {
 | 
					 | 
				
			||||||
                    display: none;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  .ant-modal-body {
 | 
					 | 
				
			||||||
                    padding-top: 16px;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  .ant-modal-body {
 | 
					 | 
				
			||||||
                    background: #f0f2f5;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  .ant-modal-close-x {
 | 
					 | 
				
			||||||
                    width: 32px;
 | 
					 | 
				
			||||||
                    height: 32px;
 | 
					 | 
				
			||||||
                    line-height: 32px;
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              `,
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            footer={
 | 
					 | 
				
			||||||
              footerSchema ? (
 | 
					 | 
				
			||||||
                <div
 | 
					 | 
				
			||||||
                  className={css`
 | 
					 | 
				
			||||||
                    display: flex;
 | 
					 | 
				
			||||||
                    justify-content: flex-end;
 | 
					 | 
				
			||||||
                    width: 100%;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    .ant-btn {
 | 
					 | 
				
			||||||
                      margin-right: 8px;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                  `}
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                  <RecursionField
 | 
					 | 
				
			||||||
                    basePath={field.address}
 | 
					 | 
				
			||||||
                    schema={schema}
 | 
					 | 
				
			||||||
                    onlyRenderProperties
 | 
					 | 
				
			||||||
                    filterProperties={(s) => {
 | 
					 | 
				
			||||||
                      return s['x-component'] === footerNodeName;
 | 
					 | 
				
			||||||
                    }}
 | 
					 | 
				
			||||||
                  />
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
              ) : (
 | 
					 | 
				
			||||||
                false
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <RecursionField
 | 
					            <Modal
 | 
				
			||||||
              basePath={field.address}
 | 
					              width={actualWidth}
 | 
				
			||||||
              schema={schema}
 | 
					              title={field.title}
 | 
				
			||||||
              onlyRenderProperties
 | 
					              {...(others as ModalProps)}
 | 
				
			||||||
              filterProperties={(s) => {
 | 
					              destroyOnClose
 | 
				
			||||||
                return s['x-component'] !== footerNodeName;
 | 
					              visible={visible}
 | 
				
			||||||
              }}
 | 
					              onCancel={() => setVisible(false, true)}
 | 
				
			||||||
            />
 | 
					              className={classNames(
 | 
				
			||||||
          </Modal>
 | 
					                others.className,
 | 
				
			||||||
        </div>,
 | 
					                css`
 | 
				
			||||||
        document.body,
 | 
					                  &.nb-action-popup {
 | 
				
			||||||
      )}
 | 
					                    .ant-modal-header {
 | 
				
			||||||
    </>
 | 
					                      display: none;
 | 
				
			||||||
  );
 | 
					                    }
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActionModal.Footer = observer(() => {
 | 
					                    .ant-modal-body {
 | 
				
			||||||
  const field = useField();
 | 
					                      padding-top: 16px;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					                    }
 | 
				
			||||||
  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
					
 | 
				
			||||||
});
 | 
					                    .ant-modal-body {
 | 
				
			||||||
 | 
					                      background: #f0f2f5;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    .ant-modal-close-x {
 | 
				
			||||||
 | 
					                      width: 32px;
 | 
				
			||||||
 | 
					                      height: 32px;
 | 
				
			||||||
 | 
					                      line-height: 32px;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                `,
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					              footer={
 | 
				
			||||||
 | 
					                footerSchema ? (
 | 
				
			||||||
 | 
					                  <div
 | 
				
			||||||
 | 
					                    className={css`
 | 
				
			||||||
 | 
					                      display: flex;
 | 
				
			||||||
 | 
					                      justify-content: flex-end;
 | 
				
			||||||
 | 
					                      width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      .ant-btn {
 | 
				
			||||||
 | 
					                        margin-right: 8px;
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    `}
 | 
				
			||||||
 | 
					                  >
 | 
				
			||||||
 | 
					                    <RecursionField
 | 
				
			||||||
 | 
					                      basePath={field.address}
 | 
				
			||||||
 | 
					                      schema={schema}
 | 
				
			||||||
 | 
					                      onlyRenderProperties
 | 
				
			||||||
 | 
					                      filterProperties={(s) => {
 | 
				
			||||||
 | 
					                        return s['x-component'] === footerNodeName;
 | 
				
			||||||
 | 
					                      }}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                ) : (
 | 
				
			||||||
 | 
					                  false
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <RecursionField
 | 
				
			||||||
 | 
					                basePath={field.address}
 | 
				
			||||||
 | 
					                schema={schema}
 | 
				
			||||||
 | 
					                onlyRenderProperties
 | 
				
			||||||
 | 
					                filterProperties={(s) => {
 | 
				
			||||||
 | 
					                  return s['x-component'] !== footerNodeName;
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </Modal>
 | 
				
			||||||
 | 
					          </div>,
 | 
				
			||||||
 | 
					          document.body,
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					      </>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionModal' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ActionModal.Footer = observer(
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
 | 
					    return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionModal.Footer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ActionModal;
 | 
					export default ActionModal;
 | 
				
			||||||
 | 
				
			|||||||
@ -10,65 +10,71 @@ const useScope = (key: string) => {
 | 
				
			|||||||
  return scope[key];
 | 
					  return scope[key];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ActionPage: ComposedActionDrawer = observer((props: any) => {
 | 
					export const ActionPage: ComposedActionDrawer = observer(
 | 
				
			||||||
  const { footerNodeName = 'Action.Page.Footer', ...others } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { containerRefKey, visible, setVisible } = useActionContext();
 | 
					    const { footerNodeName = 'Action.Page.Footer', ...others } = props;
 | 
				
			||||||
  const containerRef = useScope(containerRefKey);
 | 
					    const { containerRefKey, visible, setVisible } = useActionContext();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const containerRef = useScope(containerRefKey);
 | 
				
			||||||
  const field = useField();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const footerSchema = schema.reduceProperties((buf, s) => {
 | 
					    const field = useField();
 | 
				
			||||||
    if (s['x-component'] === footerNodeName) {
 | 
					    const footerSchema = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      return s;
 | 
					      if (s['x-component'] === footerNodeName) {
 | 
				
			||||||
    }
 | 
					        return s;
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  });
 | 
					      return buf;
 | 
				
			||||||
  return (
 | 
					    });
 | 
				
			||||||
    <>
 | 
					    return (
 | 
				
			||||||
      {containerRef?.current &&
 | 
					      <>
 | 
				
			||||||
        visible &&
 | 
					        {containerRef?.current &&
 | 
				
			||||||
        createPortal(
 | 
					          visible &&
 | 
				
			||||||
          <div>
 | 
					          createPortal(
 | 
				
			||||||
            <RecursionField
 | 
					            <div>
 | 
				
			||||||
              basePath={field.address}
 | 
					              <RecursionField
 | 
				
			||||||
              schema={schema}
 | 
					                basePath={field.address}
 | 
				
			||||||
              onlyRenderProperties
 | 
					                schema={schema}
 | 
				
			||||||
              filterProperties={(s) => {
 | 
					                onlyRenderProperties
 | 
				
			||||||
                return s['x-component'] !== footerNodeName;
 | 
					                filterProperties={(s) => {
 | 
				
			||||||
              }}
 | 
					                  return s['x-component'] !== footerNodeName;
 | 
				
			||||||
            />
 | 
					                }}
 | 
				
			||||||
            {footerSchema && (
 | 
					              />
 | 
				
			||||||
              <div
 | 
					              {footerSchema && (
 | 
				
			||||||
                className={css`
 | 
					                <div
 | 
				
			||||||
                  display: flex;
 | 
					                  className={css`
 | 
				
			||||||
                  /* justify-content: flex-end; */
 | 
					                    display: flex;
 | 
				
			||||||
                  /* flex-direction: row-reverse; */
 | 
					                    /* justify-content: flex-end; */
 | 
				
			||||||
                  width: 100%;
 | 
					                    /* flex-direction: row-reverse; */
 | 
				
			||||||
                  .ant-btn {
 | 
					                    width: 100%;
 | 
				
			||||||
                    margin-right: 8px;
 | 
					                    .ant-btn {
 | 
				
			||||||
                  }
 | 
					                      margin-right: 8px;
 | 
				
			||||||
                `}
 | 
					                    }
 | 
				
			||||||
              >
 | 
					                  `}
 | 
				
			||||||
                <RecursionField
 | 
					                >
 | 
				
			||||||
                  basePath={field.address}
 | 
					                  <RecursionField
 | 
				
			||||||
                  schema={schema}
 | 
					                    basePath={field.address}
 | 
				
			||||||
                  onlyRenderProperties
 | 
					                    schema={schema}
 | 
				
			||||||
                  filterProperties={(s) => {
 | 
					                    onlyRenderProperties
 | 
				
			||||||
                    return s['x-component'] === footerNodeName;
 | 
					                    filterProperties={(s) => {
 | 
				
			||||||
                  }}
 | 
					                      return s['x-component'] === footerNodeName;
 | 
				
			||||||
                />
 | 
					                    }}
 | 
				
			||||||
              </div>
 | 
					                  />
 | 
				
			||||||
            )}
 | 
					                </div>
 | 
				
			||||||
          </div>,
 | 
					              )}
 | 
				
			||||||
          containerRef?.current,
 | 
					            </div>,
 | 
				
			||||||
        )}
 | 
					            containerRef?.current,
 | 
				
			||||||
    </>
 | 
					          )}
 | 
				
			||||||
  );
 | 
					      </>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionPage' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActionPage.Footer = observer(() => {
 | 
					ActionPage.Footer = observer(
 | 
				
			||||||
  const field = useField();
 | 
					  () => {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField();
 | 
				
			||||||
  return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
});
 | 
					    return <RecursionField basePath={field.address} schema={schema} onlyRenderProperties />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ActionPage.Footer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ActionPage;
 | 
					export default ActionPage;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
 | 
				
			|||||||
import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react';
 | 
					import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react';
 | 
				
			||||||
import { Button, Modal, Popover } from 'antd';
 | 
					import { Button, Modal, Popover } from 'antd';
 | 
				
			||||||
import classnames from 'classnames';
 | 
					import classnames from 'classnames';
 | 
				
			||||||
import React, { useEffect, useState } from 'react';
 | 
					import React, { useEffect, useMemo, useState } from 'react';
 | 
				
			||||||
import { useActionContext } from '../..';
 | 
					import { useActionContext } from '../..';
 | 
				
			||||||
import { useDesignable } from '../../';
 | 
					import { useDesignable } from '../../';
 | 
				
			||||||
import { Icon } from '../../../icon';
 | 
					import { Icon } from '../../../icon';
 | 
				
			||||||
@ -64,139 +64,158 @@ export const actionDesignerCss = css`
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Action: ComposedAction = observer((props: any) => {
 | 
					export const Action: ComposedAction = observer(
 | 
				
			||||||
  const {
 | 
					  (props: any) => {
 | 
				
			||||||
    popover,
 | 
					    const {
 | 
				
			||||||
    confirm,
 | 
					      popover,
 | 
				
			||||||
    openMode: om,
 | 
					      confirm,
 | 
				
			||||||
    containerRefKey,
 | 
					      openMode: om,
 | 
				
			||||||
    component,
 | 
					      containerRefKey,
 | 
				
			||||||
    useAction = useA,
 | 
					      component,
 | 
				
			||||||
    className,
 | 
					      useAction = useA,
 | 
				
			||||||
    icon,
 | 
					      className,
 | 
				
			||||||
    title,
 | 
					      icon,
 | 
				
			||||||
    ...others
 | 
					      title,
 | 
				
			||||||
  } = props;
 | 
					      ...others
 | 
				
			||||||
  const { onClick } = useProps(props);
 | 
					    } = props;
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const { onClick } = useProps(props);
 | 
				
			||||||
  const [formValueChanged, setFormValueChanged] = useState(false);
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
  const Designer = useDesigner();
 | 
					    const [formValueChanged, setFormValueChanged] = useState(false);
 | 
				
			||||||
  const field = useField<any>();
 | 
					    const Designer = useDesigner();
 | 
				
			||||||
  const { run } = useAction();
 | 
					    const field = useField<any>();
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { run } = useAction();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const form = useForm();
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const values = useRecord();
 | 
					    const form = useForm();
 | 
				
			||||||
  const designerProps = fieldSchema['x-designer-props'];
 | 
					    const values = useRecord();
 | 
				
			||||||
  const openMode = fieldSchema?.['x-component-props']?.['openMode'];
 | 
					    const designerProps = fieldSchema['x-designer-props'];
 | 
				
			||||||
  const disabled = form.disabled || field.disabled || props.disabled;
 | 
					    const openMode = fieldSchema?.['x-component-props']?.['openMode'];
 | 
				
			||||||
  const openSize = fieldSchema?.['x-component-props']?.['openSize'];
 | 
					    const disabled = form.disabled || field.disabled || props.disabled;
 | 
				
			||||||
  const linkageRules = fieldSchema?.['x-linkage-rules'] || [];
 | 
					    const openSize = fieldSchema?.['x-component-props']?.['openSize'];
 | 
				
			||||||
  const { designable } = useDesignable();
 | 
					    const linkageRules = fieldSchema?.['x-linkage-rules'] || [];
 | 
				
			||||||
  const tarComponent = useComponent(component) || component;
 | 
					    const { designable } = useDesignable();
 | 
				
			||||||
  useEffect(() => {
 | 
					    const tarComponent = useComponent(component) || component;
 | 
				
			||||||
    field.linkageProperty = {};
 | 
					    const renderTitle = useMemo(() => {
 | 
				
			||||||
    linkageRules
 | 
					      if (title) {
 | 
				
			||||||
      .filter((k) => !k.disabled)
 | 
					        return title;
 | 
				
			||||||
      .forEach((v) => {
 | 
					      }
 | 
				
			||||||
        return v.actions?.map((h) => {
 | 
					      if (fieldSchema.title) {
 | 
				
			||||||
          linkageAction(h.operator, field, v.condition, values);
 | 
					        return compile(fieldSchema.title);
 | 
				
			||||||
        });
 | 
					      }
 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
  }, [linkageRules, values, designable]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const renderButton = () => {
 | 
					 | 
				
			||||||
    if (!designable && field?.data?.hidden) {
 | 
					 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }, [compile, fieldSchema.title, title]);
 | 
				
			||||||
    return (
 | 
					
 | 
				
			||||||
      <SortableItem
 | 
					    useEffect(() => {
 | 
				
			||||||
        {...others}
 | 
					      field.linkageProperty = {};
 | 
				
			||||||
        loading={field?.data?.loading}
 | 
					      linkageRules
 | 
				
			||||||
        icon={<Icon type={icon} />}
 | 
					        .filter((k) => !k.disabled)
 | 
				
			||||||
        disabled={disabled}
 | 
					        .forEach((v) => {
 | 
				
			||||||
        style={{
 | 
					          return v.actions?.map((h) => {
 | 
				
			||||||
          opacity: designable && field?.data?.hidden && 0.1,
 | 
					            linkageAction(h.operator, field, v.condition, values);
 | 
				
			||||||
        }}
 | 
					          });
 | 
				
			||||||
        onClick={(e: React.MouseEvent) => {
 | 
					        });
 | 
				
			||||||
          if (!disabled) {
 | 
					    }, [linkageRules, values, designable]);
 | 
				
			||||||
            e.preventDefault();
 | 
					
 | 
				
			||||||
            e.stopPropagation();
 | 
					    const renderButton = () => {
 | 
				
			||||||
            const onOk = () => {
 | 
					      if (!designable && field?.data?.hidden) {
 | 
				
			||||||
              onClick?.(e);
 | 
					        return null;
 | 
				
			||||||
              setVisible(true);
 | 
					      }
 | 
				
			||||||
              run();
 | 
					      return (
 | 
				
			||||||
            };
 | 
					        <SortableItem
 | 
				
			||||||
            if (confirm) {
 | 
					          {...others}
 | 
				
			||||||
              Modal.confirm({
 | 
					          loading={field?.data?.loading}
 | 
				
			||||||
                ...confirm,
 | 
					          icon={<Icon type={icon} />}
 | 
				
			||||||
                onOk,
 | 
					          disabled={disabled}
 | 
				
			||||||
              });
 | 
					          style={{
 | 
				
			||||||
            } else {
 | 
					            opacity: designable && field?.data?.hidden && 0.1,
 | 
				
			||||||
              onOk();
 | 
					          }}
 | 
				
			||||||
 | 
					          onClick={(e: React.MouseEvent) => {
 | 
				
			||||||
 | 
					            if (!disabled) {
 | 
				
			||||||
 | 
					              e.preventDefault();
 | 
				
			||||||
 | 
					              e.stopPropagation();
 | 
				
			||||||
 | 
					              const onOk = () => {
 | 
				
			||||||
 | 
					                onClick?.(e);
 | 
				
			||||||
 | 
					                setVisible(true);
 | 
				
			||||||
 | 
					                run();
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					              if (confirm) {
 | 
				
			||||||
 | 
					                Modal.confirm({
 | 
				
			||||||
 | 
					                  ...confirm,
 | 
				
			||||||
 | 
					                  onOk,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                onOk();
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }}
 | 
				
			||||||
 | 
					          component={tarComponent || Button}
 | 
				
			||||||
 | 
					          className={classnames(className, actionDesignerCss)}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {renderTitle}
 | 
				
			||||||
 | 
					          <Designer {...designerProps} />
 | 
				
			||||||
 | 
					        </SortableItem>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <ActionContext.Provider
 | 
				
			||||||
 | 
					        value={{
 | 
				
			||||||
 | 
					          button: renderButton(),
 | 
				
			||||||
 | 
					          visible,
 | 
				
			||||||
 | 
					          setVisible,
 | 
				
			||||||
 | 
					          formValueChanged,
 | 
				
			||||||
 | 
					          setFormValueChanged,
 | 
				
			||||||
 | 
					          openMode,
 | 
				
			||||||
 | 
					          openSize,
 | 
				
			||||||
 | 
					          containerRefKey,
 | 
				
			||||||
 | 
					          fieldSchema,
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
        component={tarComponent || Button}
 | 
					 | 
				
			||||||
        className={classnames(className, actionDesignerCss)}
 | 
					 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {title || compile(fieldSchema.title)}
 | 
					        {popover && <RecursionField basePath={field.address} onlyRenderProperties schema={fieldSchema} />}
 | 
				
			||||||
        <Designer {...designerProps} />
 | 
					        {!popover && renderButton()}
 | 
				
			||||||
      </SortableItem>
 | 
					        {!popover && props.children}
 | 
				
			||||||
 | 
					      </ActionContext.Provider>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Action' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					Action.Popover = observer(
 | 
				
			||||||
    <ActionContext.Provider
 | 
					  (props) => {
 | 
				
			||||||
      value={{
 | 
					    const { button, visible, setVisible } = useActionContext();
 | 
				
			||||||
        button: renderButton(),
 | 
					    return (
 | 
				
			||||||
        visible,
 | 
					      <Popover
 | 
				
			||||||
        setVisible,
 | 
					        {...props}
 | 
				
			||||||
        formValueChanged,
 | 
					        destroyTooltipOnHide
 | 
				
			||||||
        setFormValueChanged,
 | 
					        open={visible}
 | 
				
			||||||
        openMode,
 | 
					        onOpenChange={(visible) => {
 | 
				
			||||||
        openSize,
 | 
					          setVisible(visible);
 | 
				
			||||||
        containerRefKey,
 | 
					        }}
 | 
				
			||||||
        fieldSchema,
 | 
					        content={props.children}
 | 
				
			||||||
      }}
 | 
					      >
 | 
				
			||||||
    >
 | 
					        {button}
 | 
				
			||||||
      {popover && <RecursionField basePath={field.address} onlyRenderProperties schema={fieldSchema} />}
 | 
					      </Popover>
 | 
				
			||||||
      {!popover && renderButton()}
 | 
					    );
 | 
				
			||||||
      {!popover && props.children}
 | 
					  },
 | 
				
			||||||
    </ActionContext.Provider>
 | 
					  { displayName: 'Action.Popover' },
 | 
				
			||||||
  );
 | 
					);
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Action.Popover = observer((props) => {
 | 
					Action.Popover.Footer = observer(
 | 
				
			||||||
  const { button, visible, setVisible } = useActionContext();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <Popover
 | 
					      <div
 | 
				
			||||||
      {...props}
 | 
					        className={css`
 | 
				
			||||||
      destroyTooltipOnHide
 | 
					          display: flex;
 | 
				
			||||||
      open={visible}
 | 
					          justify-content: flex-end;
 | 
				
			||||||
      onOpenChange={(visible) => {
 | 
					          width: 100%;
 | 
				
			||||||
        setVisible(visible);
 | 
					        `}
 | 
				
			||||||
      }}
 | 
					      >
 | 
				
			||||||
      content={props.children}
 | 
					        {props.children}
 | 
				
			||||||
    >
 | 
					      </div>
 | 
				
			||||||
      {button}
 | 
					    );
 | 
				
			||||||
    </Popover>
 | 
					  },
 | 
				
			||||||
  );
 | 
					  { displayName: 'Action.Popover.Footer' },
 | 
				
			||||||
});
 | 
					);
 | 
				
			||||||
 | 
					 | 
				
			||||||
Action.Popover.Footer = observer((props) => {
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <div
 | 
					 | 
				
			||||||
      className={css`
 | 
					 | 
				
			||||||
        display: flex;
 | 
					 | 
				
			||||||
        justify-content: flex-end;
 | 
					 | 
				
			||||||
        width: 100%;
 | 
					 | 
				
			||||||
      `}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      {props.children}
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Action.Link = ActionLink;
 | 
					Action.Link = ActionLink;
 | 
				
			||||||
Action.Designer = ActionDesigner;
 | 
					Action.Designer = ActionDesigner;
 | 
				
			||||||
 | 
				
			|||||||
@ -6,40 +6,41 @@ import { useSchemaInitializer } from '../../../schema-initializer';
 | 
				
			|||||||
import { DndContext } from '../../common';
 | 
					import { DndContext } from '../../common';
 | 
				
			||||||
import { useDesignable, useProps } from '../../hooks';
 | 
					import { useDesignable, useProps } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ActionBar = observer((props: any) => {
 | 
					export const ActionBar = observer(
 | 
				
			||||||
  const { layout = 'tow-columns', style, spaceProps, ...others } = useProps(props);
 | 
					  (props: any) => {
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { layout = 'tow-columns', style, spaceProps, ...others } = useProps(props);
 | 
				
			||||||
  const { InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { designable } = useDesignable();
 | 
					    const { InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
				
			||||||
  if (layout === 'one-column') {
 | 
					    const { designable } = useDesignable();
 | 
				
			||||||
 | 
					    if (layout === 'one-column') {
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <DndContext>
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            style={{ display: 'flex', alignItems: 'center', ...style }}
 | 
				
			||||||
 | 
					            {...others}
 | 
				
			||||||
 | 
					            className={cx(others.className, 'nb-action-bar')}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {props.children && (
 | 
				
			||||||
 | 
					              <div style={{ marginRight: 8 }}>
 | 
				
			||||||
 | 
					                <Space {...spaceProps}>
 | 
				
			||||||
 | 
					                  {fieldSchema.mapProperties((schema, key) => {
 | 
				
			||||||
 | 
					                    return <RecursionField key={key} name={key} schema={schema} />;
 | 
				
			||||||
 | 
					                  })}
 | 
				
			||||||
 | 
					                </Space>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
 | 
					            <InitializerComponent />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </DndContext>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const hasActions = Object.keys(fieldSchema.properties ?? {}).length > 0;
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <DndContext>
 | 
					      <div
 | 
				
			||||||
        <div
 | 
					        style={
 | 
				
			||||||
          style={{ display: 'flex', alignItems: 'center', ...style }}
 | 
					          !designable && !hasActions
 | 
				
			||||||
          {...others}
 | 
					            ? undefined
 | 
				
			||||||
          className={cx(others.className, 'nb-action-bar')}
 | 
					            : {
 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {props.children && (
 | 
					 | 
				
			||||||
            <div style={{ marginRight: 8 }}>
 | 
					 | 
				
			||||||
              <Space {...spaceProps}>
 | 
					 | 
				
			||||||
                {fieldSchema.mapProperties((schema, key) => {
 | 
					 | 
				
			||||||
                  return <RecursionField key={key} name={key} schema={schema} />;
 | 
					 | 
				
			||||||
                })}
 | 
					 | 
				
			||||||
              </Space>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          )}
 | 
					 | 
				
			||||||
          <InitializerComponent />
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      </DndContext>
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  const hasActions = Object.keys(fieldSchema.properties ?? {}).length > 0;
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <div
 | 
					 | 
				
			||||||
      style={
 | 
					 | 
				
			||||||
        !designable && !hasActions
 | 
					 | 
				
			||||||
          ? undefined
 | 
					 | 
				
			||||||
          : {
 | 
					 | 
				
			||||||
              display: 'flex',
 | 
					              display: 'flex',
 | 
				
			||||||
              justifyContent: 'space-between',
 | 
					              justifyContent: 'space-between',
 | 
				
			||||||
              alignItems: 'center',
 | 
					              alignItems: 'center',
 | 
				
			||||||
@ -47,38 +48,40 @@ export const ActionBar = observer((props: any) => {
 | 
				
			|||||||
              flexShrink: 0,
 | 
					              flexShrink: 0,
 | 
				
			||||||
              ...style,
 | 
					              ...style,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
      }
 | 
					        }
 | 
				
			||||||
      {...others}
 | 
					        {...others}
 | 
				
			||||||
      className={cx(others.className, 'nb-action-bar')}
 | 
					        className={cx(others.className, 'nb-action-bar')}
 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <div
 | 
					 | 
				
			||||||
        className={css`
 | 
					 | 
				
			||||||
          .ant-space:last-child {
 | 
					 | 
				
			||||||
            margin-left: 8px;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        `}
 | 
					 | 
				
			||||||
        style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}
 | 
					 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <DndContext>
 | 
					        <div
 | 
				
			||||||
          <Space {...spaceProps}>
 | 
					          className={css`
 | 
				
			||||||
            {fieldSchema.mapProperties((schema, key) => {
 | 
					            .ant-space:last-child {
 | 
				
			||||||
              if (schema['x-align'] !== 'left') {
 | 
					              margin-left: 8px;
 | 
				
			||||||
                return null;
 | 
					            }
 | 
				
			||||||
              }
 | 
					          `}
 | 
				
			||||||
              return <RecursionField key={key} name={key} schema={schema} />;
 | 
					          style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}
 | 
				
			||||||
            })}
 | 
					        >
 | 
				
			||||||
          </Space>
 | 
					          <DndContext>
 | 
				
			||||||
          <Space {...spaceProps}>
 | 
					            <Space {...spaceProps}>
 | 
				
			||||||
            {fieldSchema.mapProperties((schema, key) => {
 | 
					              {fieldSchema.mapProperties((schema, key) => {
 | 
				
			||||||
              if (schema['x-align'] === 'left') {
 | 
					                if (schema['x-align'] !== 'left') {
 | 
				
			||||||
                return null;
 | 
					                  return null;
 | 
				
			||||||
              }
 | 
					                }
 | 
				
			||||||
              return <RecursionField key={key} name={key} schema={schema} />;
 | 
					                return <RecursionField key={key} name={key} schema={schema} />;
 | 
				
			||||||
            })}
 | 
					              })}
 | 
				
			||||||
          </Space>
 | 
					            </Space>
 | 
				
			||||||
        </DndContext>
 | 
					            <Space {...spaceProps}>
 | 
				
			||||||
 | 
					              {fieldSchema.mapProperties((schema, key) => {
 | 
				
			||||||
 | 
					                if (schema['x-align'] === 'left') {
 | 
				
			||||||
 | 
					                  return null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return <RecursionField key={key} name={key} schema={schema} />;
 | 
				
			||||||
 | 
					              })}
 | 
				
			||||||
 | 
					            </Space>
 | 
				
			||||||
 | 
					          </DndContext>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <InitializerComponent />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <InitializerComponent />
 | 
					    );
 | 
				
			||||||
    </div>
 | 
					  },
 | 
				
			||||||
  );
 | 
					  { displayName: 'ActionBar' },
 | 
				
			||||||
});
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -18,30 +18,33 @@ const useCloseAction = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Editable = observer((props) => {
 | 
					const Editable = observer(
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  (props) => {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  return (
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <div style={{ marginBottom: 24 }}>
 | 
					      <div>
 | 
				
			||||||
        打开方式:
 | 
					        <div style={{ marginBottom: 24 }}>
 | 
				
			||||||
        <Select
 | 
					          打开方式:
 | 
				
			||||||
          value={field.componentProps.openMode}
 | 
					          <Select
 | 
				
			||||||
          style={{ width: 100 }}
 | 
					            value={field.componentProps.openMode}
 | 
				
			||||||
          onChange={(value) => {
 | 
					            style={{ width: 100 }}
 | 
				
			||||||
            field.componentProps.openMode = value;
 | 
					            onChange={(value) => {
 | 
				
			||||||
            schema['x-component-props']['openMode'] = value;
 | 
					              field.componentProps.openMode = value;
 | 
				
			||||||
          }}
 | 
					              schema['x-component-props']['openMode'] = value;
 | 
				
			||||||
        >
 | 
					            }}
 | 
				
			||||||
          <Select.Option value={'drawer'}>Drawer</Select.Option>
 | 
					          >
 | 
				
			||||||
          <Select.Option value={'modal'}>Modal</Select.Option>
 | 
					            <Select.Option value={'drawer'}>Drawer</Select.Option>
 | 
				
			||||||
          <Select.Option value={'page'}>Page</Select.Option>
 | 
					            <Select.Option value={'modal'}>Modal</Select.Option>
 | 
				
			||||||
        </Select>
 | 
					            <Select.Option value={'page'}>Page</Select.Option>
 | 
				
			||||||
 | 
					          </Select>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {props.children}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      {props.children}
 | 
					    );
 | 
				
			||||||
    </div>
 | 
					  },
 | 
				
			||||||
  );
 | 
					  { displayName: 'Editable' },
 | 
				
			||||||
});
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const schema: ISchema = {
 | 
					const schema: ISchema = {
 | 
				
			||||||
  type: 'object',
 | 
					  type: 'object',
 | 
				
			||||||
 | 
				
			|||||||
@ -71,52 +71,55 @@ function TypeSelect(props) {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const EditOptions = observer((props) => {
 | 
					const EditOptions = observer(
 | 
				
			||||||
  const record = ArrayTable.useRecord();
 | 
					  (props) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const record = ArrayTable.useRecord();
 | 
				
			||||||
  console.log(record.type);
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  return (
 | 
					    console.log(record.type);
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <a
 | 
					      <div>
 | 
				
			||||||
        onClick={() => {
 | 
					        <a
 | 
				
			||||||
          FormDrawer('Pop-up form', () => {
 | 
					          onClick={() => {
 | 
				
			||||||
            return (
 | 
					            FormDrawer('Pop-up form', () => {
 | 
				
			||||||
              <FormLayout labelCol={6} wrapperCol={10}>
 | 
					              return (
 | 
				
			||||||
                <SchemaField
 | 
					                <FormLayout labelCol={6} wrapperCol={10}>
 | 
				
			||||||
                  schema={{
 | 
					                  <SchemaField
 | 
				
			||||||
                    type: 'object',
 | 
					                    schema={{
 | 
				
			||||||
                    properties: record.type ? types[record.type] || {} : {},
 | 
					                      type: 'object',
 | 
				
			||||||
                  }}
 | 
					                      properties: record.type ? types[record.type] || {} : {},
 | 
				
			||||||
                />
 | 
					                    }}
 | 
				
			||||||
                <FormDrawer.Footer>
 | 
					                  />
 | 
				
			||||||
                  <FormButtonGroup align="right">
 | 
					                  <FormDrawer.Footer>
 | 
				
			||||||
                    <Submit
 | 
					                    <FormButtonGroup align="right">
 | 
				
			||||||
                      onSubmit={() => {
 | 
					                      <Submit
 | 
				
			||||||
                        return new Promise((resolve) => {
 | 
					                        onSubmit={() => {
 | 
				
			||||||
                          setTimeout(resolve, 1000);
 | 
					                          return new Promise((resolve) => {
 | 
				
			||||||
                        });
 | 
					                            setTimeout(resolve, 1000);
 | 
				
			||||||
                      }}
 | 
					                          });
 | 
				
			||||||
                    >
 | 
					                        }}
 | 
				
			||||||
                      Submit
 | 
					                      >
 | 
				
			||||||
                    </Submit>
 | 
					                        Submit
 | 
				
			||||||
                  </FormButtonGroup>
 | 
					                      </Submit>
 | 
				
			||||||
                </FormDrawer.Footer>
 | 
					                    </FormButtonGroup>
 | 
				
			||||||
              </FormLayout>
 | 
					                  </FormDrawer.Footer>
 | 
				
			||||||
            );
 | 
					                </FormLayout>
 | 
				
			||||||
          })
 | 
					              );
 | 
				
			||||||
            .open({
 | 
					 | 
				
			||||||
              initialValues: field.value,
 | 
					 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            .then((values) => {
 | 
					              .open({
 | 
				
			||||||
              field.value = values;
 | 
					                initialValues: field.value,
 | 
				
			||||||
            });
 | 
					              })
 | 
				
			||||||
        }}
 | 
					              .then((values) => {
 | 
				
			||||||
      >
 | 
					                field.value = values;
 | 
				
			||||||
        Edit
 | 
					              });
 | 
				
			||||||
      </a>
 | 
					          }}
 | 
				
			||||||
    </div>
 | 
					        >
 | 
				
			||||||
  );
 | 
					          Edit
 | 
				
			||||||
});
 | 
					        </a>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'EditOptions' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SchemaField = createSchemaField({
 | 
					const SchemaField = createSchemaField({
 | 
				
			||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,63 +4,66 @@ import React, { useEffect, useMemo, useState } from 'react';
 | 
				
			|||||||
import { useCollectionManager } from '../../../collection-manager';
 | 
					import { useCollectionManager } from '../../../collection-manager';
 | 
				
			||||||
import { AssociationFieldContext } from './context';
 | 
					import { AssociationFieldContext } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const AssociationFieldProvider = observer((props) => {
 | 
					export const AssociationFieldProvider = observer(
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  (props) => {
 | 
				
			||||||
  const { getCollectionJoinField, getCollection } = useCollectionManager();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { getCollectionJoinField, getCollection } = useCollectionManager();
 | 
				
			||||||
  const allowMultiple = fieldSchema['x-component-props']?.multiple !== false;
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const allowDissociate = fieldSchema['x-component-props']?.allowDissociate !== false;
 | 
					    const allowMultiple = fieldSchema['x-component-props']?.multiple !== false;
 | 
				
			||||||
 | 
					    const allowDissociate = fieldSchema['x-component-props']?.allowDissociate !== false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const collectionField = useMemo(
 | 
					    const collectionField = useMemo(
 | 
				
			||||||
    () => getCollectionJoinField(fieldSchema['x-collection-field']),
 | 
					      () => getCollectionJoinField(fieldSchema['x-collection-field']),
 | 
				
			||||||
    [fieldSchema['x-collection-field'], fieldSchema.name],
 | 
					      [fieldSchema['x-collection-field'], fieldSchema.name],
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
  const isFileCollection = useMemo(
 | 
					    const isFileCollection = useMemo(
 | 
				
			||||||
    () => getCollection(collectionField?.target)?.template === 'file',
 | 
					      () => getCollection(collectionField?.target)?.template === 'file',
 | 
				
			||||||
    [fieldSchema['x-collection-field']],
 | 
					      [fieldSchema['x-collection-field']],
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
  const currentMode = useMemo(
 | 
					    const currentMode = useMemo(
 | 
				
			||||||
    () => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'),
 | 
					      () => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'),
 | 
				
			||||||
    [fieldSchema['x-component-props']?.mode],
 | 
					      [fieldSchema['x-component-props']?.mode],
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [loading, setLoading] = useState(true);
 | 
					    const [loading, setLoading] = useState(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
    setLoading(true);
 | 
					      setLoading(true);
 | 
				
			||||||
    if (!collectionField) {
 | 
					      if (!collectionField) {
 | 
				
			||||||
      setLoading(false);
 | 
					        setLoading(false);
 | 
				
			||||||
      return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					      }
 | 
				
			||||||
    if (field.value !== null && field.value !== undefined) {
 | 
					      if (field.value !== null && field.value !== undefined) {
 | 
				
			||||||
      // Nester 子表单时,如果没数据初始化一个 [null] 的占位
 | 
					        // Nester 子表单时,如果没数据初始化一个 [null] 的占位
 | 
				
			||||||
      if (currentMode === 'Nester' && Array.isArray(field.value)) {
 | 
					        if (currentMode === 'Nester' && Array.isArray(field.value)) {
 | 
				
			||||||
        if (field.value.length === 0 && ['belongsToMany', 'hasMany'].includes(collectionField.type)) {
 | 
					          if (field.value.length === 0 && ['belongsToMany', 'hasMany'].includes(collectionField.type)) {
 | 
				
			||||||
 | 
					            field.value = [{}];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        setLoading(false);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (currentMode === 'Nester') {
 | 
				
			||||||
 | 
					        if (['belongsTo', 'hasOne'].includes(collectionField.type)) {
 | 
				
			||||||
 | 
					          field.value = {};
 | 
				
			||||||
 | 
					        } else if (['belongsToMany', 'hasMany'].includes(collectionField.type)) {
 | 
				
			||||||
          field.value = [{}];
 | 
					          field.value = [{}];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      setLoading(false);
 | 
					      setLoading(false);
 | 
				
			||||||
      return;
 | 
					    }, [currentMode, collectionField, field.value]);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (currentMode === 'Nester') {
 | 
					 | 
				
			||||||
      if (['belongsTo', 'hasOne'].includes(collectionField.type)) {
 | 
					 | 
				
			||||||
        field.value = {};
 | 
					 | 
				
			||||||
      } else if (['belongsToMany', 'hasMany'].includes(collectionField.type)) {
 | 
					 | 
				
			||||||
        field.value = [{}];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    setLoading(false);
 | 
					 | 
				
			||||||
  }, [currentMode, collectionField, field.value]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (loading) {
 | 
					    if (loading) {
 | 
				
			||||||
    return null;
 | 
					      return null;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return collectionField ? (
 | 
					    return collectionField ? (
 | 
				
			||||||
    <AssociationFieldContext.Provider
 | 
					      <AssociationFieldContext.Provider
 | 
				
			||||||
      value={{ options: collectionField, field, allowMultiple, allowDissociate, currentMode }}
 | 
					        value={{ options: collectionField, field, allowMultiple, allowDissociate, currentMode }}
 | 
				
			||||||
    >
 | 
					      >
 | 
				
			||||||
      {props.children}
 | 
					        {props.children}
 | 
				
			||||||
    </AssociationFieldContext.Provider>
 | 
					      </AssociationFieldContext.Provider>
 | 
				
			||||||
  ) : null;
 | 
					    ) : null;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'AssociationFieldProvider' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,41 +11,44 @@ export type AssociationSelectProps<P = any> = RemoteSelectProps<P> & {
 | 
				
			|||||||
  multiple?: boolean;
 | 
					  multiple?: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
 | 
					const InternalAssociationSelect = observer(
 | 
				
			||||||
  const { fieldNames, objectValue = true } = props;
 | 
					  (props: AssociationSelectProps) => {
 | 
				
			||||||
  const field: any = useField();
 | 
					    const { fieldNames, objectValue = true } = props;
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field: any = useField();
 | 
				
			||||||
  const service = useServiceOptions(props);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const isAllowAddNew = fieldSchema['x-add-new'];
 | 
					    const service = useServiceOptions(props);
 | 
				
			||||||
  const value = Array.isArray(props.value) ? props.value.filter(Boolean) : props.value;
 | 
					    const isAllowAddNew = fieldSchema['x-add-new'];
 | 
				
			||||||
 | 
					    const value = Array.isArray(props.value) ? props.value.filter(Boolean) : props.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div key={fieldSchema.name}>
 | 
					      <div key={fieldSchema.name}>
 | 
				
			||||||
      <Input.Group compact style={{ display: 'flex', lineHeight: '32px' }}>
 | 
					        <Input.Group compact style={{ display: 'flex', lineHeight: '32px' }}>
 | 
				
			||||||
        <RemoteSelect
 | 
					          <RemoteSelect
 | 
				
			||||||
          style={{ width: '100%' }}
 | 
					            style={{ width: '100%' }}
 | 
				
			||||||
          {...props}
 | 
					            {...props}
 | 
				
			||||||
          objectValue={objectValue}
 | 
					            objectValue={objectValue}
 | 
				
			||||||
          value={value}
 | 
					            value={value}
 | 
				
			||||||
          service={service}
 | 
					            service={service}
 | 
				
			||||||
        ></RemoteSelect>
 | 
					          ></RemoteSelect>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {isAllowAddNew && (
 | 
					          {isAllowAddNew && (
 | 
				
			||||||
          <RecordProvider record={null}>
 | 
					            <RecordProvider record={null}>
 | 
				
			||||||
            <RecursionField
 | 
					              <RecursionField
 | 
				
			||||||
              onlyRenderProperties
 | 
					                onlyRenderProperties
 | 
				
			||||||
              basePath={field.address}
 | 
					                basePath={field.address}
 | 
				
			||||||
              schema={fieldSchema}
 | 
					                schema={fieldSchema}
 | 
				
			||||||
              filterProperties={(s) => {
 | 
					                filterProperties={(s) => {
 | 
				
			||||||
                return s['x-component'] === 'Action';
 | 
					                  return s['x-component'] === 'Action';
 | 
				
			||||||
              }}
 | 
					                }}
 | 
				
			||||||
            />
 | 
					              />
 | 
				
			||||||
          </RecordProvider>
 | 
					            </RecordProvider>
 | 
				
			||||||
        )}
 | 
					          )}
 | 
				
			||||||
      </Input.Group>
 | 
					        </Input.Group>
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'InternalAssociationSelect' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface AssociationSelectInterface {
 | 
					interface AssociationSelectInterface {
 | 
				
			||||||
  (props: any): React.ReactElement;
 | 
					  (props: any): React.ReactElement;
 | 
				
			||||||
 | 
				
			|||||||
@ -12,50 +12,56 @@ import { InternalSubTable } from './InternalSubTable';
 | 
				
			|||||||
import { CreateRecordAction } from './components/CreateRecordAction';
 | 
					import { CreateRecordAction } from './components/CreateRecordAction';
 | 
				
			||||||
import { useAssociationFieldContext } from './hooks';
 | 
					import { useAssociationFieldContext } from './hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const EditableAssociationField = observer((props: any) => {
 | 
					const EditableAssociationField = observer(
 | 
				
			||||||
  const { multiple } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field: Field = useField();
 | 
					    const { multiple } = props;
 | 
				
			||||||
  const form = useForm();
 | 
					    const field: Field = useField();
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const form = useForm();
 | 
				
			||||||
  const { options: collectionField, currentMode } = useAssociationFieldContext();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
 | 
					    const { options: collectionField, currentMode } = useAssociationFieldContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const useCreateActionProps = () => {
 | 
					    const useCreateActionProps = () => {
 | 
				
			||||||
    const { onClick } = useCAP();
 | 
					      const { onClick } = useCAP();
 | 
				
			||||||
    const actionField: any = useField();
 | 
					      const actionField: any = useField();
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      async onClick() {
 | 
					        async onClick() {
 | 
				
			||||||
        await onClick();
 | 
					          await onClick();
 | 
				
			||||||
        const { data } = actionField.data?.data?.data || {};
 | 
					          const { data } = actionField.data?.data?.data || {};
 | 
				
			||||||
        if (data) {
 | 
					          if (data) {
 | 
				
			||||||
          if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) {
 | 
					            if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) {
 | 
				
			||||||
            const values = form.getValuesIn(field.path) || [];
 | 
					              const values = form.getValuesIn(field.path) || [];
 | 
				
			||||||
            values.push(data);
 | 
					              values.push(data);
 | 
				
			||||||
            form.setValuesIn(field.path, values);
 | 
					              form.setValuesIn(field.path, values);
 | 
				
			||||||
            field.onInput(values);
 | 
					              field.onInput(values);
 | 
				
			||||||
          } else {
 | 
					            } else {
 | 
				
			||||||
            form.setValuesIn(field.path, data);
 | 
					              form.setValuesIn(field.path, data);
 | 
				
			||||||
            field.onInput(data);
 | 
					              field.onInput(data);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
      },
 | 
					      };
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <SchemaComponentOptions scope={{ useCreateActionProps }} components={{ CreateRecordAction }}>
 | 
					      <SchemaComponentOptions scope={{ useCreateActionProps }} components={{ CreateRecordAction }}>
 | 
				
			||||||
      {currentMode === 'Picker' && <InternalPicker {...props} />}
 | 
					        {currentMode === 'Picker' && <InternalPicker {...props} />}
 | 
				
			||||||
      {currentMode === 'Nester' && <InternalNester {...props} />}
 | 
					        {currentMode === 'Nester' && <InternalNester {...props} />}
 | 
				
			||||||
      {currentMode === 'Select' && <AssociationSelect {...props} />}
 | 
					        {currentMode === 'Select' && <AssociationSelect {...props} />}
 | 
				
			||||||
      {currentMode === 'SubTable' && <InternalSubTable {...props} />}
 | 
					        {currentMode === 'SubTable' && <InternalSubTable {...props} />}
 | 
				
			||||||
      {currentMode === 'FileManager' && <InternalFileManager {...props} />}
 | 
					        {currentMode === 'FileManager' && <InternalFileManager {...props} />}
 | 
				
			||||||
    </SchemaComponentOptions>
 | 
					      </SchemaComponentOptions>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'EditableAssociationField' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Editable = observer((props) => {
 | 
					export const Editable = observer(
 | 
				
			||||||
  return (
 | 
					  (props) => {
 | 
				
			||||||
    <AssociationFieldProvider>
 | 
					    return (
 | 
				
			||||||
      <EditableAssociationField {...props} />
 | 
					      <AssociationFieldProvider>
 | 
				
			||||||
    </AssociationFieldProvider>
 | 
					        <EditableAssociationField {...props} />
 | 
				
			||||||
  );
 | 
					      </AssociationFieldProvider>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Editable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -60,138 +60,145 @@ const useTableSelectorProps = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const InternalPicker = observer((props: any) => {
 | 
					export const InternalPicker = observer(
 | 
				
			||||||
  const { value, multiple, onChange, quickUpload, selectFile, ...others } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field: any = useField();
 | 
					    const { value, multiple, onChange, quickUpload, selectFile, ...others } = props;
 | 
				
			||||||
  const fieldNames = useFieldNames(props);
 | 
					    const field: any = useField();
 | 
				
			||||||
  const [visibleSelector, setVisibleSelector] = useState(false);
 | 
					    const fieldNames = useFieldNames(props);
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const [visibleSelector, setVisibleSelector] = useState(false);
 | 
				
			||||||
  const insertSelector = useInsertSchema('Selector');
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { options: collectionField } = useAssociationFieldContext();
 | 
					    const insertSelector = useInsertSchema('Selector');
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { options: collectionField } = useAssociationFieldContext();
 | 
				
			||||||
  const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const isAllowAddNew = fieldSchema['x-add-new'];
 | 
					    const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
				
			||||||
  const [selectedRows, setSelectedRows] = useState([]);
 | 
					    const isAllowAddNew = fieldSchema['x-add-new'];
 | 
				
			||||||
  const options = useMemo(() => {
 | 
					    const [selectedRows, setSelectedRows] = useState([]);
 | 
				
			||||||
    if (value && Object.keys(value).length > 0) {
 | 
					    const options = useMemo(() => {
 | 
				
			||||||
      const opts = (Array.isArray(value) ? value : value ? [value] : []).filter(Boolean).map((option) => {
 | 
					      if (value && Object.keys(value).length > 0) {
 | 
				
			||||||
        const label = option?.[fieldNames.label];
 | 
					        const opts = (Array.isArray(value) ? value : value ? [value] : []).filter(Boolean).map((option) => {
 | 
				
			||||||
        return {
 | 
					          const label = option?.[fieldNames.label];
 | 
				
			||||||
          ...option,
 | 
					          return {
 | 
				
			||||||
          [fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)),
 | 
					            ...option,
 | 
				
			||||||
        };
 | 
					            [fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)),
 | 
				
			||||||
      });
 | 
					          };
 | 
				
			||||||
      return opts;
 | 
					        });
 | 
				
			||||||
    }
 | 
					        return opts;
 | 
				
			||||||
    return [];
 | 
					      }
 | 
				
			||||||
  }, [value, fieldNames?.label]);
 | 
					      return [];
 | 
				
			||||||
 | 
					    }, [value, fieldNames?.label]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const pickerProps = {
 | 
					    const pickerProps = {
 | 
				
			||||||
    size: 'small',
 | 
					      size: 'small',
 | 
				
			||||||
    fieldNames,
 | 
					      fieldNames,
 | 
				
			||||||
    multiple: multiple !== false && ['o2m', 'm2m'].includes(collectionField?.interface),
 | 
					      multiple: multiple !== false && ['o2m', 'm2m'].includes(collectionField?.interface),
 | 
				
			||||||
    association: {
 | 
					      association: {
 | 
				
			||||||
      target: collectionField?.target,
 | 
					        target: collectionField?.target,
 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    options,
 | 
					 | 
				
			||||||
    onChange: props?.onChange,
 | 
					 | 
				
			||||||
    selectedRows,
 | 
					 | 
				
			||||||
    setSelectedRows,
 | 
					 | 
				
			||||||
    collectionField,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const getValue = () => {
 | 
					 | 
				
			||||||
    if (multiple == null) return null;
 | 
					 | 
				
			||||||
    return Array.isArray(value) ? value.filter(Boolean)?.map((v) => v?.[fieldNames.value]) : value?.[fieldNames.value];
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  const getFilter = () => {
 | 
					 | 
				
			||||||
    const targetKey = collectionField?.targetKey || 'id';
 | 
					 | 
				
			||||||
    const list = options.map((option) => option[targetKey]).filter(Boolean);
 | 
					 | 
				
			||||||
    const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {};
 | 
					 | 
				
			||||||
    return filter;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  const usePickActionProps = () => {
 | 
					 | 
				
			||||||
    const { setVisible } = useActionContext();
 | 
					 | 
				
			||||||
    const { multiple, selectedRows, onChange, options, collectionField } = useContext(RecordPickerContext);
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      onClick() {
 | 
					 | 
				
			||||||
        if (multiple) {
 | 
					 | 
				
			||||||
          onChange(unionBy(selectedRows, options, collectionField?.targetKey || 'id'));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          onChange(selectedRows?.[0] || null);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        setVisible(false);
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      options,
 | 
				
			||||||
 | 
					      onChange: props?.onChange,
 | 
				
			||||||
 | 
					      selectedRows,
 | 
				
			||||||
 | 
					      setSelectedRows,
 | 
				
			||||||
 | 
					      collectionField,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  };
 | 
					
 | 
				
			||||||
  return (
 | 
					    const getValue = () => {
 | 
				
			||||||
    <>
 | 
					      if (multiple == null) return null;
 | 
				
			||||||
      <Input.Group compact style={{ display: 'flex', lineHeight: '32px' }}>
 | 
					      return Array.isArray(value)
 | 
				
			||||||
        <div style={{ width: '100%' }}>
 | 
					        ? value.filter(Boolean)?.map((v) => v?.[fieldNames.value])
 | 
				
			||||||
          <Select
 | 
					        : value?.[fieldNames.value];
 | 
				
			||||||
            style={{ width: '100%' }}
 | 
					    };
 | 
				
			||||||
            {...others}
 | 
					    const getFilter = () => {
 | 
				
			||||||
            mode={multiple ? 'multiple' : props.mode}
 | 
					      const targetKey = collectionField?.targetKey || 'id';
 | 
				
			||||||
            fieldNames={fieldNames}
 | 
					      const list = options.map((option) => option[targetKey]).filter(Boolean);
 | 
				
			||||||
            onDropdownVisibleChange={(open) => {
 | 
					      const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {};
 | 
				
			||||||
              insertSelector(schema.Selector);
 | 
					      return filter;
 | 
				
			||||||
              setVisibleSelector(true);
 | 
					    };
 | 
				
			||||||
            }}
 | 
					    const usePickActionProps = () => {
 | 
				
			||||||
            allowClear
 | 
					      const { setVisible } = useActionContext();
 | 
				
			||||||
            onChange={(changed: any) => {
 | 
					      const { multiple, selectedRows, onChange, options, collectionField } = useContext(RecordPickerContext);
 | 
				
			||||||
              if (!changed) {
 | 
					      return {
 | 
				
			||||||
                const value = multiple ? [] : null;
 | 
					        onClick() {
 | 
				
			||||||
                onChange(value);
 | 
					          if (multiple) {
 | 
				
			||||||
                setSelectedRows(value);
 | 
					            onChange(unionBy(selectedRows, options, collectionField?.targetKey || 'id'));
 | 
				
			||||||
              } else if (Array.isArray(changed)) {
 | 
					          } else {
 | 
				
			||||||
                if (!changed.length) {
 | 
					            onChange(selectedRows?.[0] || null);
 | 
				
			||||||
                  onChange([]);
 | 
					          }
 | 
				
			||||||
                  setSelectedRows([]);
 | 
					          setVisible(false);
 | 
				
			||||||
                  return;
 | 
					        },
 | 
				
			||||||
                }
 | 
					      };
 | 
				
			||||||
                const values = options?.filter((option) => changed.includes(option[fieldNames.value]));
 | 
					    };
 | 
				
			||||||
                onChange(values);
 | 
					    return (
 | 
				
			||||||
                setSelectedRows(values);
 | 
					      <>
 | 
				
			||||||
              }
 | 
					        <Input.Group compact style={{ display: 'flex', lineHeight: '32px' }}>
 | 
				
			||||||
            }}
 | 
					          <div style={{ width: '100%' }}>
 | 
				
			||||||
            options={options}
 | 
					            <Select
 | 
				
			||||||
            value={getValue()}
 | 
					              style={{ width: '100%' }}
 | 
				
			||||||
            open={false}
 | 
					              {...others}
 | 
				
			||||||
          />
 | 
					              mode={multiple ? 'multiple' : props.mode}
 | 
				
			||||||
        </div>
 | 
					              fieldNames={fieldNames}
 | 
				
			||||||
        {isAllowAddNew && (
 | 
					              onDropdownVisibleChange={(open) => {
 | 
				
			||||||
          <RecordProvider record={null}>
 | 
					                insertSelector(schema.Selector);
 | 
				
			||||||
            <RecursionField
 | 
					                setVisibleSelector(true);
 | 
				
			||||||
              onlyRenderProperties
 | 
					 | 
				
			||||||
              basePath={field.address}
 | 
					 | 
				
			||||||
              schema={fieldSchema}
 | 
					 | 
				
			||||||
              filterProperties={(s) => {
 | 
					 | 
				
			||||||
                return s['x-component'] === 'Action';
 | 
					 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
 | 
					              allowClear
 | 
				
			||||||
 | 
					              onChange={(changed: any) => {
 | 
				
			||||||
 | 
					                if (!changed) {
 | 
				
			||||||
 | 
					                  const value = multiple ? [] : null;
 | 
				
			||||||
 | 
					                  onChange(value);
 | 
				
			||||||
 | 
					                  setSelectedRows(value);
 | 
				
			||||||
 | 
					                } else if (Array.isArray(changed)) {
 | 
				
			||||||
 | 
					                  if (!changed.length) {
 | 
				
			||||||
 | 
					                    onChange([]);
 | 
				
			||||||
 | 
					                    setSelectedRows([]);
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                  const values = options?.filter((option) => changed.includes(option[fieldNames.value]));
 | 
				
			||||||
 | 
					                  onChange(values);
 | 
				
			||||||
 | 
					                  setSelectedRows(values);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					              options={options}
 | 
				
			||||||
 | 
					              value={getValue()}
 | 
				
			||||||
 | 
					              open={false}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </RecordProvider>
 | 
					          </div>
 | 
				
			||||||
        )}
 | 
					          {isAllowAddNew && (
 | 
				
			||||||
      </Input.Group>
 | 
					            <RecordProvider record={null}>
 | 
				
			||||||
      <ActionContext.Provider value={{ openMode: 'drawer', visible: visibleSelector, setVisible: setVisibleSelector }}>
 | 
					              <RecursionField
 | 
				
			||||||
        <RecordPickerProvider {...pickerProps}>
 | 
					                onlyRenderProperties
 | 
				
			||||||
          <CollectionProvider name={collectionField?.target}>
 | 
					                basePath={field.address}
 | 
				
			||||||
            <FormProvider>
 | 
					                schema={fieldSchema}
 | 
				
			||||||
              <TableSelectorParamsProvider params={{ filter: getFilter() }}>
 | 
					                filterProperties={(s) => {
 | 
				
			||||||
                <SchemaComponentOptions scope={{ usePickActionProps, useTableSelectorProps }}>
 | 
					                  return s['x-component'] === 'Action';
 | 
				
			||||||
                  <RecursionField
 | 
					                }}
 | 
				
			||||||
                    onlyRenderProperties
 | 
					              />
 | 
				
			||||||
                    basePath={field.address}
 | 
					            </RecordProvider>
 | 
				
			||||||
                    schema={fieldSchema}
 | 
					          )}
 | 
				
			||||||
                    filterProperties={(s) => {
 | 
					        </Input.Group>
 | 
				
			||||||
                      return s['x-component'] === 'AssociationField.Selector';
 | 
					        <ActionContext.Provider
 | 
				
			||||||
                    }}
 | 
					          value={{ openMode: 'drawer', visible: visibleSelector, setVisible: setVisibleSelector }}
 | 
				
			||||||
                  />
 | 
					        >
 | 
				
			||||||
                </SchemaComponentOptions>
 | 
					          <RecordPickerProvider {...pickerProps}>
 | 
				
			||||||
              </TableSelectorParamsProvider>
 | 
					            <CollectionProvider name={collectionField?.target}>
 | 
				
			||||||
            </FormProvider>
 | 
					              <FormProvider>
 | 
				
			||||||
          </CollectionProvider>
 | 
					                <TableSelectorParamsProvider params={{ filter: getFilter() }}>
 | 
				
			||||||
        </RecordPickerProvider>
 | 
					                  <SchemaComponentOptions scope={{ usePickActionProps, useTableSelectorProps }}>
 | 
				
			||||||
      </ActionContext.Provider>
 | 
					                    <RecursionField
 | 
				
			||||||
    </>
 | 
					                      onlyRenderProperties
 | 
				
			||||||
  );
 | 
					                      basePath={field.address}
 | 
				
			||||||
});
 | 
					                      schema={fieldSchema}
 | 
				
			||||||
 | 
					                      filterProperties={(s) => {
 | 
				
			||||||
 | 
					                        return s['x-component'] === 'AssociationField.Selector';
 | 
				
			||||||
 | 
					                      }}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                  </SchemaComponentOptions>
 | 
				
			||||||
 | 
					                </TableSelectorParamsProvider>
 | 
				
			||||||
 | 
					              </FormProvider>
 | 
				
			||||||
 | 
					            </CollectionProvider>
 | 
				
			||||||
 | 
					          </RecordPickerProvider>
 | 
				
			||||||
 | 
					        </ActionContext.Provider>
 | 
				
			||||||
 | 
					      </>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'InternalPicker' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -22,94 +22,97 @@ const toValue = (value, placeholder) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return value;
 | 
					  return value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
export const ReadPrettyInternalViewer: React.FC = observer((props: any) => {
 | 
					export const ReadPrettyInternalViewer: React.FC = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props: any) => {
 | 
				
			||||||
  const recordCtx = useRecord();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { enableLink } = fieldSchema['x-component-props'];
 | 
					    const recordCtx = useRecord();
 | 
				
			||||||
  // value 做了转换,但 props.value 和原来 useField().value 的值不一致
 | 
					    const { enableLink } = fieldSchema['x-component-props'];
 | 
				
			||||||
  const field = useField();
 | 
					    // value 做了转换,但 props.value 和原来 useField().value 的值不一致
 | 
				
			||||||
  const fieldNames = useFieldNames(props);
 | 
					    const field = useField();
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const fieldNames = useFieldNames(props);
 | 
				
			||||||
  const insertViewer = useInsertSchema('Viewer');
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
  const { options: collectionField } = useAssociationFieldContext();
 | 
					    const insertViewer = useInsertSchema('Viewer');
 | 
				
			||||||
  const [record, setRecord] = useState({});
 | 
					    const { options: collectionField } = useAssociationFieldContext();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const [record, setRecord] = useState({});
 | 
				
			||||||
  const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const { snapshot } = useActionContext();
 | 
					    const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
				
			||||||
  const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>();
 | 
					    const { snapshot } = useActionContext();
 | 
				
			||||||
 | 
					    const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const renderRecords = () =>
 | 
					    const renderRecords = () =>
 | 
				
			||||||
    toArr(props.value).map((record, index, arr) => {
 | 
					      toArr(props.value).map((record, index, arr) => {
 | 
				
			||||||
      const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A');
 | 
					        const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A');
 | 
				
			||||||
      const text = getLabelFormatValue(compile(labelUiSchema), val, true);
 | 
					        const text = getLabelFormatValue(compile(labelUiSchema), val, true);
 | 
				
			||||||
      return (
 | 
					        return (
 | 
				
			||||||
        <Fragment key={`${record.id}_${index}`}>
 | 
					          <Fragment key={`${record.id}_${index}`}>
 | 
				
			||||||
          <span>
 | 
					            <span>
 | 
				
			||||||
            {snapshot ? (
 | 
					              {snapshot ? (
 | 
				
			||||||
              text
 | 
					                text
 | 
				
			||||||
            ) : enableLink !== false ? (
 | 
					              ) : enableLink !== false ? (
 | 
				
			||||||
              <a
 | 
					                <a
 | 
				
			||||||
                onClick={(e) => {
 | 
					                  onClick={(e) => {
 | 
				
			||||||
                  e.stopPropagation();
 | 
					                    e.stopPropagation();
 | 
				
			||||||
                  e.preventDefault();
 | 
					                    e.preventDefault();
 | 
				
			||||||
                  insertViewer(schema.Viewer);
 | 
					                    insertViewer(schema.Viewer);
 | 
				
			||||||
                  setVisible(true);
 | 
					                    setVisible(true);
 | 
				
			||||||
                  setRecord(record);
 | 
					                    setRecord(record);
 | 
				
			||||||
                  ellipsisWithTooltipRef?.current?.setPopoverVisible(false);
 | 
					                    ellipsisWithTooltipRef?.current?.setPopoverVisible(false);
 | 
				
			||||||
                }}
 | 
					                  }}
 | 
				
			||||||
              >
 | 
					                >
 | 
				
			||||||
                {text}
 | 
					                  {text}
 | 
				
			||||||
              </a>
 | 
					                </a>
 | 
				
			||||||
            ) : (
 | 
					              ) : (
 | 
				
			||||||
              text
 | 
					                text
 | 
				
			||||||
            )}
 | 
					              )}
 | 
				
			||||||
          </span>
 | 
					            </span>
 | 
				
			||||||
          {index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>,</span> : null}
 | 
					            {index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>,</span> : null}
 | 
				
			||||||
        </Fragment>
 | 
					          </Fragment>
 | 
				
			||||||
      );
 | 
					        );
 | 
				
			||||||
    });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const renderWithoutTableFieldResourceProvider = () => (
 | 
					    const renderWithoutTableFieldResourceProvider = () => (
 | 
				
			||||||
    <WithoutTableFieldResource.Provider value={true}>
 | 
					      <WithoutTableFieldResource.Provider value={true}>
 | 
				
			||||||
      <FormProvider>
 | 
					        <FormProvider>
 | 
				
			||||||
        <RecursionField
 | 
					          <RecursionField
 | 
				
			||||||
          schema={fieldSchema}
 | 
					            schema={fieldSchema}
 | 
				
			||||||
          onlyRenderProperties
 | 
					            onlyRenderProperties
 | 
				
			||||||
          basePath={field.address}
 | 
					            basePath={field.address}
 | 
				
			||||||
          filterProperties={(s) => {
 | 
					            filterProperties={(s) => {
 | 
				
			||||||
            return s['x-component'] === 'AssociationField.Viewer';
 | 
					              return s['x-component'] === 'AssociationField.Viewer';
 | 
				
			||||||
          }}
 | 
					            }}
 | 
				
			||||||
        />
 | 
					          />
 | 
				
			||||||
      </FormProvider>
 | 
					        </FormProvider>
 | 
				
			||||||
    </WithoutTableFieldResource.Provider>
 | 
					      </WithoutTableFieldResource.Provider>
 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const renderRecordProvider = () => {
 | 
					 | 
				
			||||||
    const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return collectionFieldNames && collectionFieldNames.length > 2 ? (
 | 
					 | 
				
			||||||
      <RecordProvider record={recordCtx[collectionFieldNames[1]]}>
 | 
					 | 
				
			||||||
        <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
					 | 
				
			||||||
      </RecordProvider>
 | 
					 | 
				
			||||||
    ) : (
 | 
					 | 
				
			||||||
      <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    const renderRecordProvider = () => {
 | 
				
			||||||
    <div>
 | 
					      const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.');
 | 
				
			||||||
      <BlockAssociationContext.Provider value={`${collectionField?.collectionName}.${collectionField?.name}`}>
 | 
					
 | 
				
			||||||
        <CollectionProvider name={collectionField?.target ?? collectionField?.targetCollection}>
 | 
					      return collectionFieldNames && collectionFieldNames.length > 2 ? (
 | 
				
			||||||
          <EllipsisWithTooltip ellipsis={true} ref={ellipsisWithTooltipRef}>
 | 
					        <RecordProvider record={recordCtx[collectionFieldNames[1]]}>
 | 
				
			||||||
            {renderRecords()}
 | 
					          <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
				
			||||||
          </EllipsisWithTooltip>
 | 
					        </RecordProvider>
 | 
				
			||||||
          <ActionContext.Provider
 | 
					      ) : (
 | 
				
			||||||
            value={{ visible, setVisible, openMode: 'drawer', snapshot: collectionField?.interface === 'snapshot' }}
 | 
					        <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
				
			||||||
          >
 | 
					      );
 | 
				
			||||||
            {renderRecordProvider()}
 | 
					    };
 | 
				
			||||||
          </ActionContext.Provider>
 | 
					
 | 
				
			||||||
        </CollectionProvider>
 | 
					    return (
 | 
				
			||||||
      </BlockAssociationContext.Provider>
 | 
					      <div>
 | 
				
			||||||
    </div>
 | 
					        <BlockAssociationContext.Provider value={`${collectionField?.collectionName}.${collectionField?.name}`}>
 | 
				
			||||||
  );
 | 
					          <CollectionProvider name={collectionField?.target ?? collectionField?.targetCollection}>
 | 
				
			||||||
});
 | 
					            <EllipsisWithTooltip ellipsis={true} ref={ellipsisWithTooltipRef}>
 | 
				
			||||||
 | 
					              {renderRecords()}
 | 
				
			||||||
 | 
					            </EllipsisWithTooltip>
 | 
				
			||||||
 | 
					            <ActionContext.Provider
 | 
				
			||||||
 | 
					              value={{ visible, setVisible, openMode: 'drawer', snapshot: collectionField?.interface === 'snapshot' }}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              {renderRecordProvider()}
 | 
				
			||||||
 | 
					            </ActionContext.Provider>
 | 
				
			||||||
 | 
					          </CollectionProvider>
 | 
				
			||||||
 | 
					        </BlockAssociationContext.Provider>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPrettyInternalViewer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -25,92 +25,95 @@ const ToOneNester = (props) => {
 | 
				
			|||||||
  return <Card bordered={true}>{props.children}</Card>;
 | 
					  return <Card bordered={true}>{props.children}</Card>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ToManyNester = observer((props) => {
 | 
					const ToManyNester = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  const { options, field, allowMultiple, allowDissociate } = useAssociationFieldContext<ArrayField>();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const { options, field, allowMultiple, allowDissociate } = useAssociationFieldContext<ArrayField>();
 | 
				
			||||||
  return (field.value || []).length > 0 ? (
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
    <Card
 | 
					    return (field.value || []).length > 0 ? (
 | 
				
			||||||
      bordered={true}
 | 
					      <Card
 | 
				
			||||||
      style={{ position: 'relative' }}
 | 
					        bordered={true}
 | 
				
			||||||
      className={css`
 | 
					        style={{ position: 'relative' }}
 | 
				
			||||||
        > .ant-card-body > .ant-divider:last-child {
 | 
					        className={css`
 | 
				
			||||||
          display: none;
 | 
					          > .ant-card-body > .ant-divider:last-child {
 | 
				
			||||||
        }
 | 
					            display: none;
 | 
				
			||||||
      `}
 | 
					          }
 | 
				
			||||||
    >
 | 
					        `}
 | 
				
			||||||
      {(field.value || []).map((value, index) => {
 | 
					      >
 | 
				
			||||||
        let allowed = allowDissociate;
 | 
					        {(field.value || []).map((value, index) => {
 | 
				
			||||||
        if (!allowDissociate) {
 | 
					          let allowed = allowDissociate;
 | 
				
			||||||
          allowed = !value?.[options.targetKey];
 | 
					          if (!allowDissociate) {
 | 
				
			||||||
        }
 | 
					            allowed = !value?.[options.targetKey];
 | 
				
			||||||
        return (
 | 
					          }
 | 
				
			||||||
          <>
 | 
					          return (
 | 
				
			||||||
            <div style={{ textAlign: 'right' }}>
 | 
					            <>
 | 
				
			||||||
              {field.editable && allowMultiple && (
 | 
					              <div style={{ textAlign: 'right' }}>
 | 
				
			||||||
                <Tooltip key={'add'} title={t('Add new')}>
 | 
					                {field.editable && allowMultiple && (
 | 
				
			||||||
                  <PlusOutlined
 | 
					                  <Tooltip key={'add'} title={t('Add new')}>
 | 
				
			||||||
                    style={{ zIndex: 1000, marginRight: '10px', color: '#a8a3a3' }}
 | 
					                    <PlusOutlined
 | 
				
			||||||
                    onClick={() => {
 | 
					                      style={{ zIndex: 1000, marginRight: '10px', color: '#a8a3a3' }}
 | 
				
			||||||
                      action(() => {
 | 
					                      onClick={() => {
 | 
				
			||||||
                        if (!Array.isArray(field.value)) {
 | 
					                        action(() => {
 | 
				
			||||||
                          field.value = [];
 | 
					                          if (!Array.isArray(field.value)) {
 | 
				
			||||||
                        }
 | 
					                            field.value = [];
 | 
				
			||||||
                        spliceArrayState(field as any, {
 | 
					                          }
 | 
				
			||||||
                          startIndex: index + 1,
 | 
					                          spliceArrayState(field as any, {
 | 
				
			||||||
                          insertCount: 1,
 | 
					                            startIndex: index + 1,
 | 
				
			||||||
 | 
					                            insertCount: 1,
 | 
				
			||||||
 | 
					                          });
 | 
				
			||||||
 | 
					                          field.value.splice(index + 1, 0, {});
 | 
				
			||||||
 | 
					                          return field.onInput(field.value);
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        field.value.splice(index + 1, 0, {});
 | 
					                      }}
 | 
				
			||||||
                        return field.onInput(field.value);
 | 
					                    />
 | 
				
			||||||
                      });
 | 
					                  </Tooltip>
 | 
				
			||||||
                    }}
 | 
					                )}
 | 
				
			||||||
                  />
 | 
					                {!field.readPretty && allowed && (
 | 
				
			||||||
                </Tooltip>
 | 
					                  <Tooltip key={'remove'} title={t('Remove')}>
 | 
				
			||||||
              )}
 | 
					                    <CloseOutlined
 | 
				
			||||||
              {!field.readPretty && allowed && (
 | 
					                      style={{ zIndex: 1000, color: '#a8a3a3' }}
 | 
				
			||||||
                <Tooltip key={'remove'} title={t('Remove')}>
 | 
					                      onClick={() => {
 | 
				
			||||||
                  <CloseOutlined
 | 
					                        action(() => {
 | 
				
			||||||
                    style={{ zIndex: 1000, color: '#a8a3a3' }}
 | 
					                          spliceArrayState(field as any, {
 | 
				
			||||||
                    onClick={() => {
 | 
					                            startIndex: index,
 | 
				
			||||||
                      action(() => {
 | 
					                            deleteCount: 1,
 | 
				
			||||||
                        spliceArrayState(field as any, {
 | 
					                          });
 | 
				
			||||||
                          startIndex: index,
 | 
					                          field.value.splice(index, 1);
 | 
				
			||||||
                          deleteCount: 1,
 | 
					                          return field.onInput(field.value);
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        field.value.splice(index, 1);
 | 
					                      }}
 | 
				
			||||||
                        return field.onInput(field.value);
 | 
					                    />
 | 
				
			||||||
                      });
 | 
					                  </Tooltip>
 | 
				
			||||||
                    }}
 | 
					                )}
 | 
				
			||||||
                  />
 | 
					              </div>
 | 
				
			||||||
                </Tooltip>
 | 
					              <RecursionField onlyRenderProperties basePath={field.address.concat(index)} schema={fieldSchema} />
 | 
				
			||||||
              )}
 | 
					              <Divider />
 | 
				
			||||||
            </div>
 | 
					            </>
 | 
				
			||||||
            <RecursionField onlyRenderProperties basePath={field.address.concat(index)} schema={fieldSchema} />
 | 
					          );
 | 
				
			||||||
            <Divider />
 | 
					        })}
 | 
				
			||||||
          </>
 | 
					      </Card>
 | 
				
			||||||
        );
 | 
					    ) : (
 | 
				
			||||||
      })}
 | 
					      <>
 | 
				
			||||||
    </Card>
 | 
					        {field.editable && allowMultiple && (
 | 
				
			||||||
  ) : (
 | 
					          <Tooltip key={'add'} title={t('Add new')}>
 | 
				
			||||||
    <>
 | 
					            <Button
 | 
				
			||||||
      {field.editable && allowMultiple && (
 | 
					              type={'default'}
 | 
				
			||||||
        <Tooltip key={'add'} title={t('Add new')}>
 | 
					              className={css`
 | 
				
			||||||
          <Button
 | 
					                border: 1px solid #f0f0f0 !important;
 | 
				
			||||||
            type={'default'}
 | 
					                box-shadow: none;
 | 
				
			||||||
            className={css`
 | 
					              `}
 | 
				
			||||||
              border: 1px solid #f0f0f0 !important;
 | 
					              block
 | 
				
			||||||
              box-shadow: none;
 | 
					              icon={<PlusOutlined />}
 | 
				
			||||||
            `}
 | 
					              onClick={() => {
 | 
				
			||||||
            block
 | 
					                const result = field.value;
 | 
				
			||||||
            icon={<PlusOutlined />}
 | 
					                result.push({});
 | 
				
			||||||
            onClick={() => {
 | 
					                field.value = result;
 | 
				
			||||||
              const result = field.value;
 | 
					              }}
 | 
				
			||||||
              result.push({});
 | 
					            ></Button>
 | 
				
			||||||
              field.value = result;
 | 
					          </Tooltip>
 | 
				
			||||||
            }}
 | 
					        )}
 | 
				
			||||||
          ></Button>
 | 
					      </>
 | 
				
			||||||
        </Tooltip>
 | 
					    );
 | 
				
			||||||
      )}
 | 
					  },
 | 
				
			||||||
    </>
 | 
					  { displayName: 'ToManyNester' },
 | 
				
			||||||
  );
 | 
					);
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -7,23 +7,29 @@ import { InternalSubTable } from './InternalSubTable';
 | 
				
			|||||||
import { FileManageReadPretty } from './FileManager';
 | 
					import { FileManageReadPretty } from './FileManager';
 | 
				
			||||||
import { useAssociationFieldContext } from './hooks';
 | 
					import { useAssociationFieldContext } from './hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ReadPrettyAssociationField = observer((props: any) => {
 | 
					const ReadPrettyAssociationField = observer(
 | 
				
			||||||
  const { currentMode } = useAssociationFieldContext();
 | 
					  (props: any) => {
 | 
				
			||||||
 | 
					    const { currentMode } = useAssociationFieldContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <>
 | 
					      <>
 | 
				
			||||||
      {['Select', 'Picker'].includes(currentMode) && <ReadPrettyInternalViewer {...props} />}
 | 
					        {['Select', 'Picker'].includes(currentMode) && <ReadPrettyInternalViewer {...props} />}
 | 
				
			||||||
      {currentMode === 'Nester' && <InternalNester {...props} />}
 | 
					        {currentMode === 'Nester' && <InternalNester {...props} />}
 | 
				
			||||||
      {currentMode === 'SubTable' && <InternalSubTable {...props} />}
 | 
					        {currentMode === 'SubTable' && <InternalSubTable {...props} />}
 | 
				
			||||||
      {currentMode === 'FileManager' && <FileManageReadPretty {...props} />}
 | 
					        {currentMode === 'FileManager' && <FileManageReadPretty {...props} />}
 | 
				
			||||||
    </>
 | 
					      </>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPrettyAssociationField' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReadPretty = observer((props) => {
 | 
					export const ReadPretty = observer(
 | 
				
			||||||
  return (
 | 
					  (props) => {
 | 
				
			||||||
    <AssociationFieldProvider>
 | 
					    return (
 | 
				
			||||||
      <ReadPrettyAssociationField {...props} />
 | 
					      <AssociationFieldProvider>
 | 
				
			||||||
    </AssociationFieldProvider>
 | 
					        <ReadPrettyAssociationField {...props} />
 | 
				
			||||||
  );
 | 
					      </AssociationFieldProvider>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPretty' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -5,24 +5,27 @@ import React from 'react';
 | 
				
			|||||||
import { Table } from '../table-v2/Table';
 | 
					import { Table } from '../table-v2/Table';
 | 
				
			||||||
import { useAssociationFieldContext } from './hooks';
 | 
					import { useAssociationFieldContext } from './hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SubTable: any = observer((props) => {
 | 
					export const SubTable: any = observer(
 | 
				
			||||||
  const { field } = useAssociationFieldContext<ArrayField>();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const { field } = useAssociationFieldContext<ArrayField>();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Table size={'small'} showIndex field={field} pagination={false} />
 | 
					      <div>
 | 
				
			||||||
      {field.editable && (
 | 
					        <Table size={'small'} showIndex field={field} pagination={false} />
 | 
				
			||||||
        <Button
 | 
					        {field.editable && (
 | 
				
			||||||
          type={'dashed'}
 | 
					          <Button
 | 
				
			||||||
          block
 | 
					            type={'dashed'}
 | 
				
			||||||
          style={{ marginTop: 12 }}
 | 
					            block
 | 
				
			||||||
          onClick={() => {
 | 
					            style={{ marginTop: 12 }}
 | 
				
			||||||
            field.value = field.value || [];
 | 
					            onClick={() => {
 | 
				
			||||||
            field.value.push({});
 | 
					              field.value = field.value || [];
 | 
				
			||||||
          }}
 | 
					              field.value.push({});
 | 
				
			||||||
        >
 | 
					            }}
 | 
				
			||||||
          Add new
 | 
					          >
 | 
				
			||||||
        </Button>
 | 
					            Add new
 | 
				
			||||||
      )}
 | 
					          </Button>
 | 
				
			||||||
    </div>
 | 
					        )}
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'SubTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,34 +6,37 @@ import { ActionContext, useActionContext } from '../../action';
 | 
				
			|||||||
import { useAssociationFieldContext, useInsertSchema } from '../hooks';
 | 
					import { useAssociationFieldContext, useInsertSchema } from '../hooks';
 | 
				
			||||||
import schema from '../schema';
 | 
					import schema from '../schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CreateRecordAction = observer((props) => {
 | 
					export const CreateRecordAction = observer(
 | 
				
			||||||
  const field: any = useField();
 | 
					  (props) => {
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field: any = useField();
 | 
				
			||||||
  const ctx = useActionContext();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const insertAddNewer = useInsertSchema('AddNewer');
 | 
					    const ctx = useActionContext();
 | 
				
			||||||
  const { options: collectionField } = useAssociationFieldContext();
 | 
					    const insertAddNewer = useInsertSchema('AddNewer');
 | 
				
			||||||
  const [visibleAddNewer, setVisibleAddNewer] = useState(false);
 | 
					    const { options: collectionField } = useAssociationFieldContext();
 | 
				
			||||||
  const [currentCollection, setCurrentCollection] = useState(collectionField?.target);
 | 
					    const [visibleAddNewer, setVisibleAddNewer] = useState(false);
 | 
				
			||||||
  const addbuttonClick = (name) => {
 | 
					    const [currentCollection, setCurrentCollection] = useState(collectionField?.target);
 | 
				
			||||||
    insertAddNewer(schema.AddNewer);
 | 
					    const addbuttonClick = (name) => {
 | 
				
			||||||
    setVisibleAddNewer(true);
 | 
					      insertAddNewer(schema.AddNewer);
 | 
				
			||||||
    setCurrentCollection(name);
 | 
					      setVisibleAddNewer(true);
 | 
				
			||||||
  };
 | 
					      setCurrentCollection(name);
 | 
				
			||||||
  return (
 | 
					    };
 | 
				
			||||||
    <CollectionProvider name={collectionField?.target}>
 | 
					    return (
 | 
				
			||||||
      <CreateAction {...props} onClick={(arg) => addbuttonClick(arg)} />
 | 
					      <CollectionProvider name={collectionField?.target}>
 | 
				
			||||||
      <ActionContext.Provider value={{ ...ctx, visible: visibleAddNewer, setVisible: setVisibleAddNewer }}>
 | 
					        <CreateAction {...props} onClick={(arg) => addbuttonClick(arg)} />
 | 
				
			||||||
        <CollectionProvider name={currentCollection}>
 | 
					        <ActionContext.Provider value={{ ...ctx, visible: visibleAddNewer, setVisible: setVisibleAddNewer }}>
 | 
				
			||||||
          <RecursionField
 | 
					          <CollectionProvider name={currentCollection}>
 | 
				
			||||||
            onlyRenderProperties
 | 
					            <RecursionField
 | 
				
			||||||
            basePath={field.address}
 | 
					              onlyRenderProperties
 | 
				
			||||||
            schema={fieldSchema}
 | 
					              basePath={field.address}
 | 
				
			||||||
            filterProperties={(s) => {
 | 
					              schema={fieldSchema}
 | 
				
			||||||
              return s['x-component'] === 'AssociationField.AddNewer';
 | 
					              filterProperties={(s) => {
 | 
				
			||||||
            }}
 | 
					                return s['x-component'] === 'AssociationField.AddNewer';
 | 
				
			||||||
          />
 | 
					              }}
 | 
				
			||||||
        </CollectionProvider>
 | 
					            />
 | 
				
			||||||
      </ActionContext.Provider>
 | 
					          </CollectionProvider>
 | 
				
			||||||
    </CollectionProvider>
 | 
					        </ActionContext.Provider>
 | 
				
			||||||
  );
 | 
					      </CollectionProvider>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'CreateRecordAction' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,11 @@ import { useFieldTitle } from '../../hooks';
 | 
				
			|||||||
import { RemoteSelect } from '../remote-select';
 | 
					import { RemoteSelect } from '../remote-select';
 | 
				
			||||||
import useServiceOptions from './useServiceOptions';
 | 
					import useServiceOptions from './useServiceOptions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReadPretty = observer((props: any) => {
 | 
					export const ReadPretty = observer(
 | 
				
			||||||
  const service = useServiceOptions(props);
 | 
					  (props: any) => {
 | 
				
			||||||
  useFieldTitle();
 | 
					    const service = useServiceOptions(props);
 | 
				
			||||||
  return <RemoteSelect.ReadPretty {...props} service={service}></RemoteSelect.ReadPretty>;
 | 
					    useFieldTitle();
 | 
				
			||||||
});
 | 
					    return <RemoteSelect.ReadPretty {...props} service={service}></RemoteSelect.ReadPretty>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPretty' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,15 +3,18 @@ import { uid } from '@formily/shared';
 | 
				
			|||||||
import { BlockItem, DndContext, DragHandler, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
					import { BlockItem, DndContext, DragHandler, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Block = observer((props) => {
 | 
					const Block = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
    <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
					    return (
 | 
				
			||||||
      Block {fieldSchema.name}
 | 
					      <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
				
			||||||
      <DragHandler />
 | 
					        Block {fieldSchema.name}
 | 
				
			||||||
    </div>
 | 
					        <DragHandler />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Block' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -190,71 +190,74 @@ const CalendarRecordViewer = (props) => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Calendar: any = observer((props: any) => {
 | 
					export const Calendar: any = observer(
 | 
				
			||||||
  const { dataSource, fieldNames, showLunar, fixedBlock } = useProps(props);
 | 
					  (props: any) => {
 | 
				
			||||||
  const [date, setDate] = useState<Date>(new Date());
 | 
					    const { dataSource, fieldNames, showLunar, fixedBlock } = useProps(props);
 | 
				
			||||||
  const [view, setView] = useState<(typeof Weeks)[number]>('month');
 | 
					    const [date, setDate] = useState<Date>(new Date());
 | 
				
			||||||
  const events = useEvents(dataSource, fieldNames, date, view);
 | 
					    const [view, setView] = useState<(typeof Weeks)[number]>('month');
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const events = useEvents(dataSource, fieldNames, date, view);
 | 
				
			||||||
  const [record, setRecord] = useState<any>({});
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					    const [record, setRecord] = useState<any>({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const components = useMemo(() => {
 | 
					    const components = useMemo(() => {
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      toolbar: (props) => <Toolbar {...props} showLunar={showLunar}></Toolbar>,
 | 
					        toolbar: (props) => <Toolbar {...props} showLunar={showLunar}></Toolbar>,
 | 
				
			||||||
      week: {
 | 
					        week: {
 | 
				
			||||||
        header: (props) => <Header {...props} type="week" showLunar={showLunar}></Header>,
 | 
					          header: (props) => <Header {...props} type="week" showLunar={showLunar}></Header>,
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
      month: {
 | 
					        month: {
 | 
				
			||||||
        dateHeader: (props) => <Header {...props} showLunar={showLunar}></Header>,
 | 
					          dateHeader: (props) => <Header {...props} showLunar={showLunar}></Header>,
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
    };
 | 
					      };
 | 
				
			||||||
  }, [showLunar]);
 | 
					    }, [showLunar]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div style={{ height: fixedBlock ? '100%' : 700 }}>
 | 
					      <div style={{ height: fixedBlock ? '100%' : 700 }}>
 | 
				
			||||||
      <CalendarRecordViewer visible={visible} setVisible={setVisible} record={record} />
 | 
					        <CalendarRecordViewer visible={visible} setVisible={setVisible} record={record} />
 | 
				
			||||||
      <BigCalendar
 | 
					        <BigCalendar
 | 
				
			||||||
        popup
 | 
					          popup
 | 
				
			||||||
        selectable
 | 
					          selectable
 | 
				
			||||||
        events={events}
 | 
					          events={events}
 | 
				
			||||||
        view={view}
 | 
					          view={view}
 | 
				
			||||||
        views={Weeks}
 | 
					          views={Weeks}
 | 
				
			||||||
        date={date}
 | 
					          date={date}
 | 
				
			||||||
        step={60}
 | 
					          step={60}
 | 
				
			||||||
        showMultiDayTimes
 | 
					          showMultiDayTimes
 | 
				
			||||||
        messages={messages}
 | 
					          messages={messages}
 | 
				
			||||||
        onNavigate={setDate}
 | 
					          onNavigate={setDate}
 | 
				
			||||||
        onView={setView}
 | 
					          onView={setView}
 | 
				
			||||||
        onSelectSlot={(slotInfo) => {
 | 
					          onSelectSlot={(slotInfo) => {
 | 
				
			||||||
          console.log('onSelectSlot', slotInfo);
 | 
					            console.log('onSelectSlot', slotInfo);
 | 
				
			||||||
        }}
 | 
					          }}
 | 
				
			||||||
        onDoubleClickEvent={(event) => {
 | 
					          onDoubleClickEvent={(event) => {
 | 
				
			||||||
          console.log('onDoubleClickEvent');
 | 
					            console.log('onDoubleClickEvent');
 | 
				
			||||||
        }}
 | 
					          }}
 | 
				
			||||||
        onSelectEvent={(event) => {
 | 
					          onSelectEvent={(event) => {
 | 
				
			||||||
          const record = dataSource?.find((item) => item[fieldNames.id] === event.id);
 | 
					            const record = dataSource?.find((item) => item[fieldNames.id] === event.id);
 | 
				
			||||||
          if (!record) {
 | 
					            if (!record) {
 | 
				
			||||||
            return;
 | 
					              return;
 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          record.__event = { ...event, start: formatDate(moment(event.start)), end: formatDate(moment(event.end)) };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          setRecord(record);
 | 
					 | 
				
			||||||
          setVisible(true);
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        formats={{
 | 
					 | 
				
			||||||
          monthHeaderFormat: 'Y-M',
 | 
					 | 
				
			||||||
          agendaDateFormat: 'M-DD',
 | 
					 | 
				
			||||||
          dayHeaderFormat: 'Y-M-DD',
 | 
					 | 
				
			||||||
          dayRangeHeaderFormat: ({ start, end }, culture, local) => {
 | 
					 | 
				
			||||||
            if (dates.eq(start, end, 'month')) {
 | 
					 | 
				
			||||||
              return local.format(start, 'Y-M', culture);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return `${local.format(start, 'Y-M', culture)} - ${local.format(end, 'Y-M', culture)}`;
 | 
					            record.__event = { ...event, start: formatDate(moment(event.start)), end: formatDate(moment(event.end)) };
 | 
				
			||||||
          },
 | 
					
 | 
				
			||||||
        }}
 | 
					            setRecord(record);
 | 
				
			||||||
        components={components}
 | 
					            setVisible(true);
 | 
				
			||||||
        localizer={localizer}
 | 
					          }}
 | 
				
			||||||
      />
 | 
					          formats={{
 | 
				
			||||||
    </div>
 | 
					            monthHeaderFormat: 'Y-M',
 | 
				
			||||||
  );
 | 
					            agendaDateFormat: 'M-DD',
 | 
				
			||||||
});
 | 
					            dayHeaderFormat: 'Y-M-DD',
 | 
				
			||||||
 | 
					            dayRangeHeaderFormat: ({ start, end }, culture, local) => {
 | 
				
			||||||
 | 
					              if (dates.eq(start, end, 'month')) {
 | 
				
			||||||
 | 
					                return local.format(start, 'Y-M', culture);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              return `${local.format(start, 'Y-M', culture)} - ${local.format(end, 'Y-M', culture)}`;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          components={components}
 | 
				
			||||||
 | 
					          localizer={localizer}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Calendar' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,61 +11,64 @@ import { DeleteEventContext } from './Calendar';
 | 
				
			|||||||
import { formatDate } from './utils';
 | 
					import { formatDate } from './utils';
 | 
				
			||||||
const { Text } = Typography;
 | 
					const { Text } = Typography;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const DeleteEvent = observer(() => {
 | 
					export const DeleteEvent = observer(
 | 
				
			||||||
  const { visible, setVisible } = useActionContext();
 | 
					  () => {
 | 
				
			||||||
  const { exclude = [], cron, ...record } = useRecord();
 | 
					    const { visible, setVisible } = useActionContext();
 | 
				
			||||||
  const { close } = useContext(DeleteEventContext);
 | 
					    const { exclude = [], cron, ...record } = useRecord();
 | 
				
			||||||
  const startDate = formatDate(moment(record.__parent.__event.start));
 | 
					    const { close } = useContext(DeleteEventContext);
 | 
				
			||||||
  const filterByTk = useFilterByTk();
 | 
					    const startDate = formatDate(moment(record.__parent.__event.start));
 | 
				
			||||||
  const { resource, service, __parent } = useBlockRequestContext();
 | 
					    const filterByTk = useFilterByTk();
 | 
				
			||||||
  const [value, onChange] = useState(startDate);
 | 
					    const { resource, service, __parent } = useBlockRequestContext();
 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					    const [value, onChange] = useState(startDate);
 | 
				
			||||||
  const onOk = async () => {
 | 
					    const [loading, setLoading] = useState(false);
 | 
				
			||||||
    setLoading(true);
 | 
					    const onOk = async () => {
 | 
				
			||||||
    if (value === 'all' || !cron) {
 | 
					      setLoading(true);
 | 
				
			||||||
      await resource.destroy({
 | 
					      if (value === 'all' || !cron) {
 | 
				
			||||||
        filterByTk,
 | 
					        await resource.destroy({
 | 
				
			||||||
      });
 | 
					          filterByTk,
 | 
				
			||||||
    } else {
 | 
					        });
 | 
				
			||||||
      await resource.update({
 | 
					      } else {
 | 
				
			||||||
        filterByTk,
 | 
					        await resource.update({
 | 
				
			||||||
        values: {
 | 
					          filterByTk,
 | 
				
			||||||
          exclude: (exclude || []).concat(value),
 | 
					          values: {
 | 
				
			||||||
        },
 | 
					            exclude: (exclude || []).concat(value),
 | 
				
			||||||
      });
 | 
					          },
 | 
				
			||||||
    }
 | 
					        });
 | 
				
			||||||
    setLoading(false);
 | 
					      }
 | 
				
			||||||
    __parent?.service?.refresh?.();
 | 
					      setLoading(false);
 | 
				
			||||||
    service?.refresh?.();
 | 
					      __parent?.service?.refresh?.();
 | 
				
			||||||
    setVisible?.(false, true);
 | 
					      service?.refresh?.();
 | 
				
			||||||
    close();
 | 
					      setVisible?.(false, true);
 | 
				
			||||||
  };
 | 
					      close();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  return createPortal(
 | 
					    return createPortal(
 | 
				
			||||||
    <Modal
 | 
					      <Modal
 | 
				
			||||||
      title={cron ? t('Delete events') : null}
 | 
					        title={cron ? t('Delete events') : null}
 | 
				
			||||||
      visible={visible}
 | 
					        visible={visible}
 | 
				
			||||||
      onCancel={() => setVisible(false)}
 | 
					        onCancel={() => setVisible(false)}
 | 
				
			||||||
      onOk={() => onOk()}
 | 
					        onOk={() => onOk()}
 | 
				
			||||||
      confirmLoading={loading}
 | 
					        confirmLoading={loading}
 | 
				
			||||||
    >
 | 
					      >
 | 
				
			||||||
      {cron ? (
 | 
					        {cron ? (
 | 
				
			||||||
        <Radio.Group value={value} onChange={(event) => onChange(event.target.value)}>
 | 
					          <Radio.Group value={value} onChange={(event) => onChange(event.target.value)}>
 | 
				
			||||||
          <Space direction="vertical">
 | 
					            <Space direction="vertical">
 | 
				
			||||||
            <Radio value={startDate}>{t('This event')}</Radio>
 | 
					              <Radio value={startDate}>{t('This event')}</Radio>
 | 
				
			||||||
            <Radio value={`${startDate}_after`}>{t('This and following events')}</Radio>
 | 
					              <Radio value={`${startDate}_after`}>{t('This and following events')}</Radio>
 | 
				
			||||||
            <Radio value="all">{t('All events')}</Radio>
 | 
					              <Radio value="all">{t('All events')}</Radio>
 | 
				
			||||||
          </Space>
 | 
					            </Space>
 | 
				
			||||||
        </Radio.Group>
 | 
					          </Radio.Group>
 | 
				
			||||||
      ) : (
 | 
					        ) : (
 | 
				
			||||||
        <Text strong style={{ fontSize: '18px' }}>
 | 
					          <Text strong style={{ fontSize: '18px' }}>
 | 
				
			||||||
          {t('Delete this event?')}
 | 
					            {t('Delete this event?')}
 | 
				
			||||||
        </Text>
 | 
					          </Text>
 | 
				
			||||||
      )}
 | 
					        )}
 | 
				
			||||||
    </Modal>,
 | 
					      </Modal>,
 | 
				
			||||||
    document.body,
 | 
					      document.body,
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'DeleteEvent' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default DeleteEvent;
 | 
					export default DeleteEvent;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
import { observer } from '@formily/react';
 | 
					import { observer } from '@formily/react';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Event = observer((props) => {
 | 
					export const Event = observer(
 | 
				
			||||||
  return <>{props.children}</>;
 | 
					  (props) => {
 | 
				
			||||||
});
 | 
					    return <>{props.children}</>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Event' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,14 +6,17 @@ import { navigate } from 'react-big-calendar/lib/utils/constants';
 | 
				
			|||||||
import { useDesignable } from '../../hooks';
 | 
					import { useDesignable } from '../../hooks';
 | 
				
			||||||
import { CalendarToolbarContext } from './context';
 | 
					import { CalendarToolbarContext } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Nav = observer((props) => {
 | 
					export const Nav = observer(
 | 
				
			||||||
  const { DesignableBar } = useDesignable();
 | 
					  (props) => {
 | 
				
			||||||
  const { onNavigate } = useContext(CalendarToolbarContext);
 | 
					    const { DesignableBar } = useDesignable();
 | 
				
			||||||
  return (
 | 
					    const { onNavigate } = useContext(CalendarToolbarContext);
 | 
				
			||||||
    <div className="ant-btn-group">
 | 
					    return (
 | 
				
			||||||
      <Button icon={<LeftOutlined />} onClick={() => onNavigate(navigate.PREVIOUS)}></Button>
 | 
					      <div className="ant-btn-group">
 | 
				
			||||||
      <Button icon={<RightOutlined />} onClick={() => onNavigate(navigate.NEXT)}></Button>
 | 
					        <Button icon={<LeftOutlined />} onClick={() => onNavigate(navigate.PREVIOUS)}></Button>
 | 
				
			||||||
      <DesignableBar />
 | 
					        <Button icon={<RightOutlined />} onClick={() => onNavigate(navigate.NEXT)}></Button>
 | 
				
			||||||
    </div>
 | 
					        <DesignableBar />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Nav' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,22 +4,25 @@ import { useDesignable } from '../../hooks';
 | 
				
			|||||||
import { CalendarToolbarContext } from './context';
 | 
					import { CalendarToolbarContext } from './context';
 | 
				
			||||||
import { getLunarDay } from './utils';
 | 
					import { getLunarDay } from './utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Title = observer(() => {
 | 
					export const Title = observer(
 | 
				
			||||||
  const { DesignableBar } = useDesignable();
 | 
					  () => {
 | 
				
			||||||
  const { date, view, label, showLunar } = useContext(CalendarToolbarContext);
 | 
					    const { DesignableBar } = useDesignable();
 | 
				
			||||||
 | 
					    const { date, view, label, showLunar } = useContext(CalendarToolbarContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const lunarElement = useMemo(() => {
 | 
					    const lunarElement = useMemo(() => {
 | 
				
			||||||
    if (!showLunar || view !== 'day') {
 | 
					      if (!showLunar || view !== 'day') {
 | 
				
			||||||
      return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					      }
 | 
				
			||||||
    return <span>{getLunarDay(date)}</span>;
 | 
					      return <span>{getLunarDay(date)}</span>;
 | 
				
			||||||
  }, [view, date, showLunar]);
 | 
					    }, [view, date, showLunar]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div className="ant-btn-group" style={{ fontSize: '1.75em', fontWeight: 300 }}>
 | 
					      <div className="ant-btn-group" style={{ fontSize: '1.75em', fontWeight: 300 }}>
 | 
				
			||||||
      <span>{label}</span>
 | 
					        <span>{label}</span>
 | 
				
			||||||
      <span style={{ marginLeft: '4px' }}>{lunarElement}</span>
 | 
					        <span style={{ marginLeft: '4px' }}>{lunarElement}</span>
 | 
				
			||||||
      <DesignableBar />
 | 
					        <DesignableBar />
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Title' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,18 +6,21 @@ import { useTranslation } from 'react-i18next';
 | 
				
			|||||||
import { useDesignable } from '../../hooks';
 | 
					import { useDesignable } from '../../hooks';
 | 
				
			||||||
import { CalendarToolbarContext } from './context';
 | 
					import { CalendarToolbarContext } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Today = observer((props) => {
 | 
					export const Today = observer(
 | 
				
			||||||
  const { DesignableBar } = useDesignable();
 | 
					  (props) => {
 | 
				
			||||||
  const { onNavigate } = useContext(CalendarToolbarContext);
 | 
					    const { DesignableBar } = useDesignable();
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const { onNavigate } = useContext(CalendarToolbarContext);
 | 
				
			||||||
  return (
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
    <Button
 | 
					    return (
 | 
				
			||||||
      onClick={() => {
 | 
					      <Button
 | 
				
			||||||
        onNavigate(navigate.TODAY);
 | 
					        onClick={() => {
 | 
				
			||||||
      }}
 | 
					          onNavigate(navigate.TODAY);
 | 
				
			||||||
    >
 | 
					        }}
 | 
				
			||||||
      {t('Today')}
 | 
					      >
 | 
				
			||||||
      <DesignableBar />
 | 
					        {t('Today')}
 | 
				
			||||||
    </Button>
 | 
					        <DesignableBar />
 | 
				
			||||||
  );
 | 
					      </Button>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Today' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,22 +4,25 @@ import React, { useContext } from 'react';
 | 
				
			|||||||
import { useDesignable } from '../../hooks';
 | 
					import { useDesignable } from '../../hooks';
 | 
				
			||||||
import { CalendarToolbarContext } from './context';
 | 
					import { CalendarToolbarContext } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ViewSelect = observer((props) => {
 | 
					export const ViewSelect = observer(
 | 
				
			||||||
  const { DesignableBar } = useDesignable();
 | 
					  (props) => {
 | 
				
			||||||
  const {
 | 
					    const { DesignableBar } = useDesignable();
 | 
				
			||||||
    views,
 | 
					    const {
 | 
				
			||||||
    view,
 | 
					      views,
 | 
				
			||||||
    onView,
 | 
					      view,
 | 
				
			||||||
    localizer: { messages },
 | 
					      onView,
 | 
				
			||||||
  } = useContext(CalendarToolbarContext);
 | 
					      localizer: { messages },
 | 
				
			||||||
  return (
 | 
					    } = useContext(CalendarToolbarContext);
 | 
				
			||||||
    <div className="ant-btn-group">
 | 
					    return (
 | 
				
			||||||
      <Select value={view} onChange={onView}>
 | 
					      <div className="ant-btn-group">
 | 
				
			||||||
        {views.map((name) => (
 | 
					        <Select value={view} onChange={onView}>
 | 
				
			||||||
          <Select.Option value={name}>{messages[name]}</Select.Option>
 | 
					          {views.map((name) => (
 | 
				
			||||||
        ))}
 | 
					            <Select.Option value={name}>{messages[name]}</Select.Option>
 | 
				
			||||||
      </Select>
 | 
					          ))}
 | 
				
			||||||
      <DesignableBar />
 | 
					        </Select>
 | 
				
			||||||
    </div>
 | 
					        <DesignableBar />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ViewSelect' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -58,6 +58,6 @@ export const CollectionSelect = connect(
 | 
				
			|||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }),
 | 
					    }, { displayName: 'CollectionSelectObserver' }),
 | 
				
			||||||
  ),
 | 
					  ),
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -15,35 +15,38 @@ const useDef = (options) => {
 | 
				
			|||||||
  return useRequest(() => Promise.resolve({ data: field.dataSource }), options);
 | 
					  return useRequest(() => Promise.resolve({ data: field.dataSource }), options);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Filter: any = observer((props: any) => {
 | 
					export const Filter: any = observer(
 | 
				
			||||||
  const { useDataSource = useDef } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { options, dynamicComponent, className } = useProps(props);
 | 
					    const { useDataSource = useDef } = props;
 | 
				
			||||||
  const field = useField<ObjectFieldModel>();
 | 
					    const { options, dynamicComponent, className } = useProps(props);
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField<ObjectFieldModel>();
 | 
				
			||||||
  useDataSource({
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
    onSuccess(data) {
 | 
					    useDataSource({
 | 
				
			||||||
      field.dataSource = data?.data || [];
 | 
					      onSuccess(data) {
 | 
				
			||||||
    },
 | 
					        field.dataSource = data?.data || [];
 | 
				
			||||||
  });
 | 
					      },
 | 
				
			||||||
  return (
 | 
					    });
 | 
				
			||||||
    <div className={className}>
 | 
					    return (
 | 
				
			||||||
      <DatePickerProvider value={{ utc: false }}>
 | 
					      <div className={className}>
 | 
				
			||||||
        <FilterContext.Provider
 | 
					        <DatePickerProvider value={{ utc: false }}>
 | 
				
			||||||
          value={{
 | 
					          <FilterContext.Provider
 | 
				
			||||||
            field,
 | 
					            value={{
 | 
				
			||||||
            fieldSchema,
 | 
					              field,
 | 
				
			||||||
            dynamicComponent,
 | 
					              fieldSchema,
 | 
				
			||||||
            options: options || field.dataSource || [],
 | 
					              dynamicComponent,
 | 
				
			||||||
            disabled: props.disabled,
 | 
					              options: options || field.dataSource || [],
 | 
				
			||||||
          }}
 | 
					              disabled: props.disabled,
 | 
				
			||||||
        >
 | 
					            }}
 | 
				
			||||||
          <FilterGroup {...props} bordered={false} />
 | 
					          >
 | 
				
			||||||
          {/* <pre>{JSON.stringify(field.value, null, 2)}</pre> */}
 | 
					            <FilterGroup {...props} bordered={false} />
 | 
				
			||||||
        </FilterContext.Provider>
 | 
					            {/* <pre>{JSON.stringify(field.value, null, 2)}</pre> */}
 | 
				
			||||||
      </DatePickerProvider>
 | 
					          </FilterContext.Provider>
 | 
				
			||||||
    </div>
 | 
					        </DatePickerProvider>
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Filter' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Filter.SaveDefaultValue = SaveDefaultValue;
 | 
					Filter.SaveDefaultValue = SaveDefaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,83 +11,86 @@ import { Action } from '../action';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const FilterActionContext = createContext<any>(null);
 | 
					export const FilterActionContext = createContext<any>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FilterAction = observer((props: any) => {
 | 
					export const FilterAction = observer(
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const { designable, dn } = useDesignable();
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { designable, dn } = useDesignable();
 | 
				
			||||||
  const form = useMemo<Form>(() => props.form || createForm(), []);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { options, onSubmit, onReset, ...others } = useProps(props);
 | 
					    const form = useMemo<Form>(() => props.form || createForm(), []);
 | 
				
			||||||
  return (
 | 
					    const { options, onSubmit, onReset, ...others } = useProps(props);
 | 
				
			||||||
    <FilterActionContext.Provider value={{ field, fieldSchema, designable, dn }}>
 | 
					    return (
 | 
				
			||||||
      <Popover
 | 
					      <FilterActionContext.Provider value={{ field, fieldSchema, designable, dn }}>
 | 
				
			||||||
        destroyTooltipOnHide
 | 
					        <Popover
 | 
				
			||||||
        placement={'bottomLeft'}
 | 
					          destroyTooltipOnHide
 | 
				
			||||||
        open={visible}
 | 
					          placement={'bottomLeft'}
 | 
				
			||||||
        onOpenChange={(visible) => {
 | 
					          open={visible}
 | 
				
			||||||
          setVisible(visible);
 | 
					          onOpenChange={(visible) => {
 | 
				
			||||||
        }}
 | 
					            setVisible(visible);
 | 
				
			||||||
        trigger={'click'}
 | 
					          }}
 | 
				
			||||||
        content={
 | 
					          trigger={'click'}
 | 
				
			||||||
          <form>
 | 
					          content={
 | 
				
			||||||
            <FormProvider form={form}>
 | 
					            <form>
 | 
				
			||||||
              <SchemaComponent
 | 
					              <FormProvider form={form}>
 | 
				
			||||||
                schema={{
 | 
					                <SchemaComponent
 | 
				
			||||||
                  type: 'object',
 | 
					                  schema={{
 | 
				
			||||||
                  properties: {
 | 
					                    type: 'object',
 | 
				
			||||||
                    filter: {
 | 
					                    properties: {
 | 
				
			||||||
                      type: 'string',
 | 
					                      filter: {
 | 
				
			||||||
                      enum: options || field.dataSource,
 | 
					                        type: 'string',
 | 
				
			||||||
                      default: fieldSchema.default,
 | 
					                        enum: options || field.dataSource,
 | 
				
			||||||
                      'x-component': 'Filter',
 | 
					                        default: fieldSchema.default,
 | 
				
			||||||
                      'x-component-props': {},
 | 
					                        'x-component': 'Filter',
 | 
				
			||||||
 | 
					                        'x-component-props': {},
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                  },
 | 
					                  }}
 | 
				
			||||||
                }}
 | 
					                />
 | 
				
			||||||
              />
 | 
					                <div
 | 
				
			||||||
              <div
 | 
					                  className={css`
 | 
				
			||||||
                className={css`
 | 
					                    display: flex;
 | 
				
			||||||
                  display: flex;
 | 
					                    justify-content: flex-end;
 | 
				
			||||||
                  justify-content: flex-end;
 | 
					                    width: 100%;
 | 
				
			||||||
                  width: 100%;
 | 
					                  `}
 | 
				
			||||||
                `}
 | 
					                >
 | 
				
			||||||
              >
 | 
					                  <Space>
 | 
				
			||||||
                <Space>
 | 
					                    <SaveConditions />
 | 
				
			||||||
                  <SaveConditions />
 | 
					                    <Button
 | 
				
			||||||
                  <Button
 | 
					                      onClick={async () => {
 | 
				
			||||||
                    onClick={async () => {
 | 
					                        await form.reset();
 | 
				
			||||||
                      await form.reset();
 | 
					                        onReset?.(form.values);
 | 
				
			||||||
                      onReset?.(form.values);
 | 
					                        field.title = t('Filter');
 | 
				
			||||||
                      field.title = t('Filter');
 | 
					                        setVisible(false);
 | 
				
			||||||
                      setVisible(false);
 | 
					                      }}
 | 
				
			||||||
                    }}
 | 
					                    >
 | 
				
			||||||
                  >
 | 
					                      {t('Reset')}
 | 
				
			||||||
                    {t('Reset')}
 | 
					                    </Button>
 | 
				
			||||||
                  </Button>
 | 
					                    <Button
 | 
				
			||||||
                  <Button
 | 
					                      type={'primary'}
 | 
				
			||||||
                    type={'primary'}
 | 
					                      htmlType={'submit'}
 | 
				
			||||||
                    htmlType={'submit'}
 | 
					                      onClick={(e) => {
 | 
				
			||||||
                    onClick={(e) => {
 | 
					                        e.preventDefault();
 | 
				
			||||||
                      e.preventDefault();
 | 
					                        e.stopPropagation();
 | 
				
			||||||
                      e.stopPropagation();
 | 
					                        onSubmit?.(form.values);
 | 
				
			||||||
                      onSubmit?.(form.values);
 | 
					                        setVisible(false);
 | 
				
			||||||
                      setVisible(false);
 | 
					                      }}
 | 
				
			||||||
                    }}
 | 
					                    >
 | 
				
			||||||
                  >
 | 
					                      {t('Submit')}
 | 
				
			||||||
                    {t('Submit')}
 | 
					                    </Button>
 | 
				
			||||||
                  </Button>
 | 
					                  </Space>
 | 
				
			||||||
                </Space>
 | 
					                </div>
 | 
				
			||||||
              </div>
 | 
					              </FormProvider>
 | 
				
			||||||
            </FormProvider>
 | 
					            </form>
 | 
				
			||||||
          </form>
 | 
					          }
 | 
				
			||||||
        }
 | 
					        >
 | 
				
			||||||
      >
 | 
					          <Action {...others} title={field.title} />
 | 
				
			||||||
        <Action {...others} title={field.title} />
 | 
					        </Popover>
 | 
				
			||||||
      </Popover>
 | 
					      </FilterActionContext.Provider>
 | 
				
			||||||
    </FilterActionContext.Provider>
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'FilterAction' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SaveConditions = () => {
 | 
					const SaveConditions = () => {
 | 
				
			||||||
  const { fieldSchema, field, designable, dn } = useContext(FilterActionContext);
 | 
					  const { fieldSchema, field, designable, dn } = useContext(FilterActionContext);
 | 
				
			||||||
 | 
				
			|||||||
@ -9,56 +9,59 @@ import { RemoveConditionContext } from './context';
 | 
				
			|||||||
import { DynamicComponent } from './DynamicComponent';
 | 
					import { DynamicComponent } from './DynamicComponent';
 | 
				
			||||||
import { useValues } from './useValues';
 | 
					import { useValues } from './useValues';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FilterItem = observer((props: any) => {
 | 
					export const FilterItem = observer(
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					  (props: any) => {
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  const remove = useContext(RemoveConditionContext);
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const { schema, fields, operators, dataIndex, operator, setDataIndex, setOperator, value, setValue } = useValues();
 | 
					    const remove = useContext(RemoveConditionContext);
 | 
				
			||||||
  return (
 | 
					    const { schema, fields, operators, dataIndex, operator, setDataIndex, setOperator, value, setValue } = useValues();
 | 
				
			||||||
    <div style={{ marginBottom: 8 }}>
 | 
					    return (
 | 
				
			||||||
      <Space>
 | 
					      <div style={{ marginBottom: 8 }}>
 | 
				
			||||||
        <Cascader
 | 
					        <Space>
 | 
				
			||||||
          className={css`
 | 
					          <Cascader
 | 
				
			||||||
            width: 160px;
 | 
					            className={css`
 | 
				
			||||||
          `}
 | 
					              width: 160px;
 | 
				
			||||||
          fieldNames={{
 | 
					            `}
 | 
				
			||||||
            label: 'title',
 | 
					            fieldNames={{
 | 
				
			||||||
            value: 'name',
 | 
					              label: 'title',
 | 
				
			||||||
            children: 'children',
 | 
					              value: 'name',
 | 
				
			||||||
          }}
 | 
					              children: 'children',
 | 
				
			||||||
          changeOnSelect={false}
 | 
					            }}
 | 
				
			||||||
          value={dataIndex}
 | 
					            changeOnSelect={false}
 | 
				
			||||||
          options={compile(fields)}
 | 
					            value={dataIndex}
 | 
				
			||||||
          onChange={(value) => {
 | 
					            options={compile(fields)}
 | 
				
			||||||
            setDataIndex(value);
 | 
					            onChange={(value) => {
 | 
				
			||||||
          }}
 | 
					              setDataIndex(value);
 | 
				
			||||||
          placeholder={t('Select Field')}
 | 
					            }}
 | 
				
			||||||
        />
 | 
					            placeholder={t('Select Field')}
 | 
				
			||||||
        <Select
 | 
					          />
 | 
				
			||||||
          className={css`
 | 
					          <Select
 | 
				
			||||||
            min-width: 110px;
 | 
					            className={css`
 | 
				
			||||||
          `}
 | 
					              min-width: 110px;
 | 
				
			||||||
          value={operator?.value}
 | 
					            `}
 | 
				
			||||||
          options={compile(operators)}
 | 
					            value={operator?.value}
 | 
				
			||||||
          onChange={(value) => {
 | 
					            options={compile(operators)}
 | 
				
			||||||
            setOperator(value);
 | 
					            onChange={(value) => {
 | 
				
			||||||
          }}
 | 
					              setOperator(value);
 | 
				
			||||||
          placeholder={t('Comparision')}
 | 
					            }}
 | 
				
			||||||
        />
 | 
					            placeholder={t('Comparision')}
 | 
				
			||||||
        {!operator?.noValue &&
 | 
					          />
 | 
				
			||||||
          React.createElement(DynamicComponent, {
 | 
					          {!operator?.noValue &&
 | 
				
			||||||
            value: value ? value : undefined,
 | 
					            React.createElement(DynamicComponent, {
 | 
				
			||||||
            schema,
 | 
					              value: value ? value : undefined,
 | 
				
			||||||
            onChange(value) {
 | 
					              schema,
 | 
				
			||||||
              setValue(value);
 | 
					              onChange(value) {
 | 
				
			||||||
            },
 | 
					                setValue(value);
 | 
				
			||||||
          })}
 | 
					              },
 | 
				
			||||||
        {!props.disabled && (
 | 
					            })}
 | 
				
			||||||
          <a>
 | 
					          {!props.disabled && (
 | 
				
			||||||
            <CloseCircleOutlined onClick={() => remove()} style={{ color: '#bfbfbf' }} />
 | 
					            <a>
 | 
				
			||||||
          </a>
 | 
					              <CloseCircleOutlined onClick={() => remove()} style={{ color: '#bfbfbf' }} />
 | 
				
			||||||
        )}
 | 
					            </a>
 | 
				
			||||||
      </Space>
 | 
					          )}
 | 
				
			||||||
    </div>
 | 
					        </Space>
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'FilterItem' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -5,17 +5,20 @@ import { RemoveConditionContext } from './context';
 | 
				
			|||||||
import { FilterGroup } from './FilterGroup';
 | 
					import { FilterGroup } from './FilterGroup';
 | 
				
			||||||
import { FilterItem } from './FilterItem';
 | 
					import { FilterItem } from './FilterItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FilterItems = observer((props) => {
 | 
					export const FilterItems = observer(
 | 
				
			||||||
  const field = useField<ArrayFieldModel>();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const field = useField<ArrayFieldModel>();
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      {field?.value?.map((item, index) => {
 | 
					      <div>
 | 
				
			||||||
        return (
 | 
					        {field?.value?.map((item, index) => {
 | 
				
			||||||
          <RemoveConditionContext.Provider key={index} value={() => field.remove(index)}>
 | 
					          return (
 | 
				
			||||||
            <ObjectField name={index} component={[item.$and || item.$or ? FilterGroup : FilterItem]} />
 | 
					            <RemoveConditionContext.Provider key={index} value={() => field.remove(index)}>
 | 
				
			||||||
          </RemoveConditionContext.Provider>
 | 
					              <ObjectField name={index} component={[item.$and || item.$or ? FilterGroup : FilterItem]} />
 | 
				
			||||||
        );
 | 
					            </RemoveConditionContext.Provider>
 | 
				
			||||||
      })}
 | 
					          );
 | 
				
			||||||
    </div>
 | 
					        })}
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'FilterItems' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -53,61 +53,64 @@ const divWrap = (schema: ISchema) => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FormItem: any = observer((props: any) => {
 | 
					export const FormItem: any = observer(
 | 
				
			||||||
  useEnsureOperatorsValid();
 | 
					  (props: any) => {
 | 
				
			||||||
 | 
					    useEnsureOperatorsValid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const ctx = useContext(BlockRequestContext);
 | 
					    const ctx = useContext(BlockRequestContext);
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const variablesCtx = useVariablesCtx();
 | 
					    const variablesCtx = useVariablesCtx();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
    if (ctx?.block === 'form') {
 | 
					      if (ctx?.block === 'form') {
 | 
				
			||||||
      ctx.field.data = ctx.field.data || {};
 | 
					        ctx.field.data = ctx.field.data || {};
 | 
				
			||||||
      ctx.field.data.activeFields = ctx.field.data.activeFields || new Set();
 | 
					        ctx.field.data.activeFields = ctx.field.data.activeFields || new Set();
 | 
				
			||||||
      ctx.field.data.activeFields.add(schema.name);
 | 
					        ctx.field.data.activeFields.add(schema.name);
 | 
				
			||||||
      // 如果默认值是一个变量,则需要解析之后再显示出来
 | 
					        // 如果默认值是一个变量,则需要解析之后再显示出来
 | 
				
			||||||
      if (isVariable(schema?.default)) {
 | 
					        if (isVariable(schema?.default)) {
 | 
				
			||||||
        field.setInitialValue?.(parseVariables(schema.default, variablesCtx));
 | 
					          field.setInitialValue?.(parseVariables(schema.default, variablesCtx));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }, []);
 | 
				
			||||||
  }, []);
 | 
					    const showTitle = schema['x-decorator-props']?.showTitle ?? true;
 | 
				
			||||||
  const showTitle = schema['x-decorator-props']?.showTitle ?? true;
 | 
					    return (
 | 
				
			||||||
  return (
 | 
					      <ACLCollectionFieldProvider>
 | 
				
			||||||
    <ACLCollectionFieldProvider>
 | 
					        <BlockItem className={'nb-form-item'}>
 | 
				
			||||||
      <BlockItem className={'nb-form-item'}>
 | 
					          <Item
 | 
				
			||||||
        <Item
 | 
					            className={cx(
 | 
				
			||||||
          className={cx(
 | 
					              css`
 | 
				
			||||||
            css`
 | 
					                & .ant-space {
 | 
				
			||||||
              & .ant-space {
 | 
					                  flex-wrap: wrap;
 | 
				
			||||||
                flex-wrap: wrap;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            `,
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              [css`
 | 
					 | 
				
			||||||
                > .ant-formily-item-label {
 | 
					 | 
				
			||||||
                  display: none;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              `]: showTitle === false,
 | 
					              `,
 | 
				
			||||||
            },
 | 
					              {
 | 
				
			||||||
          )}
 | 
					                [css`
 | 
				
			||||||
          {...props}
 | 
					                  > .ant-formily-item-label {
 | 
				
			||||||
          extra={
 | 
					                    display: none;
 | 
				
			||||||
            typeof field.description === 'string' ? (
 | 
					                  }
 | 
				
			||||||
              <div
 | 
					                `]: showTitle === false,
 | 
				
			||||||
                dangerouslySetInnerHTML={{
 | 
					              },
 | 
				
			||||||
                  __html: HTMLEncode(field.description).split('\n').join('<br/>'),
 | 
					            )}
 | 
				
			||||||
                }}
 | 
					            {...props}
 | 
				
			||||||
              />
 | 
					            extra={
 | 
				
			||||||
            ) : (
 | 
					              typeof field.description === 'string' ? (
 | 
				
			||||||
              field.description
 | 
					                <div
 | 
				
			||||||
            )
 | 
					                  dangerouslySetInnerHTML={{
 | 
				
			||||||
          }
 | 
					                    __html: HTMLEncode(field.description).split('\n').join('<br/>'),
 | 
				
			||||||
        />
 | 
					                  }}
 | 
				
			||||||
      </BlockItem>
 | 
					                />
 | 
				
			||||||
    </ACLCollectionFieldProvider>
 | 
					              ) : (
 | 
				
			||||||
  );
 | 
					                field.description
 | 
				
			||||||
});
 | 
					              )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </BlockItem>
 | 
				
			||||||
 | 
					      </ACLCollectionFieldProvider>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'FormItem' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FormItem.Designer = function Designer() {
 | 
					FormItem.Designer = function Designer() {
 | 
				
			||||||
  const { getCollectionFields, getInterface, getCollectionJoinField, getCollection } = useCollectionManager();
 | 
					  const { getCollectionFields, getInterface, getCollectionJoinField, getCollection } = useCollectionManager();
 | 
				
			||||||
 | 
				
			|||||||
@ -170,21 +170,24 @@ export const Form: React.FC<FormProps> & {
 | 
				
			|||||||
  FilterDesigner?: any;
 | 
					  FilterDesigner?: any;
 | 
				
			||||||
  ReadPrettyDesigner?: any;
 | 
					  ReadPrettyDesigner?: any;
 | 
				
			||||||
  Templates?: any;
 | 
					  Templates?: any;
 | 
				
			||||||
} = observer((props) => {
 | 
					} = observer(
 | 
				
			||||||
  const field = useField<Field>();
 | 
					  (props) => {
 | 
				
			||||||
  const { form, disabled, ...others } = useProps(props);
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const formDisabled = disabled || field.disabled;
 | 
					    const { form, disabled, ...others } = useProps(props);
 | 
				
			||||||
  return (
 | 
					    const formDisabled = disabled || field.disabled;
 | 
				
			||||||
    <ConfigProvider componentDisabled={formDisabled}>
 | 
					    return (
 | 
				
			||||||
      <form>
 | 
					      <ConfigProvider componentDisabled={formDisabled}>
 | 
				
			||||||
        <Spin spinning={field.loading || false}>
 | 
					        <form>
 | 
				
			||||||
          {form ? (
 | 
					          <Spin spinning={field.loading || false}>
 | 
				
			||||||
            <WithForm form={form} {...others} disabled={formDisabled} />
 | 
					            {form ? (
 | 
				
			||||||
          ) : (
 | 
					              <WithForm form={form} {...others} disabled={formDisabled} />
 | 
				
			||||||
            <WithoutForm {...others} disabled={formDisabled} />
 | 
					            ) : (
 | 
				
			||||||
          )}
 | 
					              <WithoutForm {...others} disabled={formDisabled} />
 | 
				
			||||||
        </Spin>
 | 
					            )}
 | 
				
			||||||
      </form>
 | 
					          </Spin>
 | 
				
			||||||
    </ConfigProvider>
 | 
					        </form>
 | 
				
			||||||
  );
 | 
					      </ConfigProvider>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Form' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,21 +4,24 @@ import { useFormBlockContext } from '../../../block-provider';
 | 
				
			|||||||
import { useCollection } from '../../../collection-manager';
 | 
					import { useCollection } from '../../../collection-manager';
 | 
				
			||||||
import { useCompile } from '../../hooks';
 | 
					import { useCompile } from '../../hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const FormField: any = observer((props) => {
 | 
					export const FormField: any = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  const { getField } = useCollection();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const field = useField();
 | 
					    const { getField } = useCollection();
 | 
				
			||||||
  const collectionField = getField(fieldSchema.name);
 | 
					    const field = useField();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const collectionField = getField(fieldSchema.name);
 | 
				
			||||||
  const ctx = useFormBlockContext();
 | 
					    const compile = useCompile();
 | 
				
			||||||
  useEffect(() => {
 | 
					    const ctx = useFormBlockContext();
 | 
				
			||||||
    if (!field.title) {
 | 
					    useEffect(() => {
 | 
				
			||||||
      field.title = compile(collectionField?.uiSchema?.title);
 | 
					      if (!field.title) {
 | 
				
			||||||
    }
 | 
					        field.title = compile(collectionField?.uiSchema?.title);
 | 
				
			||||||
    if (ctx?.field) {
 | 
					      }
 | 
				
			||||||
      ctx.field.added = ctx.field.added || new Set();
 | 
					      if (ctx?.field) {
 | 
				
			||||||
      ctx.field.added.add(fieldSchema.name);
 | 
					        ctx.field.added = ctx.field.added || new Set();
 | 
				
			||||||
    }
 | 
					        ctx.field.added.add(fieldSchema.name);
 | 
				
			||||||
  }, []);
 | 
					      }
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					    }, []);
 | 
				
			||||||
});
 | 
					    return <div>{props.children}</div>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'FormField' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -83,34 +83,37 @@ const useDefaultValues = (opts: any = {}, props: FormProps = {}) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const FormBlockContext = createContext<any>(null);
 | 
					const FormBlockContext = createContext<any>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Form: React.FC<FormProps> & { Designer?: any } = observer((props) => {
 | 
					export const Form: React.FC<FormProps> & { Designer?: any } = observer(
 | 
				
			||||||
  const { request, effects, initialValue, useValues = useDefaultValues, ...others } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { request, effects, initialValue, useValues = useDefaultValues, ...others } = props;
 | 
				
			||||||
  const field = useField();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const form = useMemo(() => createForm({ effects }), []);
 | 
					    const field = useField();
 | 
				
			||||||
  const result = useValues(
 | 
					    const form = useMemo(() => createForm({ effects }), []);
 | 
				
			||||||
    {
 | 
					    const result = useValues(
 | 
				
			||||||
      uid: fieldSchema['x-uid'],
 | 
					      {
 | 
				
			||||||
      async onSuccess(data) {
 | 
					        uid: fieldSchema['x-uid'],
 | 
				
			||||||
        await form.reset();
 | 
					        async onSuccess(data) {
 | 
				
			||||||
        form.setValues(data?.data);
 | 
					          await form.reset();
 | 
				
			||||||
 | 
					          form.setValues(data?.data);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      props,
 | 
				
			||||||
    props,
 | 
					    );
 | 
				
			||||||
  );
 | 
					    const parent = useContext(FormBlockContext);
 | 
				
			||||||
  const parent = useContext(FormBlockContext);
 | 
					    return (
 | 
				
			||||||
  return (
 | 
					      <FormBlockContext.Provider value={{ parent, form, result, field, fieldSchema }}>
 | 
				
			||||||
    <FormBlockContext.Provider value={{ parent, form, result, field, fieldSchema }}>
 | 
					        <Spin spinning={result?.loading || false}>
 | 
				
			||||||
      <Spin spinning={result?.loading || false}>
 | 
					          {fieldSchema['x-decorator'] === 'Form' ? (
 | 
				
			||||||
        {fieldSchema['x-decorator'] === 'Form' ? (
 | 
					            <FormDecorator form={form} {...others} />
 | 
				
			||||||
          <FormDecorator form={form} {...others} />
 | 
					          ) : (
 | 
				
			||||||
        ) : (
 | 
					            <FormComponent form={form} {...others} />
 | 
				
			||||||
          <FormComponent form={form} {...others} />
 | 
					          )}
 | 
				
			||||||
        )}
 | 
					        </Spin>
 | 
				
			||||||
      </Spin>
 | 
					      </FormBlockContext.Provider>
 | 
				
			||||||
    </FormBlockContext.Provider>
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'Form' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Form.Designer = () => {
 | 
					Form.Designer = () => {
 | 
				
			||||||
  const { name, title } = useCollection();
 | 
					  const { name, title } = useCollection();
 | 
				
			||||||
 | 
				
			|||||||
@ -49,10 +49,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SchemaComponentProvider scope={{ useCloseAction }} components={{ Output, Form, Action, Input, FormItem }}>
 | 
					    <SchemaComponentProvider scope={{ useCloseAction }} components={{ Output, Form, Action, Input, FormItem }}>
 | 
				
			||||||
 | 
				
			|||||||
@ -38,10 +38,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const useSubmit = () => {
 | 
					  const useSubmit = () => {
 | 
				
			||||||
    const form = useForm();
 | 
					    const form = useForm();
 | 
				
			||||||
 | 
				
			|||||||
@ -38,10 +38,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const useSubmit = () => {
 | 
					  const useSubmit = () => {
 | 
				
			||||||
    const form = useForm();
 | 
					    const form = useForm();
 | 
				
			||||||
 | 
				
			|||||||
@ -54,10 +54,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <SchemaComponentProvider scope={{ useCloseAction }} components={{ Output, Form, Action, Input, FormItem }}>
 | 
					    <SchemaComponentProvider scope={{ useCloseAction }} components={{ Output, Form, Action, Input, FormItem }}>
 | 
				
			||||||
 | 
				
			|||||||
@ -69,10 +69,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const useSubmit = () => {
 | 
					  const useSubmit = () => {
 | 
				
			||||||
    const form = useForm();
 | 
					    const form = useForm();
 | 
				
			||||||
 | 
				
			|||||||
@ -39,10 +39,13 @@ export default observer(() => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const Output = observer(() => {
 | 
					  const Output = observer(
 | 
				
			||||||
    const form = useForm();
 | 
					    () => {
 | 
				
			||||||
    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					      const form = useForm();
 | 
				
			||||||
  });
 | 
					      return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { displayName: 'Output' },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const useSubmit = () => {
 | 
					  const useSubmit = () => {
 | 
				
			||||||
    const form = useForm();
 | 
					    const form = useForm();
 | 
				
			||||||
 | 
				
			|||||||
@ -36,10 +36,13 @@ const schema: ISchema = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Output = observer(() => {
 | 
					const Output = observer(
 | 
				
			||||||
  const form = useForm();
 | 
					  () => {
 | 
				
			||||||
  return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
					    const form = useForm();
 | 
				
			||||||
});
 | 
					    return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Output' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const useSubmit = () => {
 | 
					const useSubmit = () => {
 | 
				
			||||||
  const form = useForm();
 | 
					  const form = useForm();
 | 
				
			||||||
 | 
				
			|||||||
@ -127,51 +127,54 @@ export const G2PlotRenderer = forwardRef(function <O = any>(props: ReactG2PlotPr
 | 
				
			|||||||
  return <div className={cls(['g2plot', className])} ref={containerRef} />;
 | 
					  return <div className={cls(['g2plot', className])} ref={containerRef} />;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const G2Plot: any = observer((props: any) => {
 | 
					export const G2Plot: any = observer(
 | 
				
			||||||
  const { plot, config } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { plot, config } = props;
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const api = useAPIClient();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  useEffect(() => {
 | 
					    const api = useAPIClient();
 | 
				
			||||||
    field.data = field.data || {};
 | 
					    useEffect(() => {
 | 
				
			||||||
    field.data.loading = true;
 | 
					      field.data = field.data || {};
 | 
				
			||||||
    const fn = config?.data;
 | 
					      field.data.loading = true;
 | 
				
			||||||
    if (typeof fn === 'function') {
 | 
					      const fn = config?.data;
 | 
				
			||||||
      const result = fn.bind({ api })();
 | 
					      if (typeof fn === 'function') {
 | 
				
			||||||
      if (result?.then) {
 | 
					        const result = fn.bind({ api })();
 | 
				
			||||||
        result.then((data) => {
 | 
					        if (result?.then) {
 | 
				
			||||||
          if (Array.isArray(data)) {
 | 
					          result.then((data) => {
 | 
				
			||||||
            field.componentProps.config.data = data;
 | 
					            if (Array.isArray(data)) {
 | 
				
			||||||
          }
 | 
					              field.componentProps.config.data = data;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            field.data.loading = false;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
          field.data.loading = false;
 | 
					          field.data.loading = false;
 | 
				
			||||||
        });
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        field.data.loading = false;
 | 
					        field.data.loading = false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    }, []);
 | 
				
			||||||
      field.data.loading = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }, []);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!plot || !config) {
 | 
					    if (!plot || !config) {
 | 
				
			||||||
    return <div style={{ opacity: 0.3 }}>{t('In configuration')}...</div>;
 | 
					      return <div style={{ opacity: 0.3 }}>{t('In configuration')}...</div>;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
  if (field?.data?.loading !== false) {
 | 
					    if (field?.data?.loading !== false) {
 | 
				
			||||||
    return <Spin />;
 | 
					      return <Spin />;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div>
 | 
					      <div>
 | 
				
			||||||
      {field.title && <h2>{field.title}</h2>}
 | 
					        {field.title && <h2>{field.title}</h2>}
 | 
				
			||||||
      <G2PlotRenderer
 | 
					        <G2PlotRenderer
 | 
				
			||||||
        plot={plots[plot]}
 | 
					          plot={plots[plot]}
 | 
				
			||||||
        config={{
 | 
					          config={{
 | 
				
			||||||
          ...config,
 | 
					            ...config,
 | 
				
			||||||
          data: Array.isArray(config?.data) ? config.data : [],
 | 
					            data: Array.isArray(config?.data) ? config.data : [],
 | 
				
			||||||
        }}
 | 
					          }}
 | 
				
			||||||
      />
 | 
					        />
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'G2Plot' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G2Plot.Designer = G2PlotDesigner;
 | 
					G2Plot.Designer = G2PlotDesigner;
 | 
				
			||||||
G2Plot.plots = plots;
 | 
					G2Plot.plots = plots;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
import { observer } from '@formily/react';
 | 
					import { observer } from '@formily/react';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Event = observer((props) => {
 | 
					export const Event = observer(
 | 
				
			||||||
  return <>{props.children}</>;
 | 
					  (props) => {
 | 
				
			||||||
});
 | 
					    return <>{props.children}</>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Event' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,12 +2,15 @@ import { observer, useFieldSchema } from '@formily/react';
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import { DragHandler } from '../../';
 | 
					import { DragHandler } from '../../';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Block = observer((props) => {
 | 
					export const Block = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
    <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
					    return (
 | 
				
			||||||
      Block {fieldSchema.title}
 | 
					      <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
				
			||||||
      <DragHandler />
 | 
					        Block {fieldSchema.title}
 | 
				
			||||||
    </div>
 | 
					        <DragHandler />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Block' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -330,45 +330,108 @@ export const useGridRowContext = () => {
 | 
				
			|||||||
  return useContext(GridRowContext);
 | 
					  return useContext(GridRowContext);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Grid: any = observer((props: any) => {
 | 
					export const Grid: any = observer(
 | 
				
			||||||
  const gridRef = useRef(null);
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField();
 | 
					    const gridRef = useRef(null);
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField();
 | 
				
			||||||
  const { render, InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const addr = field.address.toString();
 | 
					    const { render, InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
				
			||||||
  const rows = useRowProperties();
 | 
					    const addr = field.address.toString();
 | 
				
			||||||
  const { setPrintContent } = useFormBlockContext();
 | 
					    const rows = useRowProperties();
 | 
				
			||||||
 | 
					    const { setPrintContent } = useFormBlockContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
    gridRef.current && setPrintContent?.(gridRef.current);
 | 
					      gridRef.current && setPrintContent?.(gridRef.current);
 | 
				
			||||||
  }, [gridRef.current]);
 | 
					    }, [gridRef.current]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <GridContext.Provider value={{ ref: gridRef, fieldSchema, renderSchemaInitializer: render, InitializerComponent }}>
 | 
					      <GridContext.Provider
 | 
				
			||||||
      <div className={'nb-grid'} style={{ position: 'relative' }} ref={gridRef}>
 | 
					        value={{ ref: gridRef, fieldSchema, renderSchemaInitializer: render, InitializerComponent }}
 | 
				
			||||||
        <DndWrapper dndContext={props.dndContext}>
 | 
					      >
 | 
				
			||||||
          <RowDivider
 | 
					        <div className={'nb-grid'} style={{ position: 'relative' }} ref={gridRef}>
 | 
				
			||||||
            rows={rows}
 | 
					          <DndWrapper dndContext={props.dndContext}>
 | 
				
			||||||
 | 
					            <RowDivider
 | 
				
			||||||
 | 
					              rows={rows}
 | 
				
			||||||
 | 
					              first
 | 
				
			||||||
 | 
					              id={`${addr}_0`}
 | 
				
			||||||
 | 
					              data={{
 | 
				
			||||||
 | 
					                breakRemoveOn: breakRemoveOnGrid,
 | 
				
			||||||
 | 
					                wrapSchema: wrapRowSchema,
 | 
				
			||||||
 | 
					                insertAdjacent: 'afterBegin',
 | 
				
			||||||
 | 
					                schema: fieldSchema,
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					            {rows.map((schema, index) => {
 | 
				
			||||||
 | 
					              return (
 | 
				
			||||||
 | 
					                <React.Fragment key={index}>
 | 
				
			||||||
 | 
					                  <RecursionField name={schema.name} schema={schema} />
 | 
				
			||||||
 | 
					                  <RowDivider
 | 
				
			||||||
 | 
					                    rows={rows}
 | 
				
			||||||
 | 
					                    index={index}
 | 
				
			||||||
 | 
					                    id={`${addr}_${index + 1}`}
 | 
				
			||||||
 | 
					                    data={{
 | 
				
			||||||
 | 
					                      breakRemoveOn: breakRemoveOnGrid,
 | 
				
			||||||
 | 
					                      wrapSchema: wrapRowSchema,
 | 
				
			||||||
 | 
					                      insertAdjacent: 'afterEnd',
 | 
				
			||||||
 | 
					                      schema,
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                  />
 | 
				
			||||||
 | 
					                </React.Fragment>
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					            })}
 | 
				
			||||||
 | 
					          </DndWrapper>
 | 
				
			||||||
 | 
					          <InitializerComponent />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </GridContext.Provider>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Grid' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Grid.Row = observer(
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
 | 
					    const addr = field.address.toString();
 | 
				
			||||||
 | 
					    const cols = useColProperties();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <GridRowContext.Provider value={{ schema: fieldSchema, cols }}>
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          className={cls(
 | 
				
			||||||
 | 
					            'nb-grid-row',
 | 
				
			||||||
 | 
					            css`
 | 
				
			||||||
 | 
					              overflow-x: hidden;
 | 
				
			||||||
 | 
					              margin: 0 calc(-1 * var(--nb-spacing));
 | 
				
			||||||
 | 
					              display: flex;
 | 
				
			||||||
 | 
					              position: relative;
 | 
				
			||||||
 | 
					              /* z-index: 0; */
 | 
				
			||||||
 | 
					            `,
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <ColDivider
 | 
				
			||||||
 | 
					            cols={cols}
 | 
				
			||||||
            first
 | 
					            first
 | 
				
			||||||
            id={`${addr}_0`}
 | 
					            id={`${addr}_0`}
 | 
				
			||||||
            data={{
 | 
					            data={{
 | 
				
			||||||
              breakRemoveOn: breakRemoveOnGrid,
 | 
					              breakRemoveOn: breakRemoveOnRow,
 | 
				
			||||||
              wrapSchema: wrapRowSchema,
 | 
					              wrapSchema: wrapColSchema,
 | 
				
			||||||
              insertAdjacent: 'afterBegin',
 | 
					              insertAdjacent: 'afterBegin',
 | 
				
			||||||
              schema: fieldSchema,
 | 
					              schema: fieldSchema,
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
          {rows.map((schema, index) => {
 | 
					          {cols.map((schema, index) => {
 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
              <React.Fragment key={index}>
 | 
					              <React.Fragment key={index}>
 | 
				
			||||||
                <RecursionField name={schema.name} schema={schema} />
 | 
					                <RecursionField name={schema.name} schema={schema} />
 | 
				
			||||||
                <RowDivider
 | 
					                <ColDivider
 | 
				
			||||||
                  rows={rows}
 | 
					                  cols={cols}
 | 
				
			||||||
                  index={index}
 | 
					                  index={index}
 | 
				
			||||||
 | 
					                  last={index === cols.length - 1}
 | 
				
			||||||
                  id={`${addr}_${index + 1}`}
 | 
					                  id={`${addr}_${index + 1}`}
 | 
				
			||||||
                  data={{
 | 
					                  data={{
 | 
				
			||||||
                    breakRemoveOn: breakRemoveOnGrid,
 | 
					                    breakRemoveOn: breakRemoveOnRow,
 | 
				
			||||||
                    wrapSchema: wrapRowSchema,
 | 
					                    wrapSchema: wrapColSchema,
 | 
				
			||||||
                    insertAdjacent: 'afterEnd',
 | 
					                    insertAdjacent: 'afterEnd',
 | 
				
			||||||
                    schema,
 | 
					                    schema,
 | 
				
			||||||
                  }}
 | 
					                  }}
 | 
				
			||||||
@ -376,95 +439,43 @@ export const Grid: any = observer((props: any) => {
 | 
				
			|||||||
              </React.Fragment>
 | 
					              </React.Fragment>
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
          })}
 | 
					          })}
 | 
				
			||||||
        </DndWrapper>
 | 
					        </div>
 | 
				
			||||||
        <InitializerComponent />
 | 
					      </GridRowContext.Provider>
 | 
				
			||||||
      </div>
 | 
					    );
 | 
				
			||||||
    </GridContext.Provider>
 | 
					  },
 | 
				
			||||||
  );
 | 
					  { displayName: 'Grid.Row' },
 | 
				
			||||||
});
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Grid.Row = observer(() => {
 | 
					Grid.Col = observer(
 | 
				
			||||||
  const field = useField();
 | 
					  (props: any) => {
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { cols = [] } = useContext(GridRowContext);
 | 
				
			||||||
  const addr = field.address.toString();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const cols = useColProperties();
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    const width = useMemo(() => {
 | 
				
			||||||
    <GridRowContext.Provider value={{ schema: fieldSchema, cols }}>
 | 
					      let width = '';
 | 
				
			||||||
      <div
 | 
					      if (cols?.length) {
 | 
				
			||||||
        className={cls(
 | 
					        const w = schema?.['x-component-props']?.['width'] || 100 / cols.length;
 | 
				
			||||||
          'nb-grid-row',
 | 
					        width = `calc(${w}% - var(--nb-spacing) *  ${(cols.length + 1) / cols.length})`;
 | 
				
			||||||
          css`
 | 
					      }
 | 
				
			||||||
            overflow-x: hidden;
 | 
					      return width;
 | 
				
			||||||
            margin: 0 calc(-1 * var(--nb-spacing));
 | 
					    }, [cols?.length, schema?.['x-component-props']?.['width']]);
 | 
				
			||||||
            display: flex;
 | 
					 | 
				
			||||||
            position: relative;
 | 
					 | 
				
			||||||
            /* z-index: 0; */
 | 
					 | 
				
			||||||
          `,
 | 
					 | 
				
			||||||
        )}
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <ColDivider
 | 
					 | 
				
			||||||
          cols={cols}
 | 
					 | 
				
			||||||
          first
 | 
					 | 
				
			||||||
          id={`${addr}_0`}
 | 
					 | 
				
			||||||
          data={{
 | 
					 | 
				
			||||||
            breakRemoveOn: breakRemoveOnRow,
 | 
					 | 
				
			||||||
            wrapSchema: wrapColSchema,
 | 
					 | 
				
			||||||
            insertAdjacent: 'afterBegin',
 | 
					 | 
				
			||||||
            schema: fieldSchema,
 | 
					 | 
				
			||||||
          }}
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        {cols.map((schema, index) => {
 | 
					 | 
				
			||||||
          return (
 | 
					 | 
				
			||||||
            <React.Fragment key={index}>
 | 
					 | 
				
			||||||
              <RecursionField name={schema.name} schema={schema} />
 | 
					 | 
				
			||||||
              <ColDivider
 | 
					 | 
				
			||||||
                cols={cols}
 | 
					 | 
				
			||||||
                index={index}
 | 
					 | 
				
			||||||
                last={index === cols.length - 1}
 | 
					 | 
				
			||||||
                id={`${addr}_${index + 1}`}
 | 
					 | 
				
			||||||
                data={{
 | 
					 | 
				
			||||||
                  breakRemoveOn: breakRemoveOnRow,
 | 
					 | 
				
			||||||
                  wrapSchema: wrapColSchema,
 | 
					 | 
				
			||||||
                  insertAdjacent: 'afterEnd',
 | 
					 | 
				
			||||||
                  schema,
 | 
					 | 
				
			||||||
                }}
 | 
					 | 
				
			||||||
              />
 | 
					 | 
				
			||||||
            </React.Fragment>
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        })}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </GridRowContext.Provider>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Grid.Col = observer((props: any) => {
 | 
					    const { setNodeRef } = useDroppable({
 | 
				
			||||||
  const { cols = [] } = useContext(GridRowContext);
 | 
					      id: field.address.toString(),
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					      data: {
 | 
				
			||||||
  const field = useField();
 | 
					        insertAdjacent: 'beforeEnd',
 | 
				
			||||||
 | 
					        schema,
 | 
				
			||||||
  const width = useMemo(() => {
 | 
					        wrapSchema: (s) => s,
 | 
				
			||||||
    let width = '';
 | 
					      },
 | 
				
			||||||
    if (cols?.length) {
 | 
					    });
 | 
				
			||||||
      const w = schema?.['x-component-props']?.['width'] || 100 / cols.length;
 | 
					    return (
 | 
				
			||||||
      width = `calc(${w}% - var(--nb-spacing) *  ${(cols.length + 1) / cols.length})`;
 | 
					      <GridColContext.Provider value={{ cols, schema }}>
 | 
				
			||||||
    }
 | 
					        <div ref={setNodeRef} style={{ width }} className={cls('nb-grid-col')}>
 | 
				
			||||||
    return width;
 | 
					          {props.children}
 | 
				
			||||||
  }, [cols?.length, schema?.['x-component-props']?.['width']]);
 | 
					        </div>
 | 
				
			||||||
 | 
					      </GridColContext.Provider>
 | 
				
			||||||
  const { setNodeRef } = useDroppable({
 | 
					    );
 | 
				
			||||||
    id: field.address.toString(),
 | 
					  },
 | 
				
			||||||
    data: {
 | 
					  { displayName: 'Grid.Col' },
 | 
				
			||||||
      insertAdjacent: 'beforeEnd',
 | 
					);
 | 
				
			||||||
      schema,
 | 
					 | 
				
			||||||
      wrapSchema: (s) => s,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <GridColContext.Provider value={{ cols, schema }}>
 | 
					 | 
				
			||||||
      <div ref={setNodeRef} style={{ width }} className={cls('nb-grid-col')}>
 | 
					 | 
				
			||||||
        {props.children}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </GridColContext.Provider>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -2,15 +2,18 @@ import { observer, useFieldSchema } from '@formily/react';
 | 
				
			|||||||
import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
					import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Block = observer((props) => {
 | 
					const Block = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
    <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
					    return (
 | 
				
			||||||
      Block {fieldSchema.title}
 | 
					      <div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
 | 
				
			||||||
      <DragHandler />
 | 
					        Block {fieldSchema.title}
 | 
				
			||||||
    </div>
 | 
					        <DragHandler />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Block' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const schema = {
 | 
					const schema = {
 | 
				
			||||||
  _isJSONSchemaObject: true,
 | 
					  _isJSONSchemaObject: true,
 | 
				
			||||||
 | 
				
			|||||||
@ -10,98 +10,101 @@ import { RecordProvider } from '../../../record-provider';
 | 
				
			|||||||
import { SchemaComponentOptions } from '../../core/SchemaComponentOptions';
 | 
					import { SchemaComponentOptions } from '../../core/SchemaComponentOptions';
 | 
				
			||||||
import { KanbanCardContext } from './context';
 | 
					import { KanbanCardContext } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const KanbanCard: any = observer((props: any) => {
 | 
					export const KanbanCard: any = observer(
 | 
				
			||||||
  const { setDisableCardDrag, cardViewerSchema, card, cardField, columnIndex, cardIndex } =
 | 
					  (props: any) => {
 | 
				
			||||||
    useContext(KanbanCardContext);
 | 
					    const { setDisableCardDrag, cardViewerSchema, card, cardField, columnIndex, cardIndex } =
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					      useContext(KanbanCardContext);
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const labelDisabled = fieldSchema['x-label-disabled'];
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					    const labelDisabled = fieldSchema['x-label-disabled'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <SchemaComponentOptions components={{}} scope={{}}>
 | 
					      <SchemaComponentOptions components={{}} scope={{}}>
 | 
				
			||||||
      <Card
 | 
					        <Card
 | 
				
			||||||
        onClick={(e) => {
 | 
					          onClick={(e) => {
 | 
				
			||||||
          setVisible(true);
 | 
					            setVisible(true);
 | 
				
			||||||
        }}
 | 
					          }}
 | 
				
			||||||
        bordered={false}
 | 
					          bordered={false}
 | 
				
			||||||
        hoverable
 | 
					          hoverable
 | 
				
			||||||
        style={{ cursor: 'pointer', overflow: 'hidden' }}
 | 
					          style={{ cursor: 'pointer', overflow: 'hidden' }}
 | 
				
			||||||
        // bodyStyle={{ paddingBottom: 0 }}
 | 
					          // bodyStyle={{ paddingBottom: 0 }}
 | 
				
			||||||
        className={cls(
 | 
					          className={cls(
 | 
				
			||||||
          css`
 | 
					            css`
 | 
				
			||||||
            .ant-card-body {
 | 
					              .ant-card-body {
 | 
				
			||||||
              padding: 16px;
 | 
					                padding: 16px;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            .nb-row-divider {
 | 
					 | 
				
			||||||
              height: 16px;
 | 
					 | 
				
			||||||
              margin-top: -16px;
 | 
					 | 
				
			||||||
              &:last-child {
 | 
					 | 
				
			||||||
                margin-top: 0;
 | 
					 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					              .nb-row-divider {
 | 
				
			||||||
            .ant-description-input {
 | 
					                height: 16px;
 | 
				
			||||||
              text-overflow: ellipsis;
 | 
					                margin-top: -16px;
 | 
				
			||||||
              width: 100%;
 | 
					                &:last-child {
 | 
				
			||||||
              overflow: hidden;
 | 
					                  margin-top: 0;
 | 
				
			||||||
            }
 | 
					                }
 | 
				
			||||||
            .ant-description-textarea {
 | 
					              }
 | 
				
			||||||
              text-overflow: ellipsis;
 | 
					              .ant-description-input {
 | 
				
			||||||
              width: 100%;
 | 
					                text-overflow: ellipsis;
 | 
				
			||||||
              overflow: hidden;
 | 
					                width: 100%;
 | 
				
			||||||
            }
 | 
					                overflow: hidden;
 | 
				
			||||||
            .ant-formily-item {
 | 
					              }
 | 
				
			||||||
              margin-bottom: 12px;
 | 
					              .ant-description-textarea {
 | 
				
			||||||
            }
 | 
					                text-overflow: ellipsis;
 | 
				
			||||||
            .nb-grid-row:last-of-type {
 | 
					                width: 100%;
 | 
				
			||||||
              .nb-grid-col {
 | 
					                overflow: hidden;
 | 
				
			||||||
                .nb-form-item:last-of-type {
 | 
					              }
 | 
				
			||||||
                  .ant-formily-item {
 | 
					              .ant-formily-item {
 | 
				
			||||||
                    margin-bottom: 0;
 | 
					                margin-bottom: 12px;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              .nb-grid-row:last-of-type {
 | 
				
			||||||
 | 
					                .nb-grid-col {
 | 
				
			||||||
 | 
					                  .nb-form-item:last-of-type {
 | 
				
			||||||
 | 
					                    .ant-formily-item {
 | 
				
			||||||
 | 
					                      margin-bottom: 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            `,
 | 
				
			||||||
          `,
 | 
					            {
 | 
				
			||||||
          {
 | 
					              'kanban-no-label': labelDisabled,
 | 
				
			||||||
            'kanban-no-label': labelDisabled,
 | 
					            },
 | 
				
			||||||
          },
 | 
					          )}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <DndContext
 | 
				
			||||||
 | 
					            onDragStart={() => {
 | 
				
			||||||
 | 
					              setDisableCardDrag(true);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            onDragEnd={() => {
 | 
				
			||||||
 | 
					              setDisableCardDrag(false);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <FormLayout layout={'vertical'}>
 | 
				
			||||||
 | 
					              <RecursionField
 | 
				
			||||||
 | 
					                basePath={cardField.address.concat(`${columnIndex}.cards.${cardIndex}`)}
 | 
				
			||||||
 | 
					                schema={fieldSchema}
 | 
				
			||||||
 | 
					                onlyRenderProperties
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </FormLayout>
 | 
				
			||||||
 | 
					          </DndContext>
 | 
				
			||||||
 | 
					        </Card>
 | 
				
			||||||
 | 
					        {cardViewerSchema && (
 | 
				
			||||||
 | 
					          <ActionContext.Provider
 | 
				
			||||||
 | 
					            value={{
 | 
				
			||||||
 | 
					              openMode: fieldSchema['x-component-props']?.['openMode'] || 'drawer',
 | 
				
			||||||
 | 
					              openSize: fieldSchema['x-component-props']?.['openSize'],
 | 
				
			||||||
 | 
					              visible,
 | 
				
			||||||
 | 
					              setVisible,
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <RecordProvider record={card}>
 | 
				
			||||||
 | 
					              <RecursionField
 | 
				
			||||||
 | 
					                basePath={cardField.address.concat(`${columnIndex}.cardViewer.${cardIndex}`)}
 | 
				
			||||||
 | 
					                schema={cardViewerSchema}
 | 
				
			||||||
 | 
					                onlyRenderProperties
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </RecordProvider>
 | 
				
			||||||
 | 
					          </ActionContext.Provider>
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
      >
 | 
					      </SchemaComponentOptions>
 | 
				
			||||||
        <DndContext
 | 
					    );
 | 
				
			||||||
          onDragStart={() => {
 | 
					  },
 | 
				
			||||||
            setDisableCardDrag(true);
 | 
					  { displayName: 'KanbanCard' },
 | 
				
			||||||
          }}
 | 
					);
 | 
				
			||||||
          onDragEnd={() => {
 | 
					 | 
				
			||||||
            setDisableCardDrag(false);
 | 
					 | 
				
			||||||
          }}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <FormLayout layout={'vertical'}>
 | 
					 | 
				
			||||||
            <RecursionField
 | 
					 | 
				
			||||||
              basePath={cardField.address.concat(`${columnIndex}.cards.${cardIndex}`)}
 | 
					 | 
				
			||||||
              schema={fieldSchema}
 | 
					 | 
				
			||||||
              onlyRenderProperties
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          </FormLayout>
 | 
					 | 
				
			||||||
        </DndContext>
 | 
					 | 
				
			||||||
      </Card>
 | 
					 | 
				
			||||||
      {cardViewerSchema && (
 | 
					 | 
				
			||||||
        <ActionContext.Provider
 | 
					 | 
				
			||||||
          value={{
 | 
					 | 
				
			||||||
            openMode: fieldSchema['x-component-props']?.['openMode'] || 'drawer',
 | 
					 | 
				
			||||||
            openSize: fieldSchema['x-component-props']?.['openSize'],
 | 
					 | 
				
			||||||
            visible,
 | 
					 | 
				
			||||||
            setVisible,
 | 
					 | 
				
			||||||
          }}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <RecordProvider record={card}>
 | 
					 | 
				
			||||||
            <RecursionField
 | 
					 | 
				
			||||||
              basePath={cardField.address.concat(`${columnIndex}.cardViewer.${cardIndex}`)}
 | 
					 | 
				
			||||||
              schema={cardViewerSchema}
 | 
					 | 
				
			||||||
              onlyRenderProperties
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          </RecordProvider>
 | 
					 | 
				
			||||||
        </ActionContext.Provider>
 | 
					 | 
				
			||||||
      )}
 | 
					 | 
				
			||||||
    </SchemaComponentOptions>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
import { observer } from '@formily/react';
 | 
					import { observer } from '@formily/react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const KanbanCardViewer: any = observer((props: any) => {
 | 
					export const KanbanCardViewer: any = observer(
 | 
				
			||||||
  return props.children;
 | 
					  (props: any) => {
 | 
				
			||||||
});
 | 
					    return props.children;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'KanbanCardViewer' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -55,103 +55,106 @@ export const toColumns = (groupField: any, dataSource: Array<any> = []) => {
 | 
				
			|||||||
  return Object.values(columns);
 | 
					  return Object.values(columns);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Kanban: any = observer((props: any) => {
 | 
					export const Kanban: any = observer(
 | 
				
			||||||
  const { groupField, onCardDragEnd, ...restProps } = useProps(props);
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const { groupField, onCardDragEnd, ...restProps } = useProps(props);
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const [disableCardDrag, setDisableCardDrag] = useState(false);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const schemas = useMemo(
 | 
					    const [disableCardDrag, setDisableCardDrag] = useState(false);
 | 
				
			||||||
    () =>
 | 
					    const schemas = useMemo(
 | 
				
			||||||
      fieldSchema.reduceProperties(
 | 
					      () =>
 | 
				
			||||||
        (buf, current) => {
 | 
					        fieldSchema.reduceProperties(
 | 
				
			||||||
          if (current['x-component'].endsWith('.Card')) {
 | 
					          (buf, current) => {
 | 
				
			||||||
            buf.card = current;
 | 
					            if (current['x-component'].endsWith('.Card')) {
 | 
				
			||||||
          } else if (current['x-component'].endsWith('.CardAdder')) {
 | 
					              buf.card = current;
 | 
				
			||||||
            buf.cardAdder = current;
 | 
					            } else if (current['x-component'].endsWith('.CardAdder')) {
 | 
				
			||||||
          } else if (current['x-component'].endsWith('.CardViewer')) {
 | 
					              buf.cardAdder = current;
 | 
				
			||||||
            buf.cardViewer = current;
 | 
					            } else if (current['x-component'].endsWith('.CardViewer')) {
 | 
				
			||||||
          }
 | 
					              buf.cardViewer = current;
 | 
				
			||||||
          return buf;
 | 
					            }
 | 
				
			||||||
        },
 | 
					            return buf;
 | 
				
			||||||
        { card: null, cardAdder: null, cardViewer: null },
 | 
					          },
 | 
				
			||||||
      ),
 | 
					          { card: null, cardAdder: null, cardViewer: null },
 | 
				
			||||||
    [],
 | 
					        ),
 | 
				
			||||||
  );
 | 
					      [],
 | 
				
			||||||
  const handleCardRemove = (card, column) => {
 | 
					    );
 | 
				
			||||||
    const updatedBoard = Board.removeCard({ columns: field.value }, column, card);
 | 
					    const handleCardRemove = (card, column) => {
 | 
				
			||||||
    field.value = updatedBoard.columns;
 | 
					      const updatedBoard = Board.removeCard({ columns: field.value }, column, card);
 | 
				
			||||||
  };
 | 
					      field.value = updatedBoard.columns;
 | 
				
			||||||
  const handleCardDragEnd = (card, fromColumn, toColumn) => {
 | 
					    };
 | 
				
			||||||
    onCardDragEnd?.({ columns: field.value, groupField }, fromColumn, toColumn);
 | 
					    const handleCardDragEnd = (card, fromColumn, toColumn) => {
 | 
				
			||||||
    const updatedBoard = Board.moveCard({ columns: field.value }, fromColumn, toColumn);
 | 
					      onCardDragEnd?.({ columns: field.value, groupField }, fromColumn, toColumn);
 | 
				
			||||||
    field.value = updatedBoard.columns;
 | 
					      const updatedBoard = Board.moveCard({ columns: field.value }, fromColumn, toColumn);
 | 
				
			||||||
  };
 | 
					      field.value = updatedBoard.columns;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <Spin
 | 
					      <Spin
 | 
				
			||||||
      wrapperClassName={css`
 | 
					        wrapperClassName={css`
 | 
				
			||||||
        overflow: hidden;
 | 
					          overflow: hidden;
 | 
				
			||||||
        height: 100%;
 | 
					 | 
				
			||||||
        > .ant-spin-container {
 | 
					 | 
				
			||||||
          height: 100%;
 | 
					          height: 100%;
 | 
				
			||||||
        }
 | 
					          > .ant-spin-container {
 | 
				
			||||||
      `}
 | 
					            height: 100%;
 | 
				
			||||||
      spinning={field.loading || false}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <Board
 | 
					 | 
				
			||||||
        {...restProps}
 | 
					 | 
				
			||||||
        allowAddCard={!!schemas.cardAdder}
 | 
					 | 
				
			||||||
        disableColumnDrag
 | 
					 | 
				
			||||||
        cardAdderPosition={'bottom'}
 | 
					 | 
				
			||||||
        disableCardDrag={restProps.disableCardDrag || disableCardDrag}
 | 
					 | 
				
			||||||
        onCardRemove={handleCardRemove}
 | 
					 | 
				
			||||||
        onCardDragEnd={handleCardDragEnd}
 | 
					 | 
				
			||||||
        renderColumnHeader={({ title, color }) => (
 | 
					 | 
				
			||||||
          <div className={'react-kanban-column-header'}>
 | 
					 | 
				
			||||||
            <Tag color={color}>{title}</Tag>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        )}
 | 
					 | 
				
			||||||
        renderCard={(card, { column, dragging }) => {
 | 
					 | 
				
			||||||
          const columnIndex = field.value?.indexOf(column);
 | 
					 | 
				
			||||||
          const cardIndex = column?.cards?.indexOf(card);
 | 
					 | 
				
			||||||
          return (
 | 
					 | 
				
			||||||
            schemas.card && (
 | 
					 | 
				
			||||||
              <RecordProvider record={card}>
 | 
					 | 
				
			||||||
                <KanbanCardContext.Provider
 | 
					 | 
				
			||||||
                  value={{
 | 
					 | 
				
			||||||
                    setDisableCardDrag,
 | 
					 | 
				
			||||||
                    cardViewerSchema: schemas.cardViewer,
 | 
					 | 
				
			||||||
                    cardField: field,
 | 
					 | 
				
			||||||
                    card,
 | 
					 | 
				
			||||||
                    column,
 | 
					 | 
				
			||||||
                    dragging,
 | 
					 | 
				
			||||||
                    columnIndex,
 | 
					 | 
				
			||||||
                    cardIndex,
 | 
					 | 
				
			||||||
                  }}
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                  <RecursionField name={schemas.card.name} schema={schemas.card} />
 | 
					 | 
				
			||||||
                </KanbanCardContext.Provider>
 | 
					 | 
				
			||||||
              </RecordProvider>
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        renderCardAdder={({ column }) => {
 | 
					 | 
				
			||||||
          if (!schemas.cardAdder) {
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          return (
 | 
					        `}
 | 
				
			||||||
            <KanbanColumnContext.Provider value={{ column, groupField }}>
 | 
					        spinning={field.loading || false}
 | 
				
			||||||
              <SchemaComponentOptions scope={{ useCreateActionProps }}>
 | 
					 | 
				
			||||||
                <RecursionField name={schemas.cardAdder.name} schema={schemas.cardAdder} />
 | 
					 | 
				
			||||||
              </SchemaComponentOptions>
 | 
					 | 
				
			||||||
            </KanbanColumnContext.Provider>
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {{
 | 
					        <Board
 | 
				
			||||||
          columns: field.value || [],
 | 
					          {...restProps}
 | 
				
			||||||
        }}
 | 
					          allowAddCard={!!schemas.cardAdder}
 | 
				
			||||||
      </Board>
 | 
					          disableColumnDrag
 | 
				
			||||||
    </Spin>
 | 
					          cardAdderPosition={'bottom'}
 | 
				
			||||||
  );
 | 
					          disableCardDrag={restProps.disableCardDrag || disableCardDrag}
 | 
				
			||||||
});
 | 
					          onCardRemove={handleCardRemove}
 | 
				
			||||||
 | 
					          onCardDragEnd={handleCardDragEnd}
 | 
				
			||||||
 | 
					          renderColumnHeader={({ title, color }) => (
 | 
				
			||||||
 | 
					            <div className={'react-kanban-column-header'}>
 | 
				
			||||||
 | 
					              <Tag color={color}>{title}</Tag>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					          renderCard={(card, { column, dragging }) => {
 | 
				
			||||||
 | 
					            const columnIndex = field.value?.indexOf(column);
 | 
				
			||||||
 | 
					            const cardIndex = column?.cards?.indexOf(card);
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					              schemas.card && (
 | 
				
			||||||
 | 
					                <RecordProvider record={card}>
 | 
				
			||||||
 | 
					                  <KanbanCardContext.Provider
 | 
				
			||||||
 | 
					                    value={{
 | 
				
			||||||
 | 
					                      setDisableCardDrag,
 | 
				
			||||||
 | 
					                      cardViewerSchema: schemas.cardViewer,
 | 
				
			||||||
 | 
					                      cardField: field,
 | 
				
			||||||
 | 
					                      card,
 | 
				
			||||||
 | 
					                      column,
 | 
				
			||||||
 | 
					                      dragging,
 | 
				
			||||||
 | 
					                      columnIndex,
 | 
				
			||||||
 | 
					                      cardIndex,
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                  >
 | 
				
			||||||
 | 
					                    <RecursionField name={schemas.card.name} schema={schemas.card} />
 | 
				
			||||||
 | 
					                  </KanbanCardContext.Provider>
 | 
				
			||||||
 | 
					                </RecordProvider>
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          renderCardAdder={({ column }) => {
 | 
				
			||||||
 | 
					            if (!schemas.cardAdder) {
 | 
				
			||||||
 | 
					              return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					              <KanbanColumnContext.Provider value={{ column, groupField }}>
 | 
				
			||||||
 | 
					                <SchemaComponentOptions scope={{ useCreateActionProps }}>
 | 
				
			||||||
 | 
					                  <RecursionField name={schemas.cardAdder.name} schema={schemas.cardAdder} />
 | 
				
			||||||
 | 
					                </SchemaComponentOptions>
 | 
				
			||||||
 | 
					              </KanbanColumnContext.Provider>
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {{
 | 
				
			||||||
 | 
					            columns: field.value || [],
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        </Board>
 | 
				
			||||||
 | 
					      </Spin>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Kanban' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -41,44 +41,47 @@ const MarkdownEditor = (props: any) => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const MarkdownVoid: any = observer((props: any) => {
 | 
					export const MarkdownVoid: any = observer(
 | 
				
			||||||
  const { content, className } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField();
 | 
					    const { content, className } = props;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField();
 | 
				
			||||||
  const { dn } = useDesignable();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const { onSave, onCancel } = props;
 | 
					    const { dn } = useDesignable();
 | 
				
			||||||
  const { html, loading } = useParseMarkdown(content);
 | 
					    const { onSave, onCancel } = props;
 | 
				
			||||||
  if (loading) {
 | 
					    const { html, loading } = useParseMarkdown(content);
 | 
				
			||||||
    return <Spin />;
 | 
					    if (loading) {
 | 
				
			||||||
  }
 | 
					      return <Spin />;
 | 
				
			||||||
  return field?.editable ? (
 | 
					    }
 | 
				
			||||||
    <MarkdownEditor
 | 
					    return field?.editable ? (
 | 
				
			||||||
      {...props}
 | 
					      <MarkdownEditor
 | 
				
			||||||
      className
 | 
					        {...props}
 | 
				
			||||||
      defaultValue={content}
 | 
					        className
 | 
				
			||||||
      onCancel={() => {
 | 
					        defaultValue={content}
 | 
				
			||||||
        field.editable = false;
 | 
					        onCancel={() => {
 | 
				
			||||||
        onCancel?.();
 | 
					          field.editable = false;
 | 
				
			||||||
      }}
 | 
					          onCancel?.();
 | 
				
			||||||
      onSubmit={async (value) => {
 | 
					        }}
 | 
				
			||||||
        field.editable = false;
 | 
					        onSubmit={async (value) => {
 | 
				
			||||||
        schema['x-component-props'] ?? (schema['x-component-props'] = {});
 | 
					          field.editable = false;
 | 
				
			||||||
        schema['x-component-props']['content'] = value;
 | 
					          schema['x-component-props'] ?? (schema['x-component-props'] = {});
 | 
				
			||||||
        field.componentProps.content = value;
 | 
					          schema['x-component-props']['content'] = value;
 | 
				
			||||||
        onSave?.(schema);
 | 
					          field.componentProps.content = value;
 | 
				
			||||||
        dn.emit('patch', {
 | 
					          onSave?.(schema);
 | 
				
			||||||
          schema: {
 | 
					          dn.emit('patch', {
 | 
				
			||||||
            'x-uid': schema['x-uid'],
 | 
					            schema: {
 | 
				
			||||||
            'x-component-props': {
 | 
					              'x-uid': schema['x-uid'],
 | 
				
			||||||
              content: value,
 | 
					              'x-component-props': {
 | 
				
			||||||
 | 
					                content: value,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          });
 | 
				
			||||||
        });
 | 
					        }}
 | 
				
			||||||
      }}
 | 
					      />
 | 
				
			||||||
    />
 | 
					    ) : (
 | 
				
			||||||
  ) : (
 | 
					      <div className={cls(['nb-markdown', className])} dangerouslySetInnerHTML={{ __html: html }} />
 | 
				
			||||||
    <div className={cls(['nb-markdown', className])} dangerouslySetInnerHTML={{ __html: html }} />
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'MarkdownVoid' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MarkdownVoid.Designer = MarkdownVoidDesigner;
 | 
					MarkdownVoid.Designer = MarkdownVoidDesigner;
 | 
				
			||||||
 | 
				
			|||||||
@ -23,24 +23,27 @@ const schema = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Editable = observer((props: any) => {
 | 
					const Editable = observer(
 | 
				
			||||||
  const filed = useField<any>();
 | 
					  (props: any) => {
 | 
				
			||||||
  if (filed.editable) {
 | 
					    const filed = useField<any>();
 | 
				
			||||||
    return props.children;
 | 
					    if (filed.editable) {
 | 
				
			||||||
  }
 | 
					      return props.children;
 | 
				
			||||||
  return (
 | 
					    }
 | 
				
			||||||
    <div>
 | 
					    return (
 | 
				
			||||||
      <Button
 | 
					      <div>
 | 
				
			||||||
        onClick={() => {
 | 
					        <Button
 | 
				
			||||||
          filed.editable = true;
 | 
					          onClick={() => {
 | 
				
			||||||
        }}
 | 
					            filed.editable = true;
 | 
				
			||||||
      >
 | 
					          }}
 | 
				
			||||||
        编辑
 | 
					        >
 | 
				
			||||||
      </Button>
 | 
					          编辑
 | 
				
			||||||
      <div>{props.children}</div>
 | 
					        </Button>
 | 
				
			||||||
    </div>
 | 
					        <div>{props.children}</div>
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Editable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -136,148 +136,149 @@ const useSideMenuRef = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const MenuItemDesignerContext = createContext(null);
 | 
					const MenuItemDesignerContext = createContext(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Menu: ComposedMenu = observer((props) => {
 | 
					export const Menu: ComposedMenu = observer(
 | 
				
			||||||
  const {
 | 
					  (props) => {
 | 
				
			||||||
    onSelect,
 | 
					    const {
 | 
				
			||||||
    mode,
 | 
					      onSelect,
 | 
				
			||||||
    selectedUid,
 | 
					      mode,
 | 
				
			||||||
    defaultSelectedUid,
 | 
					      selectedUid,
 | 
				
			||||||
    sideMenuRefScopeKey,
 | 
					      defaultSelectedUid,
 | 
				
			||||||
    defaultSelectedKeys: dSelectedKeys,
 | 
					      sideMenuRefScopeKey,
 | 
				
			||||||
    defaultOpenKeys: dOpenKeys,
 | 
					      defaultSelectedKeys: dSelectedKeys,
 | 
				
			||||||
    ...others
 | 
					      defaultOpenKeys: dOpenKeys,
 | 
				
			||||||
  } = useProps(props);
 | 
					      ...others
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					    } = useProps(props);
 | 
				
			||||||
  const Designer = useDesigner();
 | 
					    const { t } = useTranslation();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const Designer = useDesigner();
 | 
				
			||||||
  const { refresh } = useDesignable();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const api = useAPIClient();
 | 
					    const { refresh } = useDesignable();
 | 
				
			||||||
  const { render } = useSchemaInitializer(schema['x-initializer']);
 | 
					    const api = useAPIClient();
 | 
				
			||||||
  const sideMenuRef = useSideMenuRef();
 | 
					    const { render } = useSchemaInitializer(schema['x-initializer']);
 | 
				
			||||||
  const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
 | 
					    const sideMenuRef = useSideMenuRef();
 | 
				
			||||||
    if (dSelectedKeys) {
 | 
					    const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
 | 
				
			||||||
      return dSelectedKeys;
 | 
					      if (dSelectedKeys) {
 | 
				
			||||||
    }
 | 
					        return dSelectedKeys;
 | 
				
			||||||
    if (defaultSelectedUid) {
 | 
					 | 
				
			||||||
      return findKeysByUid(schema, defaultSelectedUid);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return [];
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					 | 
				
			||||||
  const [defaultOpenKeys, setDefaultOpenKeys] = useState(() => {
 | 
					 | 
				
			||||||
    if (['inline', 'mix'].includes(mode)) {
 | 
					 | 
				
			||||||
      return dOpenKeys || defaultSelectedKeys;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return dOpenKeys;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  const [sideMenuSchema, setSideMenuSchema] = useState<Schema>(() => {
 | 
					 | 
				
			||||||
    const key = defaultSelectedKeys?.[0] || null;
 | 
					 | 
				
			||||||
    if (mode === 'mix' && key) {
 | 
					 | 
				
			||||||
      const s = schema.properties?.[key];
 | 
					 | 
				
			||||||
      if (s['x-component'] === 'Menu.SubMenu') {
 | 
					 | 
				
			||||||
        return s;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					      if (defaultSelectedUid) {
 | 
				
			||||||
    return null;
 | 
					        return findKeysByUid(schema, defaultSelectedUid);
 | 
				
			||||||
  });
 | 
					      }
 | 
				
			||||||
  useEffect(() => {
 | 
					      return [];
 | 
				
			||||||
    const keys = findKeysByUid(schema, selectedUid);
 | 
					    });
 | 
				
			||||||
    setDefaultSelectedKeys(keys);
 | 
					    const [loading, setLoading] = useState(false);
 | 
				
			||||||
    if (['inline', 'mix'].includes(mode)) {
 | 
					    const [defaultOpenKeys, setDefaultOpenKeys] = useState(() => {
 | 
				
			||||||
      setDefaultOpenKeys(dOpenKeys || keys);
 | 
					      if (['inline', 'mix'].includes(mode)) {
 | 
				
			||||||
    }
 | 
					        return dOpenKeys || defaultSelectedKeys;
 | 
				
			||||||
    const key = keys?.[0] || null;
 | 
					      }
 | 
				
			||||||
    if (mode === 'mix') {
 | 
					      return dOpenKeys;
 | 
				
			||||||
      if (key) {
 | 
					    });
 | 
				
			||||||
 | 
					    const [sideMenuSchema, setSideMenuSchema] = useState<Schema>(() => {
 | 
				
			||||||
 | 
					      const key = defaultSelectedKeys?.[0] || null;
 | 
				
			||||||
 | 
					      if (mode === 'mix' && key) {
 | 
				
			||||||
        const s = schema.properties?.[key];
 | 
					        const s = schema.properties?.[key];
 | 
				
			||||||
        if (s['x-component'] === 'Menu.SubMenu') {
 | 
					        if (s['x-component'] === 'Menu.SubMenu') {
 | 
				
			||||||
          setSideMenuSchema(s);
 | 
					          return s;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        setSideMenuSchema(null);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					      return null;
 | 
				
			||||||
  }, [selectedUid]);
 | 
					    });
 | 
				
			||||||
  useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
    if (['inline', 'mix'].includes(mode)) {
 | 
					      const keys = findKeysByUid(schema, selectedUid);
 | 
				
			||||||
      setDefaultOpenKeys(defaultSelectedKeys);
 | 
					      setDefaultSelectedKeys(keys);
 | 
				
			||||||
    }
 | 
					      if (['inline', 'mix'].includes(mode)) {
 | 
				
			||||||
  }, [defaultSelectedKeys]);
 | 
					        setDefaultOpenKeys(dOpenKeys || keys);
 | 
				
			||||||
  useEffect(() => {
 | 
					      }
 | 
				
			||||||
    const sideMenuElement = sideMenuRef?.current as HTMLElement;
 | 
					      const key = keys?.[0] || null;
 | 
				
			||||||
    if (!sideMenuElement) {
 | 
					      if (mode === 'mix') {
 | 
				
			||||||
      return;
 | 
					        if (key) {
 | 
				
			||||||
    }
 | 
					          const s = schema.properties?.[key];
 | 
				
			||||||
    sideMenuElement.style.display = sideMenuSchema?.['x-component'] === 'Menu.SubMenu' ? 'block' : 'none';
 | 
					          if (s['x-component'] === 'Menu.SubMenu') {
 | 
				
			||||||
  }, [sideMenuSchema?.name, sideMenuRef]);
 | 
					            setSideMenuSchema(s);
 | 
				
			||||||
  const { designable } = useDesignable();
 | 
					          }
 | 
				
			||||||
  return (
 | 
					        } else {
 | 
				
			||||||
    <DndContext>
 | 
					          setSideMenuSchema(null);
 | 
				
			||||||
      <MenuItemDesignerContext.Provider value={Designer}>
 | 
					        }
 | 
				
			||||||
        <MenuModeContext.Provider value={mode}>
 | 
					      }
 | 
				
			||||||
          <AntdMenu
 | 
					    }, [selectedUid]);
 | 
				
			||||||
            {...others}
 | 
					    useEffect(() => {
 | 
				
			||||||
            style={
 | 
					      if (['inline', 'mix'].includes(mode)) {
 | 
				
			||||||
              {
 | 
					        setDefaultOpenKeys(defaultSelectedKeys);
 | 
				
			||||||
                // width: mode === 'mix' ? '100%' : undefined,
 | 
					      }
 | 
				
			||||||
              }
 | 
					    }, [defaultSelectedKeys]);
 | 
				
			||||||
            }
 | 
					    useEffect(() => {
 | 
				
			||||||
            className={css`
 | 
					      const sideMenuElement = sideMenuRef?.current as HTMLElement;
 | 
				
			||||||
              .ant-menu-item:hover {
 | 
					      if (!sideMenuElement) {
 | 
				
			||||||
                > .ant-menu-title-content > div {
 | 
					        return;
 | 
				
			||||||
                  .general-schema-designer {
 | 
					      }
 | 
				
			||||||
                    display: block;
 | 
					      sideMenuElement.style.display = sideMenuSchema?.['x-component'] === 'Menu.SubMenu' ? 'block' : 'none';
 | 
				
			||||||
                  }
 | 
					    }, [sideMenuSchema?.name, sideMenuRef]);
 | 
				
			||||||
 | 
					    const { designable } = useDesignable();
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <DndContext>
 | 
				
			||||||
 | 
					        <MenuItemDesignerContext.Provider value={Designer}>
 | 
				
			||||||
 | 
					          <MenuModeContext.Provider value={mode}>
 | 
				
			||||||
 | 
					            <AntdMenu
 | 
				
			||||||
 | 
					              {...others}
 | 
				
			||||||
 | 
					              style={
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  // width: mode === 'mix' ? '100%' : undefined,
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            `}
 | 
					              className={css`
 | 
				
			||||||
            onSelect={(info: any) => {
 | 
					                .ant-menu-item:hover {
 | 
				
			||||||
              const s = schema.properties[info.key];
 | 
					                  > .ant-menu-title-content > div {
 | 
				
			||||||
              if (mode === 'mix') {
 | 
					                    .general-schema-designer {
 | 
				
			||||||
                setSideMenuSchema(s);
 | 
					                      display: block;
 | 
				
			||||||
                if (s['x-component'] !== 'Menu.SubMenu') {
 | 
					                    }
 | 
				
			||||||
                  onSelect && onSelect(info);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                  const menuItemSchema = findMenuItem(s);
 | 
					 | 
				
			||||||
                  if (!menuItemSchema) {
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                  // TODO
 | 
					                }
 | 
				
			||||||
                  setLoading(true);
 | 
					              `}
 | 
				
			||||||
                  const keys = findKeysByUid(schema, menuItemSchema['x-uid']);
 | 
					              onSelect={(info: any) => {
 | 
				
			||||||
                  setDefaultSelectedKeys(keys);
 | 
					                const s = schema.properties[info.key];
 | 
				
			||||||
                  setTimeout(() => {
 | 
					                if (mode === 'mix') {
 | 
				
			||||||
                    setLoading(false);
 | 
					                  setSideMenuSchema(s);
 | 
				
			||||||
                  }, 100);
 | 
					                  if (s['x-component'] !== 'Menu.SubMenu') {
 | 
				
			||||||
                  onSelect &&
 | 
					                    onSelect && onSelect(info);
 | 
				
			||||||
                    onSelect({
 | 
					                  } else {
 | 
				
			||||||
                      key: menuItemSchema.name,
 | 
					                    const menuItemSchema = findMenuItem(s);
 | 
				
			||||||
                      item: {
 | 
					                    if (!menuItemSchema) {
 | 
				
			||||||
                        props: {
 | 
					                      return;
 | 
				
			||||||
                          schema: menuItemSchema,
 | 
					                    }
 | 
				
			||||||
 | 
					                    // TODO
 | 
				
			||||||
 | 
					                    setLoading(true);
 | 
				
			||||||
 | 
					                    const keys = findKeysByUid(schema, menuItemSchema['x-uid']);
 | 
				
			||||||
 | 
					                    setDefaultSelectedKeys(keys);
 | 
				
			||||||
 | 
					                    setTimeout(() => {
 | 
				
			||||||
 | 
					                      setLoading(false);
 | 
				
			||||||
 | 
					                    }, 100);
 | 
				
			||||||
 | 
					                    onSelect &&
 | 
				
			||||||
 | 
					                      onSelect({
 | 
				
			||||||
 | 
					                        key: menuItemSchema.name,
 | 
				
			||||||
 | 
					                        item: {
 | 
				
			||||||
 | 
					                          props: {
 | 
				
			||||||
 | 
					                            schema: menuItemSchema,
 | 
				
			||||||
 | 
					                          },
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                      },
 | 
					                      });
 | 
				
			||||||
                    });
 | 
					                  }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  onSelect && onSelect(info);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              } else {
 | 
					              }}
 | 
				
			||||||
                onSelect && onSelect(info);
 | 
					              mode={mode === 'mix' ? 'horizontal' : mode}
 | 
				
			||||||
              }
 | 
					              defaultOpenKeys={defaultOpenKeys}
 | 
				
			||||||
            }}
 | 
					              defaultSelectedKeys={defaultSelectedKeys}
 | 
				
			||||||
            mode={mode === 'mix' ? 'horizontal' : mode}
 | 
					              selectedKeys={defaultSelectedKeys}
 | 
				
			||||||
            defaultOpenKeys={defaultOpenKeys}
 | 
					            >
 | 
				
			||||||
            defaultSelectedKeys={defaultSelectedKeys}
 | 
					              {designable && (
 | 
				
			||||||
            selectedKeys={defaultSelectedKeys}
 | 
					                <AntdMenu.Item disabled key="x-designer-button" style={{ padding: '0 8px', order: 9999 }}>
 | 
				
			||||||
          >
 | 
					                  {render({ style: { background: 'none' } })}
 | 
				
			||||||
            {designable && (
 | 
					                </AntdMenu.Item>
 | 
				
			||||||
              <AntdMenu.Item disabled key="x-designer-button" style={{ padding: '0 8px', order: 9999 }}>
 | 
					              )}
 | 
				
			||||||
                {render({ style: { background: 'none' } })}
 | 
					              {props.children}
 | 
				
			||||||
              </AntdMenu.Item>
 | 
					            </AntdMenu>
 | 
				
			||||||
            )}
 | 
					            {loading
 | 
				
			||||||
            {props.children}
 | 
					              ? null
 | 
				
			||||||
          </AntdMenu>
 | 
					              : mode === 'mix' &&
 | 
				
			||||||
          {loading
 | 
					 | 
				
			||||||
            ? null
 | 
					 | 
				
			||||||
            : mode === 'mix' &&
 | 
					 | 
				
			||||||
              sideMenuSchema?.['x-component'] === 'Menu.SubMenu' &&
 | 
					              sideMenuSchema?.['x-component'] === 'Menu.SubMenu' &&
 | 
				
			||||||
              sideMenuRef?.current?.firstChild &&
 | 
					              sideMenuRef?.current?.firstChild &&
 | 
				
			||||||
              createPortal(
 | 
					              createPortal(
 | 
				
			||||||
@ -290,37 +291,37 @@ export const Menu: ComposedMenu = observer((props) => {
 | 
				
			|||||||
                      onSelect && onSelect(info);
 | 
					                      onSelect && onSelect(info);
 | 
				
			||||||
                    }}
 | 
					                    }}
 | 
				
			||||||
                    className={css`
 | 
					                    className={css`
 | 
				
			||||||
                      height: 100%;
 | 
					                        height: 100%;
 | 
				
			||||||
                      overflow-y: auto;
 | 
					                        overflow-y: auto;
 | 
				
			||||||
                      overflow-x: hidden;
 | 
					                        overflow-x: hidden;
 | 
				
			||||||
                      .ant-menu-item {
 | 
					                        .ant-menu-item {
 | 
				
			||||||
                        > .ant-menu-title-content {
 | 
					                          > .ant-menu-title-content {
 | 
				
			||||||
                          margin-left: -24px;
 | 
					                            margin-left: -24px;
 | 
				
			||||||
                          margin-right: -16px;
 | 
					                            margin-right: -16px;
 | 
				
			||||||
                          padding: 0 16px 0 24px;
 | 
					                            padding: 0 16px 0 24px;
 | 
				
			||||||
                          > div {
 | 
					                            > div {
 | 
				
			||||||
                            > .general-schema-designer {
 | 
					                              > .general-schema-designer {
 | 
				
			||||||
                              right: 6px !important;
 | 
					                                right: 6px !important;
 | 
				
			||||||
 | 
					                              }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                          }
 | 
					                          }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                      }
 | 
					                        .ant-menu-submenu-title {
 | 
				
			||||||
                      .ant-menu-submenu-title {
 | 
					                          .ant-menu-title-content {
 | 
				
			||||||
                        .ant-menu-title-content {
 | 
					                            margin-left: -24px;
 | 
				
			||||||
                          margin-left: -24px;
 | 
					                            margin-right: -34px;
 | 
				
			||||||
                          margin-right: -34px;
 | 
					                            padding: 0 34px 0 24px;
 | 
				
			||||||
                          padding: 0 34px 0 24px;
 | 
					                            > div {
 | 
				
			||||||
                          > div {
 | 
					                              > .general-schema-designer {
 | 
				
			||||||
                            > .general-schema-designer {
 | 
					                                right: 6px !important;
 | 
				
			||||||
                              right: 6px !important;
 | 
					                              }
 | 
				
			||||||
                            }
 | 
					                              > span.anticon {
 | 
				
			||||||
                            > span.anticon {
 | 
					                                margin-right: 10px;
 | 
				
			||||||
                              margin-right: 10px;
 | 
					                              }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                          }
 | 
					                          }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                      }
 | 
					                      `}
 | 
				
			||||||
                    `}
 | 
					 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    <RecursionField schema={sideMenuSchema} onlyRenderProperties />
 | 
					                    <RecursionField schema={sideMenuSchema} onlyRenderProperties />
 | 
				
			||||||
                    {render({
 | 
					                    {render({
 | 
				
			||||||
@ -340,117 +341,128 @@ export const Menu: ComposedMenu = observer((props) => {
 | 
				
			|||||||
                </MenuModeContext.Provider>,
 | 
					                </MenuModeContext.Provider>,
 | 
				
			||||||
                sideMenuRef.current.firstChild,
 | 
					                sideMenuRef.current.firstChild,
 | 
				
			||||||
              )}
 | 
					              )}
 | 
				
			||||||
        </MenuModeContext.Provider>
 | 
					          </MenuModeContext.Provider>
 | 
				
			||||||
      </MenuItemDesignerContext.Provider>
 | 
					        </MenuItemDesignerContext.Provider>
 | 
				
			||||||
    </DndContext>
 | 
					      </DndContext>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Menu' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Menu.Item = observer((props) => {
 | 
					Menu.Item = observer(
 | 
				
			||||||
  const { icon, ...others } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const { icon, ...others } = props;
 | 
				
			||||||
  const field = useField();
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const Designer = useContext(MenuItemDesignerContext);
 | 
					    const field = useField();
 | 
				
			||||||
  return (
 | 
					    const Designer = useContext(MenuItemDesignerContext);
 | 
				
			||||||
    <AntdMenu.Item
 | 
					    return (
 | 
				
			||||||
      {...others}
 | 
					      <AntdMenu.Item
 | 
				
			||||||
      className={css`
 | 
					        {...others}
 | 
				
			||||||
        :active {
 | 
					        className={css`
 | 
				
			||||||
          background: inherit;
 | 
					          :active {
 | 
				
			||||||
        }
 | 
					            background: inherit;
 | 
				
			||||||
      `}
 | 
					          }
 | 
				
			||||||
      key={schema.name}
 | 
					        `}
 | 
				
			||||||
      eventKey={schema.name}
 | 
					        key={schema.name}
 | 
				
			||||||
      schema={schema}
 | 
					        eventKey={schema.name}
 | 
				
			||||||
    >
 | 
					        schema={schema}
 | 
				
			||||||
      <SortableItem className={designerCss} removeParentsIfNoChildren={false}>
 | 
					      >
 | 
				
			||||||
        <Icon type={icon} />
 | 
					        <SortableItem className={designerCss} removeParentsIfNoChildren={false}>
 | 
				
			||||||
        <span
 | 
					 | 
				
			||||||
          className={css`
 | 
					 | 
				
			||||||
            overflow: hidden;
 | 
					 | 
				
			||||||
            text-overflow: ellipsis;
 | 
					 | 
				
			||||||
            display: inline-block;
 | 
					 | 
				
			||||||
            width: 100%;
 | 
					 | 
				
			||||||
            vertical-align: middle;
 | 
					 | 
				
			||||||
          `}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {field.title}
 | 
					 | 
				
			||||||
        </span>
 | 
					 | 
				
			||||||
        <Designer />
 | 
					 | 
				
			||||||
      </SortableItem>
 | 
					 | 
				
			||||||
    </AntdMenu.Item>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Menu.URL = observer((props) => {
 | 
					 | 
				
			||||||
  const { icon, ...others } = props;
 | 
					 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					 | 
				
			||||||
  const field = useField();
 | 
					 | 
				
			||||||
  const Designer = useContext(MenuItemDesignerContext);
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <AntdMenu.Item
 | 
					 | 
				
			||||||
      {...others}
 | 
					 | 
				
			||||||
      className={css`
 | 
					 | 
				
			||||||
        :active {
 | 
					 | 
				
			||||||
          background: inherit;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      `}
 | 
					 | 
				
			||||||
      key={schema.name}
 | 
					 | 
				
			||||||
      eventKey={schema.name}
 | 
					 | 
				
			||||||
      schema={schema}
 | 
					 | 
				
			||||||
      onClick={() => {
 | 
					 | 
				
			||||||
        window.open(props.href, '_blank');
 | 
					 | 
				
			||||||
      }}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <SortableItem className={designerCss} removeParentsIfNoChildren={false}>
 | 
					 | 
				
			||||||
        <Icon type={icon} />
 | 
					 | 
				
			||||||
        <span
 | 
					 | 
				
			||||||
          className={css`
 | 
					 | 
				
			||||||
            overflow: hidden;
 | 
					 | 
				
			||||||
            text-overflow: ellipsis;
 | 
					 | 
				
			||||||
            display: inline-block;
 | 
					 | 
				
			||||||
            width: 100%;
 | 
					 | 
				
			||||||
            vertical-align: middle;
 | 
					 | 
				
			||||||
          `}
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {field.title}
 | 
					 | 
				
			||||||
        </span>
 | 
					 | 
				
			||||||
        <Designer />
 | 
					 | 
				
			||||||
      </SortableItem>
 | 
					 | 
				
			||||||
    </AntdMenu.Item>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Menu.SubMenu = observer((props) => {
 | 
					 | 
				
			||||||
  const { icon, ...others } = props;
 | 
					 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					 | 
				
			||||||
  const field = useField();
 | 
					 | 
				
			||||||
  const mode = useContext(MenuModeContext);
 | 
					 | 
				
			||||||
  const Designer = useContext(MenuItemDesignerContext);
 | 
					 | 
				
			||||||
  if (mode === 'mix') {
 | 
					 | 
				
			||||||
    return <Menu.Item {...props} />;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <AntdMenu.SubMenu
 | 
					 | 
				
			||||||
      {...others}
 | 
					 | 
				
			||||||
      className={css`
 | 
					 | 
				
			||||||
        :active {
 | 
					 | 
				
			||||||
          background: inherit;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      `}
 | 
					 | 
				
			||||||
      key={schema.name}
 | 
					 | 
				
			||||||
      eventKey={schema.name}
 | 
					 | 
				
			||||||
      title={
 | 
					 | 
				
			||||||
        <SortableItem className={subMenuDesignerCss} removeParentsIfNoChildren={false}>
 | 
					 | 
				
			||||||
          <Icon type={icon} />
 | 
					          <Icon type={icon} />
 | 
				
			||||||
          {field.title}
 | 
					          <span
 | 
				
			||||||
 | 
					            className={css`
 | 
				
			||||||
 | 
					              overflow: hidden;
 | 
				
			||||||
 | 
					              text-overflow: ellipsis;
 | 
				
			||||||
 | 
					              display: inline-block;
 | 
				
			||||||
 | 
					              width: 100%;
 | 
				
			||||||
 | 
					              vertical-align: middle;
 | 
				
			||||||
 | 
					            `}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {field.title}
 | 
				
			||||||
 | 
					          </span>
 | 
				
			||||||
          <Designer />
 | 
					          <Designer />
 | 
				
			||||||
        </SortableItem>
 | 
					        </SortableItem>
 | 
				
			||||||
      }
 | 
					      </AntdMenu.Item>
 | 
				
			||||||
    >
 | 
					    );
 | 
				
			||||||
      <RecursionField schema={schema} onlyRenderProperties />
 | 
					  },
 | 
				
			||||||
    </AntdMenu.SubMenu>
 | 
					  { displayName: 'MenuItem' },
 | 
				
			||||||
  );
 | 
					);
 | 
				
			||||||
});
 | 
					
 | 
				
			||||||
 | 
					Menu.URL = observer(
 | 
				
			||||||
 | 
					  (props) => {
 | 
				
			||||||
 | 
					    const { icon, ...others } = props;
 | 
				
			||||||
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					    const Designer = useContext(MenuItemDesignerContext);
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <AntdMenu.Item
 | 
				
			||||||
 | 
					        {...others}
 | 
				
			||||||
 | 
					        className={css`
 | 
				
			||||||
 | 
					          :active {
 | 
				
			||||||
 | 
					            background: inherit;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        `}
 | 
				
			||||||
 | 
					        key={schema.name}
 | 
				
			||||||
 | 
					        eventKey={schema.name}
 | 
				
			||||||
 | 
					        schema={schema}
 | 
				
			||||||
 | 
					        onClick={() => {
 | 
				
			||||||
 | 
					          window.open(props.href, '_blank');
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <SortableItem className={designerCss} removeParentsIfNoChildren={false}>
 | 
				
			||||||
 | 
					          <Icon type={icon} />
 | 
				
			||||||
 | 
					          <span
 | 
				
			||||||
 | 
					            className={css`
 | 
				
			||||||
 | 
					              overflow: hidden;
 | 
				
			||||||
 | 
					              text-overflow: ellipsis;
 | 
				
			||||||
 | 
					              display: inline-block;
 | 
				
			||||||
 | 
					              width: 100%;
 | 
				
			||||||
 | 
					              vertical-align: middle;
 | 
				
			||||||
 | 
					            `}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            {field.title}
 | 
				
			||||||
 | 
					          </span>
 | 
				
			||||||
 | 
					          <Designer />
 | 
				
			||||||
 | 
					        </SortableItem>
 | 
				
			||||||
 | 
					      </AntdMenu.Item>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'MenuURL' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Menu.SubMenu = observer(
 | 
				
			||||||
 | 
					  (props) => {
 | 
				
			||||||
 | 
					    const { icon, ...others } = props;
 | 
				
			||||||
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
 | 
					    const field = useField();
 | 
				
			||||||
 | 
					    const mode = useContext(MenuModeContext);
 | 
				
			||||||
 | 
					    const Designer = useContext(MenuItemDesignerContext);
 | 
				
			||||||
 | 
					    if (mode === 'mix') {
 | 
				
			||||||
 | 
					      return <Menu.Item {...props} />;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <AntdMenu.SubMenu
 | 
				
			||||||
 | 
					        {...others}
 | 
				
			||||||
 | 
					        className={css`
 | 
				
			||||||
 | 
					          :active {
 | 
				
			||||||
 | 
					            background: inherit;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        `}
 | 
				
			||||||
 | 
					        key={schema.name}
 | 
				
			||||||
 | 
					        eventKey={schema.name}
 | 
				
			||||||
 | 
					        title={
 | 
				
			||||||
 | 
					          <SortableItem className={subMenuDesignerCss} removeParentsIfNoChildren={false}>
 | 
				
			||||||
 | 
					            <Icon type={icon} />
 | 
				
			||||||
 | 
					            {field.title}
 | 
				
			||||||
 | 
					            <Designer />
 | 
				
			||||||
 | 
					          </SortableItem>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <RecursionField schema={schema} onlyRenderProperties />
 | 
				
			||||||
 | 
					      </AntdMenu.SubMenu>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'MenuSubMenu' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Menu.Designer = MenuDesigner;
 | 
					Menu.Designer = MenuDesigner;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,20 +3,23 @@ import { Pagination as AntdPagination } from 'antd';
 | 
				
			|||||||
import React, { KeyboardEventHandler } from 'react';
 | 
					import React, { KeyboardEventHandler } from 'react';
 | 
				
			||||||
import { useProps } from '../../hooks/useProps';
 | 
					import { useProps } from '../../hooks/useProps';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Pagination = observer((props: any) => {
 | 
					export const Pagination = observer(
 | 
				
			||||||
  const { hidden, ...others } = useProps(props);
 | 
					  (props: any) => {
 | 
				
			||||||
  if (hidden) {
 | 
					    const { hidden, ...others } = useProps(props);
 | 
				
			||||||
    return null;
 | 
					    if (hidden) {
 | 
				
			||||||
  }
 | 
					      return null;
 | 
				
			||||||
  const onKeypress: KeyboardEventHandler<HTMLDivElement> = (e) => {
 | 
					 | 
				
			||||||
    if (e.key === 'Enter') {
 | 
					 | 
				
			||||||
      e.preventDefault();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					    const onKeypress: KeyboardEventHandler<HTMLDivElement> = (e) => {
 | 
				
			||||||
 | 
					      if (e.key === 'Enter') {
 | 
				
			||||||
 | 
					        e.preventDefault();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div onKeyPress={onKeypress}>
 | 
					      <div onKeyPress={onKeypress}>
 | 
				
			||||||
      <AntdPagination {...others} />
 | 
					        <AntdPagination {...others} />
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Pagination' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -25,98 +25,101 @@ const toValue = (value, placeholder) => {
 | 
				
			|||||||
  return value;
 | 
					  return value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReadPrettyRecordPicker: React.FC = observer((props: any) => {
 | 
					export const ReadPrettyRecordPicker: React.FC = observer(
 | 
				
			||||||
  const { ellipsis } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const { ellipsis } = props;
 | 
				
			||||||
  const recordCtx = useRecord();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { getCollectionJoinField } = useCollectionManager();
 | 
					    const recordCtx = useRecord();
 | 
				
			||||||
  // value 做了转换,但 props.value 和原来 useField().value 的值不一致
 | 
					    const { getCollectionJoinField } = useCollectionManager();
 | 
				
			||||||
  // const field = useField<Field>();
 | 
					    // value 做了转换,但 props.value 和原来 useField().value 的值不一致
 | 
				
			||||||
  const fieldNames = useFieldNames(props);
 | 
					    // const field = useField<Field>();
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					    const fieldNames = useFieldNames(props);
 | 
				
			||||||
  const { getField } = useCollection();
 | 
					    const [visible, setVisible] = useState(false);
 | 
				
			||||||
  const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']);
 | 
					    const { getField } = useCollection();
 | 
				
			||||||
  const [record, setRecord] = useState({});
 | 
					    const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']);
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const [record, setRecord] = useState({});
 | 
				
			||||||
  const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
					    const compile = useCompile();
 | 
				
			||||||
  const showFilePicker = isShowFilePicker(labelUiSchema);
 | 
					    const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
 | 
				
			||||||
  const { snapshot } = useActionContext();
 | 
					    const showFilePicker = isShowFilePicker(labelUiSchema);
 | 
				
			||||||
  const isTagsMode = fieldSchema['x-component-props']?.mode === 'tags';
 | 
					    const { snapshot } = useActionContext();
 | 
				
			||||||
 | 
					    const isTagsMode = fieldSchema['x-component-props']?.mode === 'tags';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>();
 | 
					    const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (showFilePicker) {
 | 
					    if (showFilePicker) {
 | 
				
			||||||
    return collectionField ? <Preview {...props} /> : null;
 | 
					      return collectionField ? <Preview {...props} /> : null;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const renderRecords = () =>
 | 
					    const renderRecords = () =>
 | 
				
			||||||
    toArr(props.value).map((record, index, arr) => {
 | 
					      toArr(props.value).map((record, index, arr) => {
 | 
				
			||||||
      const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A');
 | 
					        const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A');
 | 
				
			||||||
      const text = getLabelFormatValue(labelUiSchema, val, true);
 | 
					        const text = getLabelFormatValue(labelUiSchema, val, true);
 | 
				
			||||||
      return (
 | 
					        return (
 | 
				
			||||||
        <Fragment key={`${record.id}_${index}`}>
 | 
					          <Fragment key={`${record.id}_${index}`}>
 | 
				
			||||||
          <span>
 | 
					            <span>
 | 
				
			||||||
            {snapshot || isTagsMode ? (
 | 
					              {snapshot || isTagsMode ? (
 | 
				
			||||||
              text
 | 
					                text
 | 
				
			||||||
            ) : (
 | 
					              ) : (
 | 
				
			||||||
              <a
 | 
					                <a
 | 
				
			||||||
                onClick={(e) => {
 | 
					                  onClick={(e) => {
 | 
				
			||||||
                  e.stopPropagation();
 | 
					                    e.stopPropagation();
 | 
				
			||||||
                  e.preventDefault();
 | 
					                    e.preventDefault();
 | 
				
			||||||
                  setVisible(true);
 | 
					                    setVisible(true);
 | 
				
			||||||
                  setRecord(record);
 | 
					                    setRecord(record);
 | 
				
			||||||
                  ellipsisWithTooltipRef?.current?.setPopoverVisible(false);
 | 
					                    ellipsisWithTooltipRef?.current?.setPopoverVisible(false);
 | 
				
			||||||
                }}
 | 
					                  }}
 | 
				
			||||||
              >
 | 
					                >
 | 
				
			||||||
                {text}
 | 
					                  {text}
 | 
				
			||||||
              </a>
 | 
					                </a>
 | 
				
			||||||
            )}
 | 
					              )}
 | 
				
			||||||
          </span>
 | 
					            </span>
 | 
				
			||||||
          {index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>,</span> : null}
 | 
					            {index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>,</span> : null}
 | 
				
			||||||
        </Fragment>
 | 
					          </Fragment>
 | 
				
			||||||
      );
 | 
					        );
 | 
				
			||||||
    });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const renderWithoutTableFieldResourceProvider = () => (
 | 
					    const renderWithoutTableFieldResourceProvider = () => (
 | 
				
			||||||
    <WithoutTableFieldResource.Provider value={true}>
 | 
					      <WithoutTableFieldResource.Provider value={true}>
 | 
				
			||||||
      <FormProvider>
 | 
					        <FormProvider>
 | 
				
			||||||
        <RecursionField
 | 
					          <RecursionField
 | 
				
			||||||
          schema={fieldSchema}
 | 
					            schema={fieldSchema}
 | 
				
			||||||
          onlyRenderProperties
 | 
					            onlyRenderProperties
 | 
				
			||||||
          filterProperties={(s) => {
 | 
					            filterProperties={(s) => {
 | 
				
			||||||
            return s['x-component'] === 'RecordPicker.Viewer';
 | 
					              return s['x-component'] === 'RecordPicker.Viewer';
 | 
				
			||||||
          }}
 | 
					            }}
 | 
				
			||||||
        />
 | 
					          />
 | 
				
			||||||
      </FormProvider>
 | 
					        </FormProvider>
 | 
				
			||||||
    </WithoutTableFieldResource.Provider>
 | 
					      </WithoutTableFieldResource.Provider>
 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const renderRecordProvider = () => {
 | 
					 | 
				
			||||||
    const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return collectionFieldNames && collectionFieldNames.length > 2 ? (
 | 
					 | 
				
			||||||
      <RecordProvider record={recordCtx[collectionFieldNames[1]]}>
 | 
					 | 
				
			||||||
        <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
					 | 
				
			||||||
      </RecordProvider>
 | 
					 | 
				
			||||||
    ) : (
 | 
					 | 
				
			||||||
      <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return collectionField ? (
 | 
					    const renderRecordProvider = () => {
 | 
				
			||||||
    <div>
 | 
					      const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.');
 | 
				
			||||||
      <BlockAssociationContext.Provider value={`${collectionField.collectionName}.${collectionField.name}`}>
 | 
					
 | 
				
			||||||
        <CollectionProvider name={collectionField.target ?? collectionField.targetCollection}>
 | 
					      return collectionFieldNames && collectionFieldNames.length > 2 ? (
 | 
				
			||||||
          <EllipsisWithTooltip ellipsis={ellipsis} ref={ellipsisWithTooltipRef}>
 | 
					        <RecordProvider record={recordCtx[collectionFieldNames[1]]}>
 | 
				
			||||||
            {renderRecords()}
 | 
					          <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
				
			||||||
          </EllipsisWithTooltip>
 | 
					        </RecordProvider>
 | 
				
			||||||
          <ActionContext.Provider
 | 
					      ) : (
 | 
				
			||||||
            value={{ visible, setVisible, openMode: 'drawer', snapshot: collectionField.interface === 'snapshot' }}
 | 
					        <RecordProvider record={record}>{renderWithoutTableFieldResourceProvider()}</RecordProvider>
 | 
				
			||||||
          >
 | 
					      );
 | 
				
			||||||
            {renderRecordProvider()}
 | 
					    };
 | 
				
			||||||
          </ActionContext.Provider>
 | 
					
 | 
				
			||||||
        </CollectionProvider>
 | 
					    return collectionField ? (
 | 
				
			||||||
      </BlockAssociationContext.Provider>
 | 
					      <div>
 | 
				
			||||||
    </div>
 | 
					        <BlockAssociationContext.Provider value={`${collectionField.collectionName}.${collectionField.name}`}>
 | 
				
			||||||
  ) : null;
 | 
					          <CollectionProvider name={collectionField.target ?? collectionField.targetCollection}>
 | 
				
			||||||
});
 | 
					            <EllipsisWithTooltip ellipsis={ellipsis} ref={ellipsisWithTooltipRef}>
 | 
				
			||||||
 | 
					              {renderRecords()}
 | 
				
			||||||
 | 
					            </EllipsisWithTooltip>
 | 
				
			||||||
 | 
					            <ActionContext.Provider
 | 
				
			||||||
 | 
					              value={{ visible, setVisible, openMode: 'drawer', snapshot: collectionField.interface === 'snapshot' }}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              {renderRecordProvider()}
 | 
				
			||||||
 | 
					            </ActionContext.Provider>
 | 
				
			||||||
 | 
					          </CollectionProvider>
 | 
				
			||||||
 | 
					        </BlockAssociationContext.Provider>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    ) : null;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPrettyRecordPicker' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,19 +6,20 @@ import { useRequest } from '../../../api-client';
 | 
				
			|||||||
import { useRecord } from '../../../record-provider';
 | 
					import { useRecord } from '../../../record-provider';
 | 
				
			||||||
import { useActionContext } from '../action';
 | 
					import { useActionContext } from '../action';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReadPretty = observer((props: any) => {
 | 
					export const ReadPretty = observer(
 | 
				
			||||||
  const fieldNames = { ...defaultFieldNames, ...props.fieldNames };
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<any>();
 | 
					    const fieldNames = { ...defaultFieldNames, ...props.fieldNames };
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField<any>();
 | 
				
			||||||
  const record = useRecord();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const { snapshot } = useActionContext();
 | 
					    const record = useRecord();
 | 
				
			||||||
 | 
					    const { snapshot } = useActionContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { data } = useRequest(
 | 
					    const { data } = useRequest(
 | 
				
			||||||
    snapshot
 | 
					      snapshot
 | 
				
			||||||
      ? async () => ({
 | 
					        ? async () => ({
 | 
				
			||||||
          data: record[fieldSchema.name],
 | 
					          data: record[fieldSchema.name],
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      : {
 | 
					        : {
 | 
				
			||||||
          action: 'list',
 | 
					          action: 'list',
 | 
				
			||||||
          ...props.service,
 | 
					          ...props.service,
 | 
				
			||||||
          params: {
 | 
					          params: {
 | 
				
			||||||
@ -30,10 +31,12 @@ export const ReadPretty = observer((props: any) => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    {
 | 
					      {
 | 
				
			||||||
      refreshDeps: [props.service, field.value],
 | 
					        refreshDeps: [props.service, field.value],
 | 
				
			||||||
    },
 | 
					      },
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Select.ReadPretty {...props} options={data?.data}></Select.ReadPretty>;
 | 
					    return <Select.ReadPretty {...props} options={data?.data}></Select.ReadPretty>;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPretty' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -12,29 +12,32 @@ type Composed = {
 | 
				
			|||||||
  Object?: React.FC<any>;
 | 
					  Object?: React.FC<any>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReadPretty = observer((props: any) => {
 | 
					export const ReadPretty = observer(
 | 
				
			||||||
  const fieldNames = { ...defaultFieldNames, ...props.fieldNames };
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<any>();
 | 
					    const fieldNames = { ...defaultFieldNames, ...props.fieldNames };
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const field = useField<any>();
 | 
				
			||||||
 | 
					    const compile = useCompile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!isValid(props.value)) {
 | 
					    if (!isValid(props.value)) {
 | 
				
			||||||
    return <div />;
 | 
					      return <div />;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
  if (isArrayField(field) && field?.value?.length === 0) {
 | 
					    if (isArrayField(field) && field?.value?.length === 0) {
 | 
				
			||||||
    return <div />;
 | 
					      return <div />;
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
  const dataSource = field.dataSource || props.options || [];
 | 
					    const dataSource = field.dataSource || props.options || [];
 | 
				
			||||||
  const options = getCurrentOptions(field.value, dataSource, fieldNames);
 | 
					    const options = getCurrentOptions(field.value, dataSource, fieldNames);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div>
 | 
					      <div>
 | 
				
			||||||
      <EllipsisWithTooltip ellipsis={props.ellipsis}>
 | 
					        <EllipsisWithTooltip ellipsis={props.ellipsis}>
 | 
				
			||||||
        {options.map((option, key) => (
 | 
					          {options.map((option, key) => (
 | 
				
			||||||
          <Tag key={key} color={option[fieldNames.color]} icon={option.icon}>
 | 
					            <Tag key={key} color={option[fieldNames.color]} icon={option.icon}>
 | 
				
			||||||
            {compile(option[fieldNames.label])}
 | 
					              {compile(option[fieldNames.label])}
 | 
				
			||||||
          </Tag>
 | 
					            </Tag>
 | 
				
			||||||
        ))}
 | 
					          ))}
 | 
				
			||||||
      </EllipsisWithTooltip>
 | 
					        </EllipsisWithTooltip>
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ReadPretty' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -42,12 +42,15 @@ export const designerCss = css`
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableColumnActionBar = observer((props) => {
 | 
					export const TableColumnActionBar = observer(
 | 
				
			||||||
  const Designer = useDesigner();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const Designer = useDesigner();
 | 
				
			||||||
    <SortableItem className={designerCss}>
 | 
					    return (
 | 
				
			||||||
      <Designer />
 | 
					      <SortableItem className={designerCss}>
 | 
				
			||||||
      {props.children}
 | 
					        <Designer />
 | 
				
			||||||
    </SortableItem>
 | 
					        {props.children}
 | 
				
			||||||
  );
 | 
					      </SortableItem>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableColumnActionBar' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -163,164 +163,165 @@ const useValidator = (validator: (value: any) => string) => {
 | 
				
			|||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Table: any = observer((props: any) => {
 | 
					export const Table: any = observer(
 | 
				
			||||||
  const { pagination: pagination1, useProps, onChange, ...others1 } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const { pagination: pagination2, onClickRow, ...others2 } = useProps?.() || {};
 | 
					    const { pagination: pagination1, useProps, onChange, ...others1 } = props;
 | 
				
			||||||
  const {
 | 
					    const { pagination: pagination2, onClickRow, ...others2 } = useProps?.() || {};
 | 
				
			||||||
    dragSort = false,
 | 
					    const {
 | 
				
			||||||
    showIndex = true,
 | 
					      dragSort = false,
 | 
				
			||||||
    onRowSelectionChange,
 | 
					      showIndex = true,
 | 
				
			||||||
    onChange: onTableChange,
 | 
					      onRowSelectionChange,
 | 
				
			||||||
    rowSelection,
 | 
					      onChange: onTableChange,
 | 
				
			||||||
    rowKey,
 | 
					      rowSelection,
 | 
				
			||||||
    required,
 | 
					      rowKey,
 | 
				
			||||||
    onExpand,
 | 
					      required,
 | 
				
			||||||
    ...others
 | 
					      onExpand,
 | 
				
			||||||
  } = { ...others1, ...others2 } as any;
 | 
					      ...others
 | 
				
			||||||
  const field = useArrayField(others);
 | 
					    } = { ...others1, ...others2 } as any;
 | 
				
			||||||
  const columns = useTableColumns(others);
 | 
					    const field = useArrayField(others);
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const columns = useTableColumns(others);
 | 
				
			||||||
  const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider';
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
  const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext();
 | 
					    const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider';
 | 
				
			||||||
  const { expandFlag } = ctx;
 | 
					    const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext();
 | 
				
			||||||
  const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {}));
 | 
					    const { expandFlag } = ctx;
 | 
				
			||||||
  const paginationProps = usePaginationProps(pagination1, pagination2);
 | 
					    const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => { }));
 | 
				
			||||||
  const requiredValidator = field.required || required;
 | 
					    const paginationProps = usePaginationProps(pagination1, pagination2);
 | 
				
			||||||
  const { treeTable } = schema?.parent?.['x-decorator-props'] || {};
 | 
					    const requiredValidator = field.required || required;
 | 
				
			||||||
  const [expandedKeys, setExpandesKeys] = useState([]);
 | 
					    const { treeTable } = schema?.parent?.['x-decorator-props'] || {};
 | 
				
			||||||
  const [allIncludesChildren, setAllIncludesChildren] = useState([]);
 | 
					    const [expandedKeys, setExpandesKeys] = useState([]);
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>(field?.data?.selectedRowKeys || []);
 | 
					    const [allIncludesChildren, setAllIncludesChildren] = useState([]);
 | 
				
			||||||
  const [selectedRow, setSelectedRow] = useState([]);
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>(field?.data?.selectedRowKeys || []);
 | 
				
			||||||
 | 
					    const [selectedRow, setSelectedRow] = useState([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let onRow = null,
 | 
					    let onRow = null,
 | 
				
			||||||
    highlightRow = '';
 | 
					      highlightRow = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (onClickRow) {
 | 
					    if (onClickRow) {
 | 
				
			||||||
    onRow = (record) => {
 | 
					      onRow = (record) => {
 | 
				
			||||||
      return {
 | 
					        return {
 | 
				
			||||||
        onClick: () => onClickRow(record, setSelectedRow, selectedRow),
 | 
					          onClick: () => onClickRow(record, setSelectedRow, selectedRow),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    };
 | 
					      highlightRow = css`
 | 
				
			||||||
    highlightRow = css`
 | 
					        & > td {
 | 
				
			||||||
      & > td {
 | 
					          background-color: #caedff !important;
 | 
				
			||||||
        background-color: #caedff !important;
 | 
					        }
 | 
				
			||||||
      }
 | 
					        &:hover > td {
 | 
				
			||||||
      &:hover > td {
 | 
					          background-color: #caedff !important;
 | 
				
			||||||
        background-color: #caedff !important;
 | 
					        }
 | 
				
			||||||
      }
 | 
					      `;
 | 
				
			||||||
    `;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    field.setValidator((value) => {
 | 
					 | 
				
			||||||
      if (requiredValidator) {
 | 
					 | 
				
			||||||
        return Array.isArray(value) && value.length > 0 ? null : 'The field value is required';
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }, [requiredValidator]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    if (treeTable !== false) {
 | 
					 | 
				
			||||||
      const keys = getIdsWithChildren(field.value?.slice?.());
 | 
					 | 
				
			||||||
      setAllIncludesChildren(keys);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }, [field.value]);
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    if (expandFlag) {
 | 
					 | 
				
			||||||
      setExpandesKeys(allIncludesChildren);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      setExpandesKeys([]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }, [expandFlag, allIncludesChildren]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const components = useMemo(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
    return {
 | 
					      field.setValidator((value) => {
 | 
				
			||||||
      header: {
 | 
					        if (requiredValidator) {
 | 
				
			||||||
        wrapper: (props) => {
 | 
					          return Array.isArray(value) && value.length > 0 ? null : 'The field value is required';
 | 
				
			||||||
          return (
 | 
					        }
 | 
				
			||||||
            <DndContext>
 | 
					        return;
 | 
				
			||||||
              <thead {...props} />
 | 
					      });
 | 
				
			||||||
            </DndContext>
 | 
					    }, [requiredValidator]);
 | 
				
			||||||
          );
 | 
					
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					      if (treeTable !== false) {
 | 
				
			||||||
 | 
					        const keys = getIdsWithChildren(field.value?.slice?.());
 | 
				
			||||||
 | 
					        setAllIncludesChildren(keys);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }, [field.value]);
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					      if (expandFlag) {
 | 
				
			||||||
 | 
					        setExpandesKeys(allIncludesChildren);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        setExpandesKeys([]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }, [expandFlag, allIncludesChildren]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const components = useMemo(() => {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        header: {
 | 
				
			||||||
 | 
					          wrapper: (props) => {
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					              <DndContext>
 | 
				
			||||||
 | 
					                <thead {...props} />
 | 
				
			||||||
 | 
					              </DndContext>
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          cell: (props) => {
 | 
				
			||||||
 | 
					            return (
 | 
				
			||||||
 | 
					              <th
 | 
				
			||||||
 | 
					                {...props}
 | 
				
			||||||
 | 
					                className={cls(
 | 
				
			||||||
 | 
					                  props.className,
 | 
				
			||||||
 | 
					                  css`
 | 
				
			||||||
 | 
					                    max-width: 300px;
 | 
				
			||||||
 | 
					                    white-space: nowrap;
 | 
				
			||||||
 | 
					                    &:hover .general-schema-designer {
 | 
				
			||||||
 | 
					                      display: block;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  `,
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        cell: (props) => {
 | 
					        body: {
 | 
				
			||||||
          return (
 | 
					          wrapper: (props) => {
 | 
				
			||||||
            <th
 | 
					            return (
 | 
				
			||||||
 | 
					              <DndContext
 | 
				
			||||||
 | 
					                onDragEnd={(e) => {
 | 
				
			||||||
 | 
					                  if (!e.active || !e.over) {
 | 
				
			||||||
 | 
					                    console.warn('move cancel');
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  const fromIndex = e.active?.data.current?.sortable?.index;
 | 
				
			||||||
 | 
					                  const toIndex = e.over?.data.current?.sortable?.index;
 | 
				
			||||||
 | 
					                  const from = field.value[fromIndex];
 | 
				
			||||||
 | 
					                  const to = field.value[toIndex];
 | 
				
			||||||
 | 
					                  field.move(fromIndex, toIndex);
 | 
				
			||||||
 | 
					                  onRowDragEnd({ fromIndex, toIndex, from, to });
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <tbody {...props} />
 | 
				
			||||||
 | 
					              </DndContext>
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          row: (props) => {
 | 
				
			||||||
 | 
					            return <SortableRow {...props}></SortableRow>;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          cell: (props) => (
 | 
				
			||||||
 | 
					            <td
 | 
				
			||||||
              {...props}
 | 
					              {...props}
 | 
				
			||||||
              className={cls(
 | 
					              className={classNames(
 | 
				
			||||||
                props.className,
 | 
					                props.className,
 | 
				
			||||||
                css`
 | 
					                css`
 | 
				
			||||||
                  max-width: 300px;
 | 
					                  max-width: 300px;
 | 
				
			||||||
                  white-space: nowrap;
 | 
					                  white-space: nowrap;
 | 
				
			||||||
                  &:hover .general-schema-designer {
 | 
					                  .nb-read-pretty-input-number {
 | 
				
			||||||
                    display: block;
 | 
					                    text-align: right;
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                `,
 | 
					                `,
 | 
				
			||||||
              )}
 | 
					              )}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          );
 | 
					          ),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      };
 | 
				
			||||||
      body: {
 | 
					    }, [field, onRowDragEnd, dragSort]);
 | 
				
			||||||
        wrapper: (props) => {
 | 
					 | 
				
			||||||
          return (
 | 
					 | 
				
			||||||
            <DndContext
 | 
					 | 
				
			||||||
              onDragEnd={(e) => {
 | 
					 | 
				
			||||||
                if (!e.active || !e.over) {
 | 
					 | 
				
			||||||
                  console.warn('move cancel');
 | 
					 | 
				
			||||||
                  return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const fromIndex = e.active?.data.current?.sortable?.index;
 | 
					    const defaultRowKey = (record: any) => {
 | 
				
			||||||
                const toIndex = e.over?.data.current?.sortable?.index;
 | 
					      return field.value?.indexOf?.(record);
 | 
				
			||||||
                const from = field.value[fromIndex];
 | 
					 | 
				
			||||||
                const to = field.value[toIndex];
 | 
					 | 
				
			||||||
                field.move(fromIndex, toIndex);
 | 
					 | 
				
			||||||
                onRowDragEnd({ fromIndex, toIndex, from, to });
 | 
					 | 
				
			||||||
              }}
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
              <tbody {...props} />
 | 
					 | 
				
			||||||
            </DndContext>
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        row: (props) => {
 | 
					 | 
				
			||||||
          return <SortableRow {...props}></SortableRow>;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        cell: (props) => (
 | 
					 | 
				
			||||||
          <td
 | 
					 | 
				
			||||||
            {...props}
 | 
					 | 
				
			||||||
            className={classNames(
 | 
					 | 
				
			||||||
              props.className,
 | 
					 | 
				
			||||||
              css`
 | 
					 | 
				
			||||||
                max-width: 300px;
 | 
					 | 
				
			||||||
                white-space: nowrap;
 | 
					 | 
				
			||||||
                .nb-read-pretty-input-number {
 | 
					 | 
				
			||||||
                  text-align: right;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              `,
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }, [field, onRowDragEnd, dragSort]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const defaultRowKey = (record: any) => {
 | 
					    const getRowKey = (record: any) => {
 | 
				
			||||||
    return field.value?.indexOf?.(record);
 | 
					      if (typeof rowKey === 'string') {
 | 
				
			||||||
  };
 | 
					        return record[rowKey]?.toString();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return (rowKey ?? defaultRowKey)(record)?.toString();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const getRowKey = (record: any) => {
 | 
					    const restProps = {
 | 
				
			||||||
    if (typeof rowKey === 'string') {
 | 
					      rowSelection: rowSelection
 | 
				
			||||||
      return record[rowKey]?.toString();
 | 
					        ? {
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return (rowKey ?? defaultRowKey)(record)?.toString();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const restProps = {
 | 
					 | 
				
			||||||
    rowSelection: rowSelection
 | 
					 | 
				
			||||||
      ? {
 | 
					 | 
				
			||||||
          type: 'checkbox',
 | 
					          type: 'checkbox',
 | 
				
			||||||
          selectedRowKeys: selectedRowKeys,
 | 
					          selectedRowKeys: selectedRowKeys,
 | 
				
			||||||
          onChange(selectedRowKeys: any[], selectedRows: any[]) {
 | 
					          onChange(selectedRowKeys: any[], selectedRows: any[]) {
 | 
				
			||||||
@ -348,40 +349,40 @@ export const Table: any = observer((props: any) => {
 | 
				
			|||||||
                className={classNames(
 | 
					                className={classNames(
 | 
				
			||||||
                  checked ? 'checked' : null,
 | 
					                  checked ? 'checked' : null,
 | 
				
			||||||
                  css`
 | 
					                  css`
 | 
				
			||||||
                    position: relative;
 | 
					                      position: relative;
 | 
				
			||||||
                    display: flex;
 | 
					                      display: flex;
 | 
				
			||||||
                    float: left;
 | 
					                      float: left;
 | 
				
			||||||
                    align-items: center;
 | 
					                      align-items: center;
 | 
				
			||||||
                    justify-content: space-evenly;
 | 
					                      justify-content: space-evenly;
 | 
				
			||||||
                    padding-right: 8px;
 | 
					                      padding-right: 8px;
 | 
				
			||||||
                    .nb-table-index {
 | 
					 | 
				
			||||||
                      opacity: 0;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    &:not(.checked) {
 | 
					 | 
				
			||||||
                      .nb-table-index {
 | 
					 | 
				
			||||||
                        opacity: 1;
 | 
					 | 
				
			||||||
                      }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    &:hover {
 | 
					 | 
				
			||||||
                      .nb-table-index {
 | 
					                      .nb-table-index {
 | 
				
			||||||
                        opacity: 0;
 | 
					                        opacity: 0;
 | 
				
			||||||
                      }
 | 
					                      }
 | 
				
			||||||
                      .nb-origin-node {
 | 
					                      &:not(.checked) {
 | 
				
			||||||
                        display: block;
 | 
					                        .nb-table-index {
 | 
				
			||||||
 | 
					                          opacity: 1;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                      }
 | 
					                      }
 | 
				
			||||||
                    }
 | 
					                      &:hover {
 | 
				
			||||||
                  `,
 | 
					                        .nb-table-index {
 | 
				
			||||||
 | 
					                          opacity: 0;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        .nb-origin-node {
 | 
				
			||||||
 | 
					                          display: block;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    `,
 | 
				
			||||||
                )}
 | 
					                )}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <div
 | 
					                <div
 | 
				
			||||||
                  className={classNames(
 | 
					                  className={classNames(
 | 
				
			||||||
                    checked ? 'checked' : null,
 | 
					                    checked ? 'checked' : null,
 | 
				
			||||||
                    css`
 | 
					                    css`
 | 
				
			||||||
                      position: relative;
 | 
					                        position: relative;
 | 
				
			||||||
                      display: flex;
 | 
					                        display: flex;
 | 
				
			||||||
                      align-items: center;
 | 
					                        align-items: center;
 | 
				
			||||||
                      justify-content: space-evenly;
 | 
					                        justify-content: space-evenly;
 | 
				
			||||||
                    `,
 | 
					                      `,
 | 
				
			||||||
                  )}
 | 
					                  )}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  {dragSort && <SortHandle id={getRowKey(record)} />}
 | 
					                  {dragSort && <SortHandle id={getRowKey(record)} />}
 | 
				
			||||||
@ -392,13 +393,13 @@ export const Table: any = observer((props: any) => {
 | 
				
			|||||||
                    'nb-origin-node',
 | 
					                    'nb-origin-node',
 | 
				
			||||||
                    checked ? 'checked' : null,
 | 
					                    checked ? 'checked' : null,
 | 
				
			||||||
                    css`
 | 
					                    css`
 | 
				
			||||||
                      position: absolute;
 | 
					                        position: absolute;
 | 
				
			||||||
                      right: 50%;
 | 
					                        right: 50%;
 | 
				
			||||||
                      transform: translateX(50%);
 | 
					                        transform: translateX(50%);
 | 
				
			||||||
                      &:not(.checked) {
 | 
					                        &:not(.checked) {
 | 
				
			||||||
                        display: none;
 | 
					                          display: none;
 | 
				
			||||||
                      }
 | 
					                        }
 | 
				
			||||||
                    `,
 | 
					                      `,
 | 
				
			||||||
                  )}
 | 
					                  )}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  {originNode}
 | 
					                  {originNode}
 | 
				
			||||||
@ -408,94 +409,96 @@ export const Table: any = observer((props: any) => {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          ...rowSelection,
 | 
					          ...rowSelection,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      : undefined,
 | 
					        : undefined,
 | 
				
			||||||
  };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const SortableWrapper = useCallback<React.FC>(
 | 
					    const SortableWrapper = useCallback<React.FC>(
 | 
				
			||||||
    ({ children }) => {
 | 
					      ({ children }) => {
 | 
				
			||||||
      return dragSort
 | 
					        return dragSort
 | 
				
			||||||
        ? React.createElement(SortableContext, {
 | 
					          ? React.createElement(SortableContext, {
 | 
				
			||||||
            items: field.value.map(getRowKey),
 | 
					            items: field.value.map(getRowKey),
 | 
				
			||||||
            children: children,
 | 
					            children: children,
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
        : React.createElement(React.Fragment, {
 | 
					          : React.createElement(React.Fragment, {
 | 
				
			||||||
            children,
 | 
					            children,
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
    },
 | 
					      },
 | 
				
			||||||
    [field, dragSort],
 | 
					      [field, dragSort],
 | 
				
			||||||
  );
 | 
					    );
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const fixedBlock = fieldSchema?.parent?.['x-decorator-props']?.fixedBlock;
 | 
					    const fixedBlock = fieldSchema?.parent?.['x-decorator-props']?.fixedBlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { height: tableHeight, tableSizeRefCallback } = useTableSize();
 | 
					    const { height: tableHeight, tableSizeRefCallback } = useTableSize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const scroll = useMemo(() => {
 | 
					    const scroll = useMemo(() => {
 | 
				
			||||||
    return fixedBlock
 | 
					      return fixedBlock
 | 
				
			||||||
      ? {
 | 
					        ? {
 | 
				
			||||||
          x: 'max-content',
 | 
					          x: 'max-content',
 | 
				
			||||||
          y: tableHeight,
 | 
					          y: tableHeight,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      : {
 | 
					        : {
 | 
				
			||||||
          x: 'max-content',
 | 
					          x: 'max-content',
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
  }, [fixedBlock, tableHeight]);
 | 
					    }, [fixedBlock, tableHeight]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div
 | 
					      <div
 | 
				
			||||||
      className={css`
 | 
					        className={css`
 | 
				
			||||||
        height: 100%;
 | 
					 | 
				
			||||||
        overflow: hidden;
 | 
					 | 
				
			||||||
        .ant-table-wrapper {
 | 
					 | 
				
			||||||
          height: 100%;
 | 
					          height: 100%;
 | 
				
			||||||
          .ant-spin-nested-loading {
 | 
					          overflow: hidden;
 | 
				
			||||||
 | 
					          .ant-table-wrapper {
 | 
				
			||||||
            height: 100%;
 | 
					            height: 100%;
 | 
				
			||||||
            .ant-spin-container {
 | 
					            .ant-spin-nested-loading {
 | 
				
			||||||
              height: 100%;
 | 
					              height: 100%;
 | 
				
			||||||
              display: flex;
 | 
					              .ant-spin-container {
 | 
				
			||||||
              flex-direction: column;
 | 
					                height: 100%;
 | 
				
			||||||
 | 
					                display: flex;
 | 
				
			||||||
 | 
					                flex-direction: column;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					          .ant-table {
 | 
				
			||||||
        .ant-table {
 | 
					            overflow-x: auto;
 | 
				
			||||||
          overflow-x: auto;
 | 
					            overflow-y: hidden;
 | 
				
			||||||
          overflow-y: hidden;
 | 
					          }
 | 
				
			||||||
        }
 | 
					        `}
 | 
				
			||||||
      `}
 | 
					      >
 | 
				
			||||||
    >
 | 
					        <SortableWrapper>
 | 
				
			||||||
      <SortableWrapper>
 | 
					          <AntdTable
 | 
				
			||||||
        <AntdTable
 | 
					            ref={tableSizeRefCallback}
 | 
				
			||||||
          ref={tableSizeRefCallback}
 | 
					            rowKey={rowKey ?? defaultRowKey}
 | 
				
			||||||
          rowKey={rowKey ?? defaultRowKey}
 | 
					            dataSource={field?.value?.slice?.()}
 | 
				
			||||||
          dataSource={field?.value?.slice?.()}
 | 
					            {...others}
 | 
				
			||||||
          {...others}
 | 
					            {...restProps}
 | 
				
			||||||
          {...restProps}
 | 
					            pagination={paginationProps}
 | 
				
			||||||
          pagination={paginationProps}
 | 
					            components={components}
 | 
				
			||||||
          components={components}
 | 
					            onChange={(pagination, filters, sorter, extra) => {
 | 
				
			||||||
          onChange={(pagination, filters, sorter, extra) => {
 | 
					              onTableChange?.(pagination, filters, sorter, extra);
 | 
				
			||||||
            onTableChange?.(pagination, filters, sorter, extra);
 | 
					            }}
 | 
				
			||||||
          }}
 | 
					            onRow={onRow}
 | 
				
			||||||
          onRow={onRow}
 | 
					            rowClassName={(record) => (selectedRow.includes(record[rowKey]) ? highlightRow : '')}
 | 
				
			||||||
          rowClassName={(record) => (selectedRow.includes(record[rowKey]) ? highlightRow : '')}
 | 
					            tableLayout={'auto'}
 | 
				
			||||||
          tableLayout={'auto'}
 | 
					            scroll={scroll}
 | 
				
			||||||
          scroll={scroll}
 | 
					            columns={columns}
 | 
				
			||||||
          columns={columns}
 | 
					            expandable={{
 | 
				
			||||||
          expandable={{
 | 
					              onExpand: (flag, record) => {
 | 
				
			||||||
            onExpand: (flag, record) => {
 | 
					                const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i);
 | 
				
			||||||
              const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i);
 | 
					                setExpandesKeys(newKeys);
 | 
				
			||||||
              setExpandesKeys(newKeys);
 | 
					                onExpand?.(flag, record);
 | 
				
			||||||
              onExpand?.(flag, record);
 | 
					              },
 | 
				
			||||||
            },
 | 
					              expandedRowKeys: expandedKeys,
 | 
				
			||||||
            expandedRowKeys: expandedKeys,
 | 
					            }}
 | 
				
			||||||
          }}
 | 
					          />
 | 
				
			||||||
        />
 | 
					        </SortableWrapper>
 | 
				
			||||||
      </SortableWrapper>
 | 
					        {field.errors.length > 0 && (
 | 
				
			||||||
      {field.errors.length > 0 && (
 | 
					          <div className="ant-formily-item-error-help ant-formily-item-help ant-formily-item-help-enter ant-formily-item-help-enter-active">
 | 
				
			||||||
        <div className="ant-formily-item-error-help ant-formily-item-help ant-formily-item-help-enter ant-formily-item-help-enter-active">
 | 
					            {field.errors.map((error) => {
 | 
				
			||||||
          {field.errors.map((error) => {
 | 
					              return error.messages.map((message) => <div>{message}</div>);
 | 
				
			||||||
            return error.messages.map((message) => <div>{message}</div>);
 | 
					            })}
 | 
				
			||||||
          })}
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        )}
 | 
				
			||||||
      )}
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'Table' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,36 +6,42 @@ import { useCollection } from '../../../collection-manager';
 | 
				
			|||||||
import { useCompile } from '../../hooks';
 | 
					import { useCompile } from '../../hooks';
 | 
				
			||||||
import { ActionBar } from '../action';
 | 
					import { ActionBar } from '../action';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableField: any = observer((props) => {
 | 
					export const TableField: any = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props) => {
 | 
				
			||||||
  const { getField } = useCollection();
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { getField } = useCollection();
 | 
				
			||||||
  const collectionField = getField(fieldSchema.name);
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const compile = useCompile();
 | 
					    const collectionField = getField(fieldSchema.name);
 | 
				
			||||||
  const ctx = useFormBlockContext();
 | 
					    const compile = useCompile();
 | 
				
			||||||
  useEffect(() => {
 | 
					    const ctx = useFormBlockContext();
 | 
				
			||||||
    if (!field.title) {
 | 
					    useEffect(() => {
 | 
				
			||||||
      field.title = compile(collectionField?.uiSchema?.title);
 | 
					      if (!field.title) {
 | 
				
			||||||
    }
 | 
					        field.title = compile(collectionField?.uiSchema?.title);
 | 
				
			||||||
    if (ctx?.field) {
 | 
					      }
 | 
				
			||||||
      ctx.field.added = ctx.field.added || new Set();
 | 
					      if (ctx?.field) {
 | 
				
			||||||
      ctx.field.added.add(fieldSchema.name);
 | 
					        ctx.field.added = ctx.field.added || new Set();
 | 
				
			||||||
    }
 | 
					        ctx.field.added.add(fieldSchema.name);
 | 
				
			||||||
  }, []);
 | 
					      }
 | 
				
			||||||
  useEffect(() => {
 | 
					    }, []);
 | 
				
			||||||
    field.decoratorProps.asterisk = fieldSchema.required;
 | 
					    useEffect(() => {
 | 
				
			||||||
  }, [fieldSchema.required]);
 | 
					      field.decoratorProps.asterisk = fieldSchema.required;
 | 
				
			||||||
  return <div>{props.children}</div>;
 | 
					    }, [fieldSchema.required]);
 | 
				
			||||||
});
 | 
					    return <div>{props.children}</div>;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableField' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TableField.ActionBar = observer((props) => {
 | 
					TableField.ActionBar = observer(
 | 
				
			||||||
  const form = useForm();
 | 
					  (props) => {
 | 
				
			||||||
  if (form.readPretty) {
 | 
					    const form = useForm();
 | 
				
			||||||
    return null;
 | 
					    if (form.readPretty) {
 | 
				
			||||||
  }
 | 
					      return null;
 | 
				
			||||||
  return (
 | 
					    }
 | 
				
			||||||
    <div style={{ marginBottom: 8, marginTop: -32 }}>
 | 
					    return (
 | 
				
			||||||
      <ActionBar {...props} />
 | 
					      <div style={{ marginBottom: 8, marginTop: -32 }}>
 | 
				
			||||||
    </div>
 | 
					        <ActionBar {...props} />
 | 
				
			||||||
  );
 | 
					      </div>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableField.ActionBar' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
 | 
				
			|||||||
import { Table, TableColumnType } from 'antd';
 | 
					import { Table, TableColumnType } from 'antd';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ArrayTable = observer((props: any) => {
 | 
					const ArrayTable = observer(
 | 
				
			||||||
  const { rowKey } = props;
 | 
					  (props: any) => {
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					    const { rowKey } = props;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
					    const schema = useFieldSchema();
 | 
				
			||||||
    if (s['x-component'] === 'ArrayTable.Column') {
 | 
					    const columnSchemas = schema.reduceProperties((buf, s) => {
 | 
				
			||||||
      buf.push(s);
 | 
					      if (s['x-component'] === 'ArrayTable.Column') {
 | 
				
			||||||
    }
 | 
					        buf.push(s);
 | 
				
			||||||
    return buf;
 | 
					      }
 | 
				
			||||||
  }, []);
 | 
					      return buf;
 | 
				
			||||||
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const columns = columnSchemas.map((s) => {
 | 
					    const columns = columnSchemas.map((s) => {
 | 
				
			||||||
    return {
 | 
					      return {
 | 
				
			||||||
      render: (value, record) => {
 | 
					        render: (value, record) => {
 | 
				
			||||||
        return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
					          return <RecursionField name={record.__path} schema={s} onlyRenderProperties />;
 | 
				
			||||||
      },
 | 
					        },
 | 
				
			||||||
    } as TableColumnType<any>;
 | 
					      } as TableColumnType<any>;
 | 
				
			||||||
  });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Table {...props} rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
					    return <Table {...props} rowKey={rowKey} columns={columns} dataSource={field.value} />;
 | 
				
			||||||
});
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'ArrayTable' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Value = connect((props) => {
 | 
					const Value = connect((props) => {
 | 
				
			||||||
  return <li>value: {props.value}</li>;
 | 
					  return <li>value: {props.value}</li>;
 | 
				
			||||||
 | 
				
			|||||||
@ -151,28 +151,29 @@ const useDefAction = () => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableArray: React.FC<any> = observer((props) => {
 | 
					export const TableArray: React.FC<any> = observer(
 | 
				
			||||||
  const field = useField<ArrayField>();
 | 
					  (props) => {
 | 
				
			||||||
  const columns = useTableColumns();
 | 
					    const field = useField<ArrayField>();
 | 
				
			||||||
  const {
 | 
					    const columns = useTableColumns();
 | 
				
			||||||
    dragSort = false,
 | 
					    const {
 | 
				
			||||||
    showIndex = true,
 | 
					      dragSort = false,
 | 
				
			||||||
    useSelectedRowKeys = useDef,
 | 
					      showIndex = true,
 | 
				
			||||||
    useDataSource = useDefDataSource,
 | 
					      useSelectedRowKeys = useDef,
 | 
				
			||||||
    useAction = useDefAction,
 | 
					      useDataSource = useDefDataSource,
 | 
				
			||||||
    onChange,
 | 
					      useAction = useDefAction,
 | 
				
			||||||
    ...others
 | 
					      onChange,
 | 
				
			||||||
  } = props;
 | 
					      ...others
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
 | 
					    } = props;
 | 
				
			||||||
  useDataSource({
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
 | 
				
			||||||
    onSuccess(data) {
 | 
					    useDataSource({
 | 
				
			||||||
      field.value = data?.data || [];
 | 
					      onSuccess(data) {
 | 
				
			||||||
    },
 | 
					        field.value = data?.data || [];
 | 
				
			||||||
  });
 | 
					      },
 | 
				
			||||||
  const { move } = useAction();
 | 
					    });
 | 
				
			||||||
  const restProps = {
 | 
					    const { move } = useAction();
 | 
				
			||||||
    rowSelection: props.rowSelection
 | 
					    const restProps = {
 | 
				
			||||||
      ? {
 | 
					      rowSelection: props.rowSelection
 | 
				
			||||||
 | 
					        ? {
 | 
				
			||||||
          type: 'checkbox',
 | 
					          type: 'checkbox',
 | 
				
			||||||
          selectedRowKeys,
 | 
					          selectedRowKeys,
 | 
				
			||||||
          onChange(selectedRowKeys: any[]) {
 | 
					          onChange(selectedRowKeys: any[]) {
 | 
				
			||||||
@ -189,39 +190,39 @@ export const TableArray: React.FC<any> = observer((props) => {
 | 
				
			|||||||
                className={classNames(
 | 
					                className={classNames(
 | 
				
			||||||
                  checked ? 'checked' : null,
 | 
					                  checked ? 'checked' : null,
 | 
				
			||||||
                  css`
 | 
					                  css`
 | 
				
			||||||
                    position: relative;
 | 
					                      position: relative;
 | 
				
			||||||
                    display: flex;
 | 
					                      display: flex;
 | 
				
			||||||
                    align-items: center;
 | 
					                      align-items: center;
 | 
				
			||||||
                    justify-content: space-evenly;
 | 
					                      justify-content: space-evenly;
 | 
				
			||||||
                    padding-right: 8px;
 | 
					                      padding-right: 8px;
 | 
				
			||||||
                    .nb-table-index {
 | 
					 | 
				
			||||||
                      opacity: 0;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    &:not(.checked) {
 | 
					 | 
				
			||||||
                      .nb-table-index {
 | 
					 | 
				
			||||||
                        opacity: 1;
 | 
					 | 
				
			||||||
                      }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    &:hover {
 | 
					 | 
				
			||||||
                      .nb-table-index {
 | 
					                      .nb-table-index {
 | 
				
			||||||
                        opacity: 0;
 | 
					                        opacity: 0;
 | 
				
			||||||
                      }
 | 
					                      }
 | 
				
			||||||
                      .nb-origin-node {
 | 
					                      &:not(.checked) {
 | 
				
			||||||
                        display: block;
 | 
					                        .nb-table-index {
 | 
				
			||||||
 | 
					                          opacity: 1;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                      }
 | 
					                      }
 | 
				
			||||||
                    }
 | 
					                      &:hover {
 | 
				
			||||||
                  `,
 | 
					                        .nb-table-index {
 | 
				
			||||||
 | 
					                          opacity: 0;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        .nb-origin-node {
 | 
				
			||||||
 | 
					                          display: block;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    `,
 | 
				
			||||||
                )}
 | 
					                )}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                <div
 | 
					                <div
 | 
				
			||||||
                  className={classNames(
 | 
					                  className={classNames(
 | 
				
			||||||
                    checked ? 'checked' : null,
 | 
					                    checked ? 'checked' : null,
 | 
				
			||||||
                    css`
 | 
					                    css`
 | 
				
			||||||
                      position: relative;
 | 
					                        position: relative;
 | 
				
			||||||
                      display: flex;
 | 
					                        display: flex;
 | 
				
			||||||
                      align-items: center;
 | 
					                        align-items: center;
 | 
				
			||||||
                      justify-content: space-evenly;
 | 
					                        justify-content: space-evenly;
 | 
				
			||||||
                    `,
 | 
					                      `,
 | 
				
			||||||
                  )}
 | 
					                  )}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  {dragSort && <SortHandle />}
 | 
					                  {dragSort && <SortHandle />}
 | 
				
			||||||
@ -232,13 +233,13 @@ export const TableArray: React.FC<any> = observer((props) => {
 | 
				
			|||||||
                    'nb-origin-node',
 | 
					                    'nb-origin-node',
 | 
				
			||||||
                    checked ? 'checked' : null,
 | 
					                    checked ? 'checked' : null,
 | 
				
			||||||
                    css`
 | 
					                    css`
 | 
				
			||||||
                      position: absolute;
 | 
					                        position: absolute;
 | 
				
			||||||
                      right: 50%;
 | 
					                        right: 50%;
 | 
				
			||||||
                      transform: translateX(50%);
 | 
					                        transform: translateX(50%);
 | 
				
			||||||
                      &:not(.checked) {
 | 
					                        &:not(.checked) {
 | 
				
			||||||
                        display: none;
 | 
					                          display: none;
 | 
				
			||||||
                      }
 | 
					                        }
 | 
				
			||||||
                    `,
 | 
					                      `,
 | 
				
			||||||
                  )}
 | 
					                  )}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  {originNode}
 | 
					                  {originNode}
 | 
				
			||||||
@ -248,43 +249,45 @@ export const TableArray: React.FC<any> = observer((props) => {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          ...props.rowSelection,
 | 
					          ...props.rowSelection,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      : undefined,
 | 
					        : undefined,
 | 
				
			||||||
  };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const defaultRowKey = (record: any) => {
 | 
					    const defaultRowKey = (record: any) => {
 | 
				
			||||||
    return field.value?.indexOf?.(record);
 | 
					      return field.value?.indexOf?.(record);
 | 
				
			||||||
  };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					    return (
 | 
				
			||||||
    <div
 | 
					      <div
 | 
				
			||||||
      className={css`
 | 
					        className={css`
 | 
				
			||||||
        .ant-table {
 | 
					          .ant-table {
 | 
				
			||||||
          overflow-x: auto;
 | 
					            overflow-x: auto;
 | 
				
			||||||
          overflow-y: hidden;
 | 
					            overflow-y: hidden;
 | 
				
			||||||
        }
 | 
					          }
 | 
				
			||||||
      `}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <ReactDragListView
 | 
					 | 
				
			||||||
        handleSelector={'.drag-handle'}
 | 
					 | 
				
			||||||
        onDragEnd={async (fromIndex, toIndex) => {
 | 
					 | 
				
			||||||
          const from = field.value[fromIndex];
 | 
					 | 
				
			||||||
          const to = field.value[toIndex];
 | 
					 | 
				
			||||||
          field.move(fromIndex, toIndex);
 | 
					 | 
				
			||||||
          await move(from, to);
 | 
					 | 
				
			||||||
        }}
 | 
					 | 
				
			||||||
        lineClassName={css`
 | 
					 | 
				
			||||||
          border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important;
 | 
					 | 
				
			||||||
        `}
 | 
					        `}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <Table
 | 
					        <ReactDragListView
 | 
				
			||||||
          rowKey={defaultRowKey}
 | 
					          handleSelector={'.drag-handle'}
 | 
				
			||||||
          {...others}
 | 
					          onDragEnd={async (fromIndex, toIndex) => {
 | 
				
			||||||
          {...restProps}
 | 
					            const from = field.value[fromIndex];
 | 
				
			||||||
          components={components}
 | 
					            const to = field.value[toIndex];
 | 
				
			||||||
          columns={columns}
 | 
					            field.move(fromIndex, toIndex);
 | 
				
			||||||
          dataSource={field?.value?.slice?.()}
 | 
					            await move(from, to);
 | 
				
			||||||
        />
 | 
					          }}
 | 
				
			||||||
      </ReactDragListView>
 | 
					          lineClassName={css`
 | 
				
			||||||
    </div>
 | 
					            border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important;
 | 
				
			||||||
  );
 | 
					          `}
 | 
				
			||||||
});
 | 
					        >
 | 
				
			||||||
 | 
					          <Table
 | 
				
			||||||
 | 
					            rowKey={defaultRowKey}
 | 
				
			||||||
 | 
					            {...others}
 | 
				
			||||||
 | 
					            {...restProps}
 | 
				
			||||||
 | 
					            components={components}
 | 
				
			||||||
 | 
					            columns={columns}
 | 
				
			||||||
 | 
					            dataSource={field?.value?.slice?.()}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </ReactDragListView>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableArray' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -42,12 +42,15 @@ export const designerCss = css`
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableColumnActionBar = observer((props) => {
 | 
					export const TableColumnActionBar = observer(
 | 
				
			||||||
  const Designer = useDesigner();
 | 
					  (props) => {
 | 
				
			||||||
  return (
 | 
					    const Designer = useDesigner();
 | 
				
			||||||
    <SortableItem className={designerCss}>
 | 
					    return (
 | 
				
			||||||
      <Designer />
 | 
					      <SortableItem className={designerCss}>
 | 
				
			||||||
      {props.children}
 | 
					        <Designer />
 | 
				
			||||||
    </SortableItem>
 | 
					        {props.children}
 | 
				
			||||||
  );
 | 
					      </SortableItem>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableColumnActionBar' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -9,20 +9,23 @@ type Props = TableProps<any> & { value?: any; onChange?: any; objectValue?: bool
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const toArr = (value: any) => (isArr(value) ? value : isValid(value) ? [value] : []);
 | 
					const toArr = (value: any) => (isArr(value) ? value : isValid(value) ? [value] : []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableRowSelection = observer((props: Props) => {
 | 
					export const TableRowSelection = observer(
 | 
				
			||||||
  const { rowKey = 'id', objectValue } = props;
 | 
					  (props: Props) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { rowKey = 'id', objectValue } = props;
 | 
				
			||||||
  const rowSelection: any = {
 | 
					    const field = useField<Field>();
 | 
				
			||||||
    type: 'checkbox',
 | 
					    const rowSelection: any = {
 | 
				
			||||||
    ...props.rowSelection,
 | 
					      type: 'checkbox',
 | 
				
			||||||
    selectedRowKeys: toArr(field.value).map((val) => (typeof val === 'object' ? val[rowKey as any] : val)),
 | 
					      ...props.rowSelection,
 | 
				
			||||||
    onChange(selectedRowKeys: any[], selectedRows?: any) {
 | 
					      selectedRowKeys: toArr(field.value).map((val) => (typeof val === 'object' ? val[rowKey as any] : val)),
 | 
				
			||||||
      if (rowSelection.type === 'checkbox') {
 | 
					      onChange(selectedRowKeys: any[], selectedRows?: any) {
 | 
				
			||||||
        props.onChange(objectValue ? selectedRows : selectedRowKeys);
 | 
					        if (rowSelection.type === 'checkbox') {
 | 
				
			||||||
      } else {
 | 
					          props.onChange(objectValue ? selectedRows : selectedRowKeys);
 | 
				
			||||||
        props.onChange([...(objectValue ? selectedRows : selectedRowKeys)].shift());
 | 
					        } else {
 | 
				
			||||||
      }
 | 
					          props.onChange([...(objectValue ? selectedRows : selectedRowKeys)].shift());
 | 
				
			||||||
    },
 | 
					        }
 | 
				
			||||||
  };
 | 
					      },
 | 
				
			||||||
  return <TableVoid {...props} rowSelection={rowSelection} />;
 | 
					    };
 | 
				
			||||||
});
 | 
					    return <TableVoid {...props} rowSelection={rowSelection} />;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TableRowSelection' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -80,45 +80,48 @@ const useDefSelectedRowKeys = () => {
 | 
				
			|||||||
  return [result?.state?.selectedRowKeys, (selectedRowKeys) => result?.setState?.({ selectedRowKeys })];
 | 
					  return [result?.state?.selectedRowKeys, (selectedRowKeys) => result?.setState?.({ selectedRowKeys })];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TableVoid: React.FC<TableVoidProps> = observer((props) => {
 | 
					export const TableVoid: React.FC<TableVoidProps> = observer(
 | 
				
			||||||
  const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props;
 | 
					  (props) => {
 | 
				
			||||||
  const field = useField<Field>();
 | 
					    const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props;
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					    const field = useField<Field>();
 | 
				
			||||||
  const form = useMemo(() => createForm(), []);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  const f = useAttach(form.createArrayField({ ...field.props, basePath: '' }));
 | 
					    const form = useMemo(() => createForm(), []);
 | 
				
			||||||
  const result = useDataSource(
 | 
					    const f = useAttach(form.createArrayField({ ...field.props, basePath: '' }));
 | 
				
			||||||
    {
 | 
					    const result = useDataSource(
 | 
				
			||||||
      uid: fieldSchema['x-uid'],
 | 
					      {
 | 
				
			||||||
      onSuccess(data) {
 | 
					        uid: fieldSchema['x-uid'],
 | 
				
			||||||
        form.setValues({
 | 
					        onSuccess(data) {
 | 
				
			||||||
          [fieldSchema.name]: data?.data,
 | 
					          form.setValues({
 | 
				
			||||||
        });
 | 
					            [fieldSchema.name]: data?.data,
 | 
				
			||||||
        if (field?.componentProps?.pagination === false) {
 | 
					          });
 | 
				
			||||||
          return;
 | 
					          if (field?.componentProps?.pagination === false) {
 | 
				
			||||||
        }
 | 
					            return;
 | 
				
			||||||
        field.componentProps.pagination = field.componentProps.pagination || {};
 | 
					          }
 | 
				
			||||||
        if (data?.meta?.count) {
 | 
					          field.componentProps.pagination = field.componentProps.pagination || {};
 | 
				
			||||||
          field.componentProps.pagination.total = data?.meta?.count;
 | 
					          if (data?.meta?.count) {
 | 
				
			||||||
        }
 | 
					            field.componentProps.pagination.total = data?.meta?.count;
 | 
				
			||||||
        field.componentProps.pagination.current = data?.meta?.page || 1;
 | 
					          }
 | 
				
			||||||
        field.componentProps.pagination.pageSize = data?.meta?.pageSize || 10;
 | 
					          field.componentProps.pagination.current = data?.meta?.page || 1;
 | 
				
			||||||
 | 
					          field.componentProps.pagination.pageSize = data?.meta?.pageSize || 10;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      props,
 | 
				
			||||||
    props,
 | 
					    );
 | 
				
			||||||
  );
 | 
					    return (
 | 
				
			||||||
  return (
 | 
					      <AsyncDataProvider value={result}>
 | 
				
			||||||
    <AsyncDataProvider value={result}>
 | 
					        <FormContext.Provider value={form}>
 | 
				
			||||||
      <FormContext.Provider value={form}>
 | 
					          <FieldContext.Provider value={f}>
 | 
				
			||||||
        <FieldContext.Provider value={f}>
 | 
					            <TableArray
 | 
				
			||||||
          <TableArray
 | 
					              {...props}
 | 
				
			||||||
            {...props}
 | 
					              rowKey={rowKey}
 | 
				
			||||||
            rowKey={rowKey}
 | 
					              useSelectedRowKeys={useSelectedRowKeys}
 | 
				
			||||||
            useSelectedRowKeys={useSelectedRowKeys}
 | 
					              loading={result?.loading}
 | 
				
			||||||
            loading={result?.loading}
 | 
					              pagination={usePaginationProps(props, result)}
 | 
				
			||||||
            pagination={usePaginationProps(props, result)}
 | 
					            />
 | 
				
			||||||
          />
 | 
					          </FieldContext.Provider>
 | 
				
			||||||
        </FieldContext.Provider>
 | 
					        </FormContext.Provider>
 | 
				
			||||||
      </FormContext.Provider>
 | 
					      </AsyncDataProvider>
 | 
				
			||||||
    </AsyncDataProvider>
 | 
					    );
 | 
				
			||||||
  );
 | 
					  },
 | 
				
			||||||
});
 | 
					  { displayName: 'TableVoid' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -184,40 +184,43 @@ const schema: ISchema = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DataSourceProvider = observer((props) => {
 | 
					const DataSourceProvider = observer(
 | 
				
			||||||
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
					  (props) => {
 | 
				
			||||||
  const [dataSource, setDataSource] = useState([]);
 | 
					    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
 | 
				
			||||||
  const service = useRequest(
 | 
					    const [dataSource, setDataSource] = useState([]);
 | 
				
			||||||
    () => {
 | 
					    const service = useRequest(
 | 
				
			||||||
      return Promise.resolve({
 | 
					      () => {
 | 
				
			||||||
        data: [
 | 
					        return Promise.resolve({
 | 
				
			||||||
          { id: 1, name: 'Name1' },
 | 
					          data: [
 | 
				
			||||||
          { id: 2, name: 'Name2' },
 | 
					            { id: 1, name: 'Name1' },
 | 
				
			||||||
          { id: 3, name: 'Name3' },
 | 
					            { id: 2, name: 'Name2' },
 | 
				
			||||||
        ],
 | 
					            { id: 3, name: 'Name3' },
 | 
				
			||||||
      });
 | 
					          ],
 | 
				
			||||||
    },
 | 
					        });
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      onSuccess(data) {
 | 
					 | 
				
			||||||
        setDataSource(data.data);
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					      {
 | 
				
			||||||
  );
 | 
					        onSuccess(data) {
 | 
				
			||||||
  console.log('dataSource1', dataSource);
 | 
					          setDataSource(data.data);
 | 
				
			||||||
  return (
 | 
					        },
 | 
				
			||||||
    <DataSourceContext.Provider
 | 
					      },
 | 
				
			||||||
      value={{
 | 
					    );
 | 
				
			||||||
        service,
 | 
					    console.log('dataSource1', dataSource);
 | 
				
			||||||
        dataSource,
 | 
					    return (
 | 
				
			||||||
        setDataSource,
 | 
					      <DataSourceContext.Provider
 | 
				
			||||||
        selectedRowKeys,
 | 
					        value={{
 | 
				
			||||||
        setSelectedRowKeys,
 | 
					          service,
 | 
				
			||||||
      }}
 | 
					          dataSource,
 | 
				
			||||||
    >
 | 
					          setDataSource,
 | 
				
			||||||
      {props.children}
 | 
					          selectedRowKeys,
 | 
				
			||||||
    </DataSourceContext.Provider>
 | 
					          setSelectedRowKeys,
 | 
				
			||||||
  );
 | 
					        }}
 | 
				
			||||||
});
 | 
					      >
 | 
				
			||||||
 | 
					        {props.children}
 | 
				
			||||||
 | 
					      </DataSourceContext.Provider>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'DataSourceProvider' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -9,28 +9,31 @@ import { DndContext, SortableItem } from '../../common';
 | 
				
			|||||||
import { useDesigner } from '../../hooks/useDesigner';
 | 
					import { useDesigner } from '../../hooks/useDesigner';
 | 
				
			||||||
import { TabsDesigner } from './Tabs.Designer';
 | 
					import { TabsDesigner } from './Tabs.Designer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Tabs: any = observer((props: TabsProps) => {
 | 
					export const Tabs: any = observer(
 | 
				
			||||||
  const fieldSchema = useFieldSchema();
 | 
					  (props: TabsProps) => {
 | 
				
			||||||
  const { render } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
					    const fieldSchema = useFieldSchema();
 | 
				
			||||||
  return (
 | 
					    const { render } = useSchemaInitializer(fieldSchema['x-initializer']);
 | 
				
			||||||
    <DndContext>
 | 
					    return (
 | 
				
			||||||
      <AntdTabs
 | 
					      <DndContext>
 | 
				
			||||||
        style={props.style}
 | 
					        <AntdTabs
 | 
				
			||||||
        tabBarExtraContent={{
 | 
					          style={props.style}
 | 
				
			||||||
          right: render(),
 | 
					          tabBarExtraContent={{
 | 
				
			||||||
        }}
 | 
					            right: render(),
 | 
				
			||||||
      >
 | 
					          }}
 | 
				
			||||||
        {fieldSchema.mapProperties((schema, key) => {
 | 
					        >
 | 
				
			||||||
          return (
 | 
					          {fieldSchema.mapProperties((schema, key) => {
 | 
				
			||||||
            <AntdTabs.TabPane tab={<RecursionField name={key} schema={schema} onlyRenderSelf />} key={key}>
 | 
					            return (
 | 
				
			||||||
              <RecursionField name={key} schema={schema} onlyRenderProperties />
 | 
					              <AntdTabs.TabPane tab={<RecursionField name={key} schema={schema} onlyRenderSelf />} key={key}>
 | 
				
			||||||
            </AntdTabs.TabPane>
 | 
					                <RecursionField name={key} schema={schema} onlyRenderProperties />
 | 
				
			||||||
          );
 | 
					              </AntdTabs.TabPane>
 | 
				
			||||||
        })}
 | 
					            );
 | 
				
			||||||
      </AntdTabs>
 | 
					          })}
 | 
				
			||||||
    </DndContext>
 | 
					        </AntdTabs>
 | 
				
			||||||
  );
 | 
					      </DndContext>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'Tabs' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const designerCss = css`
 | 
					const designerCss = css`
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
@ -79,15 +82,18 @@ const designerCss = css`
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Tabs.TabPane = observer((props: TabPaneProps & { icon?: any }) => {
 | 
					Tabs.TabPane = observer(
 | 
				
			||||||
  const Designer = useDesigner();
 | 
					  (props: TabPaneProps & { icon?: any }) => {
 | 
				
			||||||
  const field = useField();
 | 
					    const Designer = useDesigner();
 | 
				
			||||||
  return (
 | 
					    const field = useField();
 | 
				
			||||||
    <SortableItem className={classNames('nb-action-link', designerCss, props.className)}>
 | 
					    return (
 | 
				
			||||||
      {props.icon && <Icon style={{ marginRight: 2 }} type={props.icon} />} {props.tab || field.title}
 | 
					      <SortableItem className={classNames('nb-action-link', designerCss, props.className)}>
 | 
				
			||||||
      <Designer />
 | 
					        {props.icon && <Icon style={{ marginRight: 2 }} type={props.icon} />} {props.tab || field.title}
 | 
				
			||||||
    </SortableItem>
 | 
					        <Designer />
 | 
				
			||||||
  );
 | 
					      </SortableItem>
 | 
				
			||||||
});
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { displayName: 'TabPane' },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Tabs.Designer = TabsDesigner;
 | 
					Tabs.Designer = TabsDesigner;
 | 
				
			||||||
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user