@jiangood/open-admin 3.1.0 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -59,7 +59,7 @@
59
59
  "test:e2e": "playwright test",
60
60
  "test:e2e:ui": "playwright test --ui"
61
61
  },
62
- "version": "3.1.0",
62
+ "version": "3.1.2",
63
63
  "overrides": {
64
64
  "zod-validation-error": "^4.0.2"
65
65
  }
@@ -0,0 +1,108 @@
1
+ import {Drawer, Form, FormInstance} from 'antd'
2
+ import React from 'react'
3
+
4
+ export interface FormDrawerProps {
5
+ title: string
6
+ onFinish?: (values: Record<string, unknown>) => Promise<void> | void
7
+ onValuesChange?: (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => void
8
+ width?: number
9
+ height?: number
10
+ placement?: 'left' | 'right' | 'top' | 'bottom'
11
+ layout?: 'horizontal' | 'vertical' | 'inline'
12
+ labelCol?: Record<string, unknown>
13
+ wrapperCol?: Record<string, unknown>
14
+ extra?: React.ReactNode
15
+ children?: React.ReactNode
16
+ }
17
+
18
+ export default class FormDrawer extends React.Component<FormDrawerProps> {
19
+
20
+ readonly state = {
21
+ visible: false,
22
+ confirmLoading: false,
23
+ }
24
+
25
+ private pendingValues: Record<string, unknown> | null = null
26
+ private formRef = React.createRef<FormInstance>()
27
+
28
+ get formInstance() {
29
+ return this.formRef.current
30
+ }
31
+
32
+ open = (values?: Record<string, unknown>) => {
33
+ this.pendingValues = values || {}
34
+ this.setState({visible: true})
35
+ }
36
+
37
+ componentDidUpdate(_: Readonly<FormDrawerProps>, prevState: Readonly<{ visible: boolean; confirmLoading: boolean }>) {
38
+ if (this.state.visible && !prevState.visible) {
39
+ setTimeout(() => {
40
+ if (this.pendingValues && Object.keys(this.pendingValues).length > 0) {
41
+ this.formRef.current?.setFieldsValue(this.pendingValues)
42
+ } else {
43
+ this.formRef.current?.resetFields()
44
+ }
45
+ this.pendingValues = null
46
+ })
47
+ }
48
+ }
49
+
50
+ private handleSubmit = async () => {
51
+ this.setState({confirmLoading: true})
52
+ try {
53
+ const values = await this.formRef.current?.validateFields()
54
+ if (values == null) return
55
+ await this.props.onFinish?.(values)
56
+ this.setState({visible: false})
57
+ } catch {
58
+ // 提交失败(错误提示已由 HttpClient 弹出),保持抽屉打开以便用户修改后重试
59
+ } finally {
60
+ this.setState({confirmLoading: false})
61
+ }
62
+ }
63
+
64
+ private footer = () => (
65
+ <div style={{textAlign: 'right'}}>
66
+ <button
67
+ type='button'
68
+ className='ant-btn ant-btn-default'
69
+ onClick={() => this.setState({visible: false})}
70
+ >
71
+ 取消
72
+ </button>
73
+ <button
74
+ type='button'
75
+ className='ant-btn ant-btn-primary'
76
+ style={{marginLeft: 8}}
77
+ disabled={this.state.confirmLoading}
78
+ onClick={this.handleSubmit}
79
+ >
80
+ {this.state.confirmLoading ? '提交中...' : '确定'}
81
+ </button>
82
+ </div>
83
+ )
84
+
85
+ render() {
86
+ return (
87
+ <Drawer
88
+ title={this.props.title}
89
+ open={this.state.visible}
90
+ onClose={() => this.setState({visible: false})}
91
+ destroyOnHidden
92
+ width={this.props.placement === 'top' || this.props.placement === 'bottom' ? undefined : (this.props.width ?? 600)}
93
+ height={this.props.placement === 'top' || this.props.placement === 'bottom' ? (this.props.height ?? 600) : undefined}
94
+ placement={this.props.placement ?? 'right'}
95
+ footer={this.footer()}
96
+ >
97
+ <Form ref={this.formRef}
98
+ layout={this.props.layout ?? 'vertical'}
99
+ labelCol={this.props.labelCol}
100
+ wrapperCol={this.props.wrapperCol}
101
+ onValuesChange={this.props.onValuesChange}>
102
+ <Form.Item name='id' noStyle/>
103
+ {this.props.children}
104
+ </Form>
105
+ </Drawer>
106
+ )
107
+ }
108
+ }
@@ -6,7 +6,9 @@ export interface FormModalProps {
6
6
  onFinish?: (values: Record<string, unknown>) => Promise<void> | void
7
7
  onValuesChange?: (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => void
8
8
  width?: number
9
+ layout?: 'horizontal' | 'vertical' | 'inline'
9
10
  labelCol?: Record<string, unknown>
11
+ wrapperCol?: Record<string, unknown>
10
12
  children?: React.ReactNode
11
13
  }
12
14
 
@@ -67,7 +69,10 @@ export default class FormModal extends React.Component<FormModalProps> { // NOSO
67
69
  destroyOnHidden
68
70
  width={this.props.width ?? 600}
69
71
  >
70
- <Form ref={this.formRef} labelCol={this.props.labelCol ?? {flex: '100px'}}
72
+ <Form ref={this.formRef}
73
+ layout={this.props.layout}
74
+ labelCol={this.props.layout ? undefined : (this.props.labelCol ?? {flex: '100px'})}
75
+ wrapperCol={this.props.wrapperCol}
71
76
  onValuesChange={this.props.onValuesChange}>
72
77
  <Form.Item name='id' noStyle/>
73
78
  {this.props.children}
@@ -1,4 +1,4 @@
1
- import {Input} from "antd";
1
+ import {Input, InputNumber, Switch} from "antd";
2
2
 
3
3
  import {ViewPassword, ViewBoolean, ViewImage, ViewText} from "../../views";
4
4
  import {FieldDictSelect, FieldRemoteSelect} from "../../fields";
@@ -6,6 +6,14 @@ import {FieldDictSelect, FieldRemoteSelect} from "../../fields";
6
6
 
7
7
  export const fieldRegistry = {
8
8
  'text':Input,
9
+ 'string': Input,
10
+
11
+ 'number': InputNumber,
12
+
13
+ 'boolean': Switch,
14
+
15
+ 'img': Input,
16
+ 'img_base64': Input,
9
17
 
10
18
  'dict':FieldDictSelect,
11
19
  'password':Input.Password,
@@ -10,3 +10,4 @@ export * from './DownloadModal'
10
10
  export * from './OrgSwitcher'
11
11
  export { default as ErrorBoundary } from './ErrorBoundary'
12
12
  export { default as FormModal } from './FormModal'
13
+ export { default as FormDrawer } from './DrawerForm'
@@ -231,8 +231,9 @@ export default class JobPage extends React.Component {
231
231
  name={['jobData', p.name]}
232
232
  key={p.name}
233
233
  initialValue={p.defaultValue}
234
+ valuePropName={p.valueType === 'boolean' ? 'checked' : 'value'}
234
235
  rules={[{required: p.required}]}>
235
- {ValueType.renderField(p.componentType, {
236
+ {ValueType.renderField(p.valueType, {
236
237
  ...p.componentProps,
237
238
  placeholder: p.placeholder || '请输入'
238
239
  })}
@@ -11,6 +11,7 @@ import {
11
11
  NamedIcon,
12
12
  Page,
13
13
  PermActions,
14
+ PermUtils,
14
15
  ViewSwitch,
15
16
  } from "../../../framework";
16
17
 
@@ -91,6 +92,7 @@ export default class OrgPage extends React.Component {
91
92
  render() {
92
93
  const {selectedOrg} = this.state
93
94
  const params = this.state.params
95
+ const canSort = PermUtils.hasPermission('sys-org:update')
94
96
 
95
97
  return <Page title="组织机构" description="管理组织机构树" actions={
96
98
  <Button type='primary' perm='sys-org:create' icon={<PlusOutlined/>} onClick={this.handleAdd}>新增</Button>
@@ -122,6 +124,7 @@ export default class OrgPage extends React.Component {
122
124
  <div>
123
125
  拖拽排序&nbsp;<Switch
124
126
  value={this.state.draggable}
127
+ disabled={!canSort}
125
128
  onChange={this.onDraggableChange}/>
126
129
  </div>
127
130
  <Button size='small' shape='round' icon={<SyncOutlined/>} onClick={this.loadTree}>刷新</Button>
@@ -224,6 +227,7 @@ export default class OrgPage extends React.Component {
224
227
  }
225
228
 
226
229
  onDrop = (e) => {
230
+ if (!PermUtils.hasPermission('sys-org:update')) return;
227
231
  const {dragNode, dropToGap, node} = e;
228
232
  const dropKey = node.key;
229
233
  const dragKey = dragNode.key;