@quansitech/antd-admin 1.0.0 → 1.1.0

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.
Files changed (41) hide show
  1. package/components/Column/Cascader.tsx +78 -78
  2. package/components/Column/File.tsx +165 -167
  3. package/components/Column/Image.tsx +76 -76
  4. package/components/{Table/Option → Column/Readonly/Action}/Link.tsx +77 -67
  5. package/components/{Table/Option → Column/Readonly/Action}/types.d.ts +5 -4
  6. package/components/Column/Readonly/Action.tsx +80 -0
  7. package/components/Column/Readonly/Cascader.tsx +50 -50
  8. package/components/Column/Readonly/File.tsx +52 -53
  9. package/components/Column/Readonly/Image.tsx +38 -77
  10. package/components/Column/Readonly/Ueditor.tsx +18 -0
  11. package/components/Column/Readonly/types.d.ts +9 -8
  12. package/components/Column/Ueditor.tsx +313 -313
  13. package/components/Column/types.d.ts +29 -28
  14. package/components/Form/Action/Button.tsx +128 -124
  15. package/components/Form/Action/types.d.ts +5 -4
  16. package/components/Form/Actions.tsx +38 -34
  17. package/components/Form.tsx +176 -170
  18. package/components/FormContext.ts +8 -7
  19. package/components/Layout/New.tsx +252 -0
  20. package/components/Layout.tsx +52 -237
  21. package/components/LayoutContext.ts +25 -25
  22. package/components/ModalContext.ts +15 -15
  23. package/components/Table/Action/Button.tsx +88 -88
  24. package/components/Table/Action/StartEditable.tsx +58 -58
  25. package/components/Table/Action/types.d.ts +7 -6
  26. package/components/Table/ToolbarActions.tsx +43 -38
  27. package/components/Table.scss +4 -7
  28. package/components/Table.tsx +280 -279
  29. package/components/TableContext.ts +14 -13
  30. package/components/Tabs.tsx +71 -71
  31. package/lib/container.ts +83 -81
  32. package/lib/customRule.ts +9 -9
  33. package/lib/global.ts +10 -10
  34. package/lib/helpers.tsx +145 -149
  35. package/lib/http.ts +73 -73
  36. package/lib/schemaHandler.ts +121 -121
  37. package/lib/upload.ts +177 -177
  38. package/lib/writeExtra.js +31 -0
  39. package/package.json +2 -6
  40. package/readme.md +151 -128
  41. package/components/Column/Readonly/Option.tsx +0 -58
@@ -1,237 +1,52 @@
1
- import {MenuDataItem, PageContainer, ProLayout} from "@ant-design/pro-components";
2
- import {App, Dropdown, Menu, Space} from "antd";
3
- import type {LayoutProps} from "./LayoutContext";
4
- import {LayoutContext} from "./LayoutContext";
5
- import {useEffect, useRef, useState} from "react";
6
- import {usePage} from "@inertiajs/react";
7
- import {routerNavigateTo} from "../lib/helpers";
8
- import {MenuInfo} from "rc-menu/lib/interface";
9
- import http from "../lib/http";
10
- // @ts-ignore
11
- import {Route} from '@ant-design/pro-layout/lib/typing';
12
- import global from "../lib/global";
13
- import assign from "lodash/assign";
14
-
15
- export default function ({children}: {
16
- children: React.ReactNode
17
- }) {
18
-
19
- const pageProps = usePage<{
20
- layoutProps: LayoutProps,
21
- }>().props
22
-
23
- const layoutProps = pageProps.layoutProps
24
- const {modal, notification, message} = App.useApp()
25
- const contentRef = useRef<HTMLDivElement>(null)
26
-
27
- const [props, setProps] = useState<LayoutProps>({
28
- title: '',
29
- metaTitle: '',
30
- topMenuActiveKey: '',
31
- menuActiveKey: '',
32
- loading: false,
33
- topMenu: [],
34
- menuList: [],
35
- logo: '',
36
- userMenu: [],
37
- })
38
-
39
- const assignProps = (newProps: LayoutProps) => {
40
- setProps(assign(props, newProps))
41
- }
42
-
43
- const headerContentRender = () => {
44
- return <>
45
- <Menu items={props.topMenu}
46
- mode={'horizontal'}
47
- activeKey={props.topMenuActiveKey}
48
- />
49
- </>
50
- }
51
-
52
- const [openKeys, setOpenKeys] = useState<string[]>([])
53
- const [pageTitle, setPageTitle] = useState<string>('')
54
- const [route, setRoute] = useState<Route>()
55
-
56
- useEffect(() => {
57
- function findKeyPath(key: string, list: MenuDataItem[]): string[] {
58
- for (let i = 0; i < list.length; i++) {
59
- const item = list[i];
60
- if (item.key === key) {
61
- return [item.key]
62
- } else if (item.children?.length) {
63
- const path = findKeyPath(key, item.children)
64
- if (path?.length) {
65
- return [item.key as string, ...path]
66
- }
67
- }
68
- }
69
- return []
70
- }
71
-
72
- if (!props.menuActiveKey) {
73
- return
74
- }
75
- setOpenKeys(findKeyPath(props.menuActiveKey, props.menuList || []))
76
-
77
- }, [props.menuActiveKey]);
78
-
79
- useEffect(() => {
80
- if (pageProps.layoutProps?.menuActiveKey) {
81
- assignProps({
82
- menuActiveKey: pageProps.layoutProps.menuActiveKey
83
- })
84
- }
85
-
86
- const title = props.title || layoutProps.title
87
- if (pageProps.layoutProps?.metaTitle) {
88
- setPageTitle(pageProps.layoutProps.metaTitle + ' - ' + title)
89
- assignProps({
90
- metaTitle: pageProps.layoutProps.metaTitle + ' - ' + title
91
- })
92
- } else {
93
- setPageTitle(title as string)
94
- assignProps({
95
- metaTitle: title
96
- })
97
- }
98
- }, [pageProps]);
99
-
100
-
101
- useEffect(() => {
102
- console.log(pageProps)
103
-
104
- global.modal = modal
105
- global.notification = notification
106
- global.message = message
107
-
108
- setProps({
109
- title: layoutProps.title || '',
110
- metaTitle: '',
111
- topMenuActiveKey: layoutProps.topMenuActiveKey,
112
- menuActiveKey: layoutProps.menuActiveKey,
113
- loading: false,
114
- topMenu: layoutProps.topMenu,
115
- menuList: layoutProps.menuList,
116
- logo: layoutProps.logo,
117
- userMenu: layoutProps.userMenu,
118
- })
119
-
120
- const r = {
121
- key: '/',
122
- routes: layoutProps.menuList?.map(menu => {
123
- return {
124
- name: menu.name,
125
- key: menu.key,
126
- children: menu.children?.map(child => {
127
- return {
128
- name: child.name,
129
- key: child.key
130
- }
131
- })
132
- }
133
- })
134
- }
135
-
136
- setRoute(r)
137
-
138
- // 设置内容高度
139
- if (contentRef.current) {
140
- contentRef.current.style.minHeight = (window.innerHeight - 200) + 'px'
141
- }
142
-
143
- }, [])
144
-
145
-
146
- const onMenuClick = (info: MenuInfo) => {
147
- const keyPath = info.keyPath.reverse()
148
- let menu: MenuDataItem | undefined = props.menuList?.find(menu => menu.key === keyPath[0]);
149
- for (let i = 1; i < keyPath.length; i++) {
150
- menu = menu?.children?.find(m => m.key === keyPath[i])
151
- }
152
- if (menu?.path) {
153
- assignProps({
154
- loading: true
155
- })
156
- routerNavigateTo(menu.path, {
157
- onSuccess() {
158
- assignProps({
159
- menuActiveKey: info.key
160
- })
161
- },
162
- onFinish() {
163
- assignProps({
164
- loading: false
165
- })
166
- }
167
- })
168
- }
169
- }
170
-
171
- return <>
172
- <LayoutContext.Provider value={{
173
- assignProps,
174
- props,
175
- }}>
176
- <ProLayout title={props.title}
177
- loading={props.loading}
178
- layout="mix"
179
- route={route}
180
- fixSiderbar={true}
181
- logo={props.logo}
182
- headerContentRender={headerContentRender}
183
- pageTitleRender={p => pageTitle}
184
- footerRender={() => <>
185
- <Space>
186
- <a href="https://www.quansitech.com/" target={'_blank'}>全思科技</a>
187
- <a href="https://github.com/quansitech/" target={'_blank'}>Github</a>
188
- </Space>
189
- </>}
190
- avatarProps={{
191
- title: 'admin',
192
- render(p, dom) {
193
- return <>
194
- <Dropdown menu={{
195
- items: props.userMenu?.map(menu => {
196
- return {
197
- label: menu.title,
198
- key: menu.url,
199
- onClick() {
200
- switch (menu.type) {
201
- case 'open':
202
- window.open(menu.url)
203
- break;
204
- case 'nav':
205
- routerNavigateTo(menu.url)
206
- break
207
- case 'ajax':
208
- http.get(menu.url).then(() => {
209
- window.location.reload()
210
- })
211
- break
212
- }
213
- }
214
- }
215
- }) || [],
216
- }}>
217
- {dom}
218
- </Dropdown>
219
- </>
220
- }
221
- }}
222
- menuProps={{
223
- activeKey: props.menuActiveKey as string,
224
- selectedKeys: [props.menuActiveKey as string],
225
- openKeys: openKeys,
226
- onClick: onMenuClick,
227
- onOpenChange: setOpenKeys
228
- }}
229
- >
230
-
231
- <PageContainer title={props.metaTitle}>
232
- <div ref={contentRef}>{children}</div>
233
- </PageContainer>
234
- </ProLayout>
235
- </LayoutContext.Provider>
236
- </>
237
- }
1
+ import {Head, usePage} from "@inertiajs/react";
2
+ import {useEffect, useState} from "react";
3
+ import {PageProps} from "@inertiajs/core/types/types";
4
+ import New from "./Layout/New";
5
+ import {PageContainer} from "@ant-design/pro-components"
6
+ import {App} from "antd";
7
+ import global from "../lib/global";
8
+
9
+ export default function ({children}: {
10
+ children: React.ReactNode
11
+ }) {
12
+ const pageProps: PageProps & {
13
+ layoutProps?: {
14
+ metaTitle?: string,
15
+ enableNewLayout?: boolean
16
+ title?: string,
17
+ }
18
+ } = usePage().props
19
+ const {modal, notification, message} = App.useApp()
20
+ const [enableNewLayout, setEnableNewLayout] = useState(false)
21
+ const [pageTitle, setPageTitle] = useState('')
22
+ const [siteTitle, setSiteTitle] = useState('')
23
+
24
+ useEffect(() => {
25
+ console.log(pageProps)
26
+
27
+ if (pageProps.layoutProps?.enableNewLayout) {
28
+ setEnableNewLayout(true)
29
+ }
30
+
31
+ global.modal = modal
32
+ global.notification = notification
33
+ global.message = message
34
+ }, [])
35
+
36
+ useEffect(() => {
37
+ setPageTitle(pageProps.layoutProps?.metaTitle || '')
38
+ pageProps.layoutProps?.title && setSiteTitle(pageProps.layoutProps?.title + '')
39
+ }, [pageProps.layoutProps]);
40
+
41
+ return <>
42
+ {enableNewLayout
43
+ ? <New pageTitle={pageTitle} siteTitle={siteTitle} children={children}></New>
44
+ : <>
45
+ <Head title={pageTitle + ' | ' + siteTitle + ' 后台管理'}></Head>
46
+ <PageContainer title={pageTitle}>
47
+ {children}
48
+ </PageContainer>
49
+ </>
50
+ }
51
+ </>
52
+ }
@@ -1,26 +1,26 @@
1
- import {createContext} from "react";
2
- import {MenuDataItem} from "@ant-design/pro-components";
3
-
4
- declare type LayoutContextValue = {
5
- assignProps: (props: LayoutProps) => void,
6
- props: LayoutProps,
7
- }
8
-
9
- export declare type LayoutProps = {
10
- title?: string,
11
- metaTitle?: string,
12
- topMenuActiveKey?: string,
13
- menuActiveKey?: string,
14
- loading?: boolean,
15
- topMenu?: { name: string, key: string }[],
16
- menuList?: MenuDataItem[],
17
- logo?: string,
18
- userMenu?: {
19
- title: string,
20
- url: string,
21
- type: string,
22
-
23
- }[]
24
- }
25
-
1
+ import {createContext} from "react";
2
+ import {MenuDataItem} from "@ant-design/pro-components";
3
+
4
+ declare type LayoutContextValue = {
5
+ assignProps: (props: LayoutProps) => void,
6
+ props: LayoutProps,
7
+ }
8
+
9
+ export declare type LayoutProps = {
10
+ title?: string,
11
+ metaTitle?: string,
12
+ topMenuActiveKey?: string,
13
+ menuActiveKey?: string,
14
+ loading?: boolean,
15
+ topMenu?: { name: string, key: string }[],
16
+ menuList?: MenuDataItem[],
17
+ logo?: string,
18
+ userMenu?: {
19
+ title: string,
20
+ url: string,
21
+ type: string,
22
+
23
+ }[]
24
+ }
25
+
26
26
  export const LayoutContext = createContext<LayoutContextValue>({} as LayoutContextValue)
@@ -1,16 +1,16 @@
1
- import {createContext} from "react";
2
-
3
- export type ModalContextProps = {
4
- inModal: boolean,
5
- closeModal: () => void,
6
- contexts?: Record<string, any>
7
- setAfterClose(callback: () => void): void
8
- }
9
-
10
- export const ModalContext = createContext<ModalContextProps>({
11
- inModal: false,
12
- closeModal: () => {
13
- },
14
- setAfterClose: (fn: Function) => {
15
- },
1
+ import {createContext} from "react";
2
+
3
+ export type ModalContextProps = {
4
+ inModal: boolean,
5
+ closeModal: () => void,
6
+ contexts?: Record<string, any>
7
+ setAfterClose(callback: () => void): void
8
+ }
9
+
10
+ export const ModalContext = createContext<ModalContextProps>({
11
+ inModal: false,
12
+ closeModal: () => {
13
+ },
14
+ setAfterClose: (fn: Function) => {
15
+ },
16
16
  })
@@ -1,89 +1,89 @@
1
- import {Button, Popconfirm} from "antd";
2
- import {useContext, useEffect, useState} from "react";
3
- import {TableContext} from "../../TableContext";
4
- import http from "../../../lib/http";
5
- import {modal, routerNavigateTo} from "../../../lib/helpers";
6
- import {TableActionProps} from "./types";
7
-
8
- export default function (props: TableActionProps & {
9
- props: Record<string, any>,
10
- link?: {
11
- url: string,
12
- },
13
- request?: RequestOptions,
14
- modal?: ModalOptions,
15
- }) {
16
- const tableContext = useContext(TableContext)
17
-
18
- const onClick = async () => {
19
- const rowKey = tableContext.getTableProps().rowKey
20
- if (props.link) {
21
- routerNavigateTo(props.link.url)
22
- return
23
- }
24
-
25
- if (props.request) {
26
- setLoading(true)
27
- const data = props.request.data || {}
28
- if (props.relateSelection) {
29
- data.selection = props.selectedRows?.map(item => item[rowKey])
30
- for (const key in data) {
31
- if (typeof data[key] !== 'string') {
32
- continue
33
- }
34
- const matches = data[key].match(/^__(\w+)__$/)
35
- if (!matches) {
36
- continue
37
- }
38
- data[key] = props.selectedRows?.map(item => item[matches[1]])
39
- }
40
- }
41
- try {
42
- await http({
43
- url: props.request.url,
44
- method: props.request.method,
45
- headers: props.request.headers || {},
46
- data: data,
47
- })
48
- } finally {
49
- setLoading(false)
50
- }
51
- return
52
- }
53
-
54
- if (props.modal) {
55
- await modal(props.modal)
56
- return
57
- }
58
-
59
- await tableContext.actionRef?.reload()
60
- }
61
-
62
- const [loading, setLoading] = useState(false)
63
-
64
- const [disabled, setDisabled] = useState(props.props.disabled)
65
-
66
- useEffect(() => {
67
- if (!props.relateSelection) {
68
- return
69
- }
70
- setDisabled(props.selectedRows?.length === 0)
71
-
72
- }, [props.selectedRows]);
73
-
74
-
75
- const ButtonComponent = () => {
76
- if (props.request?.confirm) {
77
- return <Popconfirm title={props.request.confirm} onConfirm={onClick}>
78
- <Button loading={loading} {...props.props} disabled={disabled}>{props.title}</Button>
79
- </Popconfirm>
80
- } else {
81
- return <Button loading={loading} onClick={onClick} {...props.props}
82
- disabled={disabled}>{props.title}</Button>
83
- }
84
- }
85
-
86
- return <>
87
- <ButtonComponent></ButtonComponent>
88
- </>
1
+ import {Button, Popconfirm} from "antd";
2
+ import {useContext, useEffect, useState} from "react";
3
+ import {TableContext} from "../../TableContext";
4
+ import http from "../../../lib/http";
5
+ import {modalShow, routerNavigateTo} from "../../../lib/helpers";
6
+ import {TableActionProps} from "./types";
7
+
8
+ export default function (props: TableActionProps & {
9
+ props: Record<string, any>,
10
+ link?: {
11
+ url: string,
12
+ },
13
+ request?: RequestOptions,
14
+ modal?: ModalOptions,
15
+ }) {
16
+ const tableContext = useContext(TableContext)
17
+
18
+ const onClick = async () => {
19
+ const rowKey = tableContext.getTableProps().rowKey
20
+ if (props.link) {
21
+ routerNavigateTo(props.link.url)
22
+ return
23
+ }
24
+
25
+ if (props.request) {
26
+ setLoading(true)
27
+ const data = props.request.data || {}
28
+ if (props.relateSelection) {
29
+ data.selection = props.selectedRows?.map(item => item[rowKey])
30
+ for (const key in data) {
31
+ if (typeof data[key] !== 'string') {
32
+ continue
33
+ }
34
+ const matches = data[key].match(/^__(\w+)__$/)
35
+ if (!matches) {
36
+ continue
37
+ }
38
+ data[key] = props.selectedRows?.map(item => item[matches[1]])
39
+ }
40
+ }
41
+ try {
42
+ await http({
43
+ url: props.request.url,
44
+ method: props.request.method,
45
+ headers: props.request.headers || {},
46
+ data: data,
47
+ })
48
+ } finally {
49
+ setLoading(false)
50
+ }
51
+ return
52
+ }
53
+
54
+ if (props.modal) {
55
+ await modalShow(props.modal)
56
+ return
57
+ }
58
+
59
+ await tableContext.actionRef?.reload()
60
+ }
61
+
62
+ const [loading, setLoading] = useState(false)
63
+
64
+ const [disabled, setDisabled] = useState(props.props.disabled)
65
+
66
+ useEffect(() => {
67
+ if (!props.relateSelection) {
68
+ return
69
+ }
70
+ setDisabled(props.selectedRows?.length === 0)
71
+
72
+ }, [props.selectedRows]);
73
+
74
+
75
+ const ButtonComponent = () => {
76
+ if (props.request?.confirm) {
77
+ return <Popconfirm title={props.request.confirm} onConfirm={onClick}>
78
+ <Button loading={loading} {...props.props} disabled={disabled}>{props.title}</Button>
79
+ </Popconfirm>
80
+ } else {
81
+ return <Button loading={loading} onClick={onClick} {...props.props}
82
+ disabled={disabled}>{props.title}</Button>
83
+ }
84
+ }
85
+
86
+ return <>
87
+ <ButtonComponent></ButtonComponent>
88
+ </>
89
89
  }
@@ -1,59 +1,59 @@
1
- import {Button, ButtonProps, Space} from "antd";
2
- import {TableContext} from "../../TableContext";
3
- import {useContext, useState} from "react";
4
- import http from "../../../lib/http";
5
- import {TableActionProps} from "./types";
6
-
7
- export default function (props: TableActionProps & {
8
- props: ButtonProps,
9
- saveRequest: {
10
- url: string,
11
- method: string,
12
- },
13
- }) {
14
- const tableContext = useContext(TableContext)
15
-
16
- const onStartClick = () => {
17
- const rowKey = tableContext.getTableProps().rowKey
18
- tableContext.getTableProps().dataSource.map(item => {
19
- tableContext.actionRef?.startEditable(item[rowKey], item)
20
- })
21
- }
22
-
23
- const onCancelClick = () => {
24
- const rowKey = tableContext.getTableProps().rowKey
25
- tableContext.getTableProps().dataSource.map(item => {
26
- tableContext.actionRef?.cancelEditable(item[rowKey])
27
- })
28
- }
29
-
30
- const [loading, setLoading] = useState(false)
31
-
32
- const onSaveClick = async () => {
33
- setLoading(true)
34
-
35
- try {
36
- await http({
37
- method: props.saveRequest.method,
38
- url: props.saveRequest.url,
39
- data: tableContext.getEditedValues(),
40
- })
41
-
42
- await tableContext.actionRef?.reload()
43
- } finally {
44
- setLoading(false)
45
- }
46
- onCancelClick()
47
- }
48
-
49
- return <>
50
- {tableContext.editableKeys.length > 0
51
- ?
52
- <Space>
53
- <Button loading={loading} type={'primary'} onClick={onSaveClick}>保存</Button>
54
- <Button danger={true} onClick={onCancelClick}>取消</Button>
55
- </Space>
56
- : <Button {...props.props} onClick={onStartClick}>{props.title}</Button>
57
- }
58
- </>
1
+ import {Button, ButtonProps, Space} from "antd";
2
+ import {TableContext} from "../../TableContext";
3
+ import {useContext, useState} from "react";
4
+ import http from "../../../lib/http";
5
+ import {TableActionProps} from "./types";
6
+
7
+ export default function (props: TableActionProps & {
8
+ props: ButtonProps,
9
+ saveRequest: {
10
+ url: string,
11
+ method: string,
12
+ },
13
+ }) {
14
+ const tableContext = useContext(TableContext)
15
+
16
+ const onStartClick = () => {
17
+ const rowKey = tableContext.getTableProps().rowKey
18
+ tableContext.getTableProps().dataSource.map(item => {
19
+ tableContext.actionRef?.startEditable(item[rowKey], item)
20
+ })
21
+ }
22
+
23
+ const onCancelClick = () => {
24
+ const rowKey = tableContext.getTableProps().rowKey
25
+ tableContext.getTableProps().dataSource.map(item => {
26
+ tableContext.actionRef?.cancelEditable(item[rowKey])
27
+ })
28
+ }
29
+
30
+ const [loading, setLoading] = useState(false)
31
+
32
+ const onSaveClick = async () => {
33
+ setLoading(true)
34
+
35
+ try {
36
+ await http({
37
+ method: props.saveRequest.method,
38
+ url: props.saveRequest.url,
39
+ data: tableContext.getEditedValues(),
40
+ })
41
+
42
+ await tableContext.actionRef?.reload()
43
+ } finally {
44
+ setLoading(false)
45
+ }
46
+ onCancelClick()
47
+ }
48
+
49
+ return <>
50
+ {tableContext.editableKeys.length > 0
51
+ ?
52
+ <Space>
53
+ <Button loading={loading} type={'primary'} onClick={onSaveClick}>保存</Button>
54
+ <Button danger={true} onClick={onCancelClick}>取消</Button>
55
+ </Space>
56
+ : <Button {...props.props} onClick={onStartClick}>{props.title}</Button>
57
+ }
58
+ </>
59
59
  }