@quansitech/antd-admin 1.0.0 → 1.0.1

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 (40) 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 +179 -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 +283 -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/package.json +2 -6
  39. package/readme.md +128 -128
  40. package/components/Column/Readonly/Option.tsx +0 -58
@@ -1,72 +1,72 @@
1
- import {Tabs} from "antd";
2
- import {lazy, Suspense, useEffect, useState} from "react";
3
- import type {Tab} from 'rc-tabs/lib/interface';
4
- import container from "../lib/container";
5
- import {routerNavigateTo} from "../lib/helpers";
6
- import upperFirst from "lodash/upperFirst";
7
- import {ProSkeleton} from "@ant-design/pro-components";
8
-
9
- type TabProps = {
10
- title: string,
11
- url?: string,
12
- pane?: {
13
- component: 'form' | 'table',
14
- props: any,
15
- }
16
- }
17
-
18
- export type TabsPageType = {
19
- tabs: Record<string, TabProps>,
20
- defaultActiveKey?: string,
21
- }
22
-
23
- export default function (props: TabsPageType) {
24
- const [items, setItems] = useState<Tab[]>([]);
25
- const [activeKey, setActiveKey] = useState<string>();
26
-
27
- useEffect(() => {
28
- setActiveKey(props.defaultActiveKey || Object.keys(props.tabs)[0])
29
-
30
- setItems(Object.keys(props.tabs).map(key => {
31
- const t = props.tabs[key]
32
-
33
- if (!t.pane) {
34
- return {
35
- key,
36
- label: t.title,
37
- children: <>
38
- <ProSkeleton list={2}></ProSkeleton>
39
- </>
40
- }
41
- }
42
-
43
- const Component = lazy(() => container.get('Tab.Pane.' + upperFirst(t.pane?.component)))
44
-
45
- return {
46
- key,
47
- label: t.title,
48
- children: <>
49
- <Suspense>
50
- <Component {...t.pane.props}></Component>
51
- </Suspense>
52
- </>
53
- }
54
- }))
55
- }, []);
56
-
57
- const onChange = (key: string) => {
58
- setActiveKey(key)
59
-
60
- const tab = props.tabs[key]
61
- if (tab.url) {
62
- routerNavigateTo(tab.url)
63
- }
64
- }
65
-
66
- return <>
67
- <Tabs items={items}
68
- onChange={onChange}
69
- activeKey={activeKey}
70
- ></Tabs>
71
- </>
1
+ import {Tabs} from "antd";
2
+ import {lazy, Suspense, useEffect, useState} from "react";
3
+ import type {Tab} from 'rc-tabs/lib/interface';
4
+ import container from "../lib/container";
5
+ import {routerNavigateTo} from "../lib/helpers";
6
+ import upperFirst from "lodash/upperFirst";
7
+ import {ProSkeleton} from "@ant-design/pro-components";
8
+
9
+ type TabProps = {
10
+ title: string,
11
+ url?: string,
12
+ pane?: {
13
+ component: 'form' | 'table',
14
+ props: any,
15
+ }
16
+ }
17
+
18
+ export type TabsPageType = {
19
+ tabs: Record<string, TabProps>,
20
+ defaultActiveKey?: string,
21
+ }
22
+
23
+ export default function (props: TabsPageType) {
24
+ const [items, setItems] = useState<Tab[]>([]);
25
+ const [activeKey, setActiveKey] = useState<string>();
26
+
27
+ useEffect(() => {
28
+ setActiveKey(props.defaultActiveKey || Object.keys(props.tabs)[0])
29
+
30
+ setItems(Object.keys(props.tabs).map(key => {
31
+ const t = props.tabs[key]
32
+
33
+ if (!t.pane) {
34
+ return {
35
+ key,
36
+ label: t.title,
37
+ children: <>
38
+ <ProSkeleton list={2}></ProSkeleton>
39
+ </>
40
+ }
41
+ }
42
+
43
+ const Component = lazy(() => container.get('Tab.Pane.' + upperFirst(t.pane?.component)))
44
+
45
+ return {
46
+ key,
47
+ label: t.title,
48
+ children: <>
49
+ <Suspense>
50
+ <Component {...t.pane.props}></Component>
51
+ </Suspense>
52
+ </>
53
+ }
54
+ }))
55
+ }, []);
56
+
57
+ const onChange = (key: string) => {
58
+ setActiveKey(key)
59
+
60
+ const tab = props.tabs[key]
61
+ if (tab.url) {
62
+ routerNavigateTo(tab.url)
63
+ }
64
+ }
65
+
66
+ return <>
67
+ <Tabs items={items}
68
+ onChange={onChange}
69
+ activeKey={activeKey}
70
+ ></Tabs>
71
+ </>
72
72
  }
package/lib/container.ts CHANGED
@@ -1,82 +1,84 @@
1
- import {schemaHandler} from "./schemaHandler";
2
-
3
- const components: Record<string, any> = {}
4
-
5
- const container = {
6
- register(name: string, componentLoader: any) {
7
- if (this.check(name)) {
8
- throw new Error(`Component ${name} already registered`)
9
- }
10
- components[name] = componentLoader
11
- },
12
- get(name: string) {
13
- if (!this.check(name)) {
14
- throw new Error(`Component ${name} is not registered`)
15
- }
16
- return components[name]
17
- },
18
- check(name: string) {
19
- return !!components[name]
20
- },
21
- schemaHandler,
22
- };
23
-
24
- function autoRegister(prefix: string, components: Record<string, () => Promise<any>>) {
25
- for (const [key, value] of Object.entries(components)) {
26
- const name = key.split('/').pop()?.split('.').shift()
27
- container.register(prefix + name, value)
28
- }
29
- }
30
-
31
- // -------- 通用 -----------
32
- {
33
- const columnRender = import.meta.glob('../components/Column/*.tsx')
34
- autoRegister('Column.', columnRender)
35
-
36
- // readonly render
37
- const columnReadonlyRender = import.meta.glob('../components/Column/Readonly/*.tsx')
38
- autoRegister('Column.Readonly.', columnReadonlyRender)
39
- }
40
-
41
- // -------- 弹窗 -----------
42
- {
43
- container.register('Modal.Table', import('../components/Table'))
44
- container.register('Modal.Form', import('../components/Form'))
45
- }
46
-
47
- // -------- Tabs -----------
48
- {
49
- container.register('Tab.Pane.Table', import('../components/Table'))
50
- container.register('Tab.Pane.Form', import('../components/Form'))
51
- }
52
-
53
- // -------- 表格 -----------
54
- {
55
- // options render
56
- const optionsRender = import.meta.glob('../components/Table/Option/*.tsx')
57
- autoRegister('Table.Option.', optionsRender)
58
-
59
- // action render
60
- const actionRender = import.meta.glob('../components/Table/Action/*.tsx')
61
- autoRegister('Table.Action.', actionRender)
62
- }
63
-
64
- // -------- 表单 -----------
65
- {
66
-
67
- // formAction render
68
- const formActionRender = import.meta.glob('../components/Form/Action/*.tsx')
69
- autoRegister('Form.Action.', formActionRender)
70
- }
71
-
72
-
73
- ;((globalThis: any) => {
74
- if (globalThis.$qsContainer) {
75
- return;
76
- }
77
-
78
- globalThis.$qsContainer = container
79
-
80
- })(window)
81
-
1
+ import {schemaHandler} from "./schemaHandler";
2
+ import {routerNavigateTo} from "./helpers";
3
+
4
+ const components: Record<string, any> = {}
5
+
6
+ const container = {
7
+ register(name: string, componentLoader: any) {
8
+ if (this.check(name)) {
9
+ throw new Error(`Component ${name} already registered`)
10
+ }
11
+ components[name] = componentLoader
12
+ },
13
+ get(name: string) {
14
+ if (!this.check(name)) {
15
+ throw new Error(`Component ${name} is not registered`)
16
+ }
17
+ return components[name]
18
+ },
19
+ check(name: string) {
20
+ return !!components[name]
21
+ },
22
+ schemaHandler,
23
+ routerNavigateTo,
24
+ };
25
+
26
+ function autoRegister(prefix: string, components: Record<string, () => Promise<any>>) {
27
+ for (const [key, value] of Object.entries(components)) {
28
+ const name = key.split('/').pop()?.split('.').shift()
29
+ container.register(prefix + name, value)
30
+ }
31
+ }
32
+
33
+ // -------- 通用 -----------
34
+ {
35
+ const columnRender = import.meta.glob('../components/Column/*.tsx')
36
+ autoRegister('Column.', columnRender)
37
+
38
+ // readonly render
39
+ const columnReadonlyRender = import.meta.glob('../components/Column/Readonly/*.tsx')
40
+ autoRegister('Column.Readonly.', columnReadonlyRender)
41
+ }
42
+
43
+ // -------- 弹窗 -----------
44
+ {
45
+ container.register('Modal.Table', import('../components/Table'))
46
+ container.register('Modal.Form', import('../components/Form'))
47
+ }
48
+
49
+ // -------- Tabs -----------
50
+ {
51
+ container.register('Tab.Pane.Table', import('../components/Table'))
52
+ container.register('Tab.Pane.Form', import('../components/Form'))
53
+ }
54
+
55
+ // -------- 表格 -----------
56
+ {
57
+ // column.action render
58
+ const optionsRender = import.meta.glob('../components/Column/Readonly/Action/*.tsx')
59
+ autoRegister('Column.Readonly.Action.', optionsRender)
60
+
61
+ // action render
62
+ const actionRender = import.meta.glob('../components/Table/Action/*.tsx')
63
+ autoRegister('Table.Action.', actionRender)
64
+ }
65
+
66
+ // -------- 表单 -----------
67
+ {
68
+
69
+ // formAction render
70
+ const formActionRender = import.meta.glob('../components/Form/Action/*.tsx')
71
+ autoRegister('Form.Action.', formActionRender)
72
+ }
73
+
74
+
75
+ ;((globalThis: any) => {
76
+ if (globalThis.$qsContainer) {
77
+ return;
78
+ }
79
+
80
+ globalThis.$qsContainer = container
81
+
82
+ })(window)
83
+
82
84
  export default container
package/lib/customRule.ts CHANGED
@@ -1,10 +1,10 @@
1
- import {RuleObject, StoreValue} from "rc-field-form/lib/interface";
2
-
3
- const customRule: Record<string, (rule: RuleObject, value: StoreValue, callback: (error?: string) => void) => any> = {
4
- notInEnum(rule, value) {
5
- return !rule.enum?.includes(value);
6
-
7
- }
8
- }
9
-
1
+ import {RuleObject, StoreValue} from "rc-field-form/lib/interface";
2
+
3
+ const customRule: Record<string, (rule: RuleObject, value: StoreValue, callback: (error?: string) => void) => any> = {
4
+ notInEnum(rule, value) {
5
+ return !rule.enum?.includes(value);
6
+
7
+ }
8
+ }
9
+
10
10
  export default customRule
package/lib/global.ts CHANGED
@@ -1,11 +1,11 @@
1
- import {MessageInstance} from "antd/es/message/interface";
2
- import {ModalStaticFunctions} from "antd/es/modal/confirm";
3
- import {NotificationInstance} from "antd/es/notification/interface";
4
-
5
- const global = {} as {
6
- message: MessageInstance,
7
- modal: Omit<ModalStaticFunctions, 'warn'>,
8
- notification: NotificationInstance,
9
- }
10
-
1
+ import {MessageInstance} from "antd/es/message/interface";
2
+ import {ModalStaticFunctions} from "antd/es/modal/confirm";
3
+ import {NotificationInstance} from "antd/es/notification/interface";
4
+
5
+ const global = {} as {
6
+ message: MessageInstance,
7
+ modal: Omit<ModalStaticFunctions, 'warn'>,
8
+ notification: NotificationInstance,
9
+ }
10
+
11
11
  export default global
package/lib/helpers.tsx CHANGED
@@ -1,150 +1,146 @@
1
- import {router} from "@inertiajs/react";
2
- import {VisitOptions} from "@inertiajs/core/types/types";
3
- import Schema from '@rc-component/async-validator';
4
- import {Rules, ValidateError, ValidateFieldsError, Values} from "@rc-component/async-validator/lib/interface";
5
- import {Spin} from "antd";
6
- import http from "./http";
7
- import container from "./container";
8
- import upperFirst from "lodash/upperFirst";
9
- import {lazy, Suspense} from "react";
10
- import global from "./global";
11
- import {ModalContext} from "../components/ModalContext";
12
-
13
- export function replaceUrl(url: string, params: any) {
14
- return url.replace(/__([\w]+)__/g, (match, key) => {
15
- return params[key] || match;
16
- })
17
- }
18
-
19
- export function replaceParams(params: Record<string, any>, data: Record<string, any>) {
20
- if (typeof params !== 'object') {
21
- return params;
22
- }
23
- const res = Object.assign({}, params);
24
- Object.keys(params).forEach(key => {
25
- if (typeof params[key] === 'string') {
26
- const m = params[key].match(/^__(\w+)__$/)
27
- if (m) {
28
- res[key] = data[m[1]];
29
- }
30
- }
31
- })
32
- return res;
33
- }
34
-
35
- export function routerNavigateTo(url: string, config?: VisitOptions) {
36
- return router.visit(url, {
37
- ...config,
38
- })
39
- }
40
-
41
- export function handleRules(dataRules: Rules, data: any) {
42
- return new Promise(resolve => {
43
- const validator = new Schema(dataRules);
44
- validator.validate(data, (errors: ValidateError[] | null, fields: ValidateFieldsError | Values) => {
45
- if (errors) {
46
- resolve(false);
47
- return;
48
- }
49
- resolve(true);
50
- })
51
-
52
- })
53
-
54
- }
55
-
56
- export async function asyncFilter(arr: any[], predicate: (item: any) => PromiseLike<any>) {
57
- return await Promise.all(arr.map(predicate))
58
- .then((results) => arr.filter((_v, index) => results[index]))
59
- }
60
-
61
- export function modalShow(type: string, props: any) {
62
-
63
- }
64
-
65
- export function filterObjectKeys(obj: Record<string, any>, keysToKeep: string[]) {
66
- if (typeof obj !== 'object' || !obj) {
67
- return obj;
68
- }
69
- return Object.keys(obj)
70
- .filter(key => !keysToKeep.includes(key))
71
- .reduce((newObj, key) => {
72
- newObj[key] = obj[key];
73
- return newObj;
74
- }, {} as Record<string, any>);
75
- }
76
-
77
-
78
- export function createScript(url: string) {
79
- let scriptTags = window.document.querySelectorAll('script')
80
- let len = scriptTags.length
81
- let i = 0
82
- let _url = window.location.origin + url
83
- return new Promise((resolve, reject) => {
84
- for (i = 0; i < len; i++) {
85
- var src = scriptTags[i].src
86
- if (src && src === _url) {
87
- scriptTags[i].parentElement?.removeChild(scriptTags[i])
88
- }
89
- }
90
-
91
- let node = document.createElement('script')
92
- node.src = url
93
- node.onload = resolve
94
- document.body.appendChild(node)
95
- })
96
- }
97
-
98
- export async function modal(options: ModalOptions) {
99
- let props = options.content.props
100
- if (options.content.url) {
101
- const res = await http({
102
- method: 'get',
103
- url: options.content.url,
104
- headers: {
105
- 'X-Modal': '1',
106
- }
107
- })
108
- if (typeof res.data === 'string') {
109
- throw new Error('modal response is not vail')
110
- }
111
- props = res.data
112
- }
113
- if (!props) {
114
- throw new Error('modal props is empty')
115
- }
116
- const Component = lazy(() => container.get('Modal.' + upperFirst(options.content.type)))
117
-
118
- let afterClose = () => {
119
- }
120
- const modal = global.modal.info({
121
- ...options,
122
- closable: true,
123
- icon: null,
124
- destroyOnClose: true,
125
- footer: null,
126
- content: (
127
- <Suspense fallback={<Spin/>}>
128
- <ModalContext.Provider value={{
129
- inModal: true,
130
- closeModal: () => {
131
- modal?.destroy()
132
- },
133
- contexts: options.contexts,
134
- setAfterClose(callback: () => void) {
135
- afterClose = callback
136
- }
137
- }}>
138
- <Component {...props} />
139
- </ModalContext.Provider>
140
- </Suspense>
141
- ),
142
- afterClose: () => {
143
- afterClose && afterClose()
144
- },
145
- })
146
- return {
147
- destroy: modal.destroy,
148
- update: modal.update,
149
- }
1
+ import {router} from "@inertiajs/react";
2
+ import {VisitOptions} from "@inertiajs/core/types/types";
3
+ import Schema from '@rc-component/async-validator';
4
+ import {Rules, ValidateError, ValidateFieldsError, Values} from "@rc-component/async-validator/lib/interface";
5
+ import {Spin} from "antd";
6
+ import http from "./http";
7
+ import container from "./container";
8
+ import upperFirst from "lodash/upperFirst";
9
+ import {lazy, Suspense} from "react";
10
+ import global from "./global";
11
+ import {ModalContext} from "../components/ModalContext";
12
+
13
+ export function replaceUrl(url: string, params: any) {
14
+ return url.replace(/__([\w]+)__/g, (match, key) => {
15
+ return params[key] || match;
16
+ })
17
+ }
18
+
19
+ export function replaceParams(params: Record<string, any>, data: Record<string, any>) {
20
+ if (typeof params !== 'object') {
21
+ return params;
22
+ }
23
+ const res = Object.assign({}, params);
24
+ Object.keys(params).forEach(key => {
25
+ if (typeof params[key] === 'string') {
26
+ const m = params[key].match(/^__(\w+)__$/)
27
+ if (m) {
28
+ res[key] = data[m[1]];
29
+ }
30
+ }
31
+ })
32
+ return res;
33
+ }
34
+
35
+ export function routerNavigateTo(url: string, config?: VisitOptions) {
36
+ return router.visit(url, {
37
+ ...config,
38
+ })
39
+ }
40
+
41
+ export function handleRules(dataRules: Rules, data: any) {
42
+ return new Promise(resolve => {
43
+ const validator = new Schema(dataRules);
44
+ validator.validate(data, (errors: ValidateError[] | null, fields: ValidateFieldsError | Values) => {
45
+ if (errors) {
46
+ resolve(false);
47
+ return;
48
+ }
49
+ resolve(true);
50
+ })
51
+
52
+ })
53
+
54
+ }
55
+
56
+ export async function asyncFilter(arr: any[], predicate: (item: any) => PromiseLike<any>) {
57
+ return await Promise.all(arr.map(predicate))
58
+ .then((results) => arr.filter((_v, index) => results[index]))
59
+ }
60
+
61
+ export function filterObjectKeys(obj: Record<string, any>, keysToKeep: string[]) {
62
+ if (typeof obj !== 'object' || !obj) {
63
+ return obj;
64
+ }
65
+ return Object.keys(obj)
66
+ .filter(key => !keysToKeep.includes(key))
67
+ .reduce((newObj, key) => {
68
+ newObj[key] = obj[key];
69
+ return newObj;
70
+ }, {} as Record<string, any>);
71
+ }
72
+
73
+
74
+ export function createScript(url: string) {
75
+ let scriptTags = window.document.querySelectorAll('script')
76
+ let len = scriptTags.length
77
+ let i = 0
78
+ let _url = window.location.origin + url
79
+ return new Promise((resolve, reject) => {
80
+ for (i = 0; i < len; i++) {
81
+ var src = scriptTags[i].src
82
+ if (src && src === _url) {
83
+ scriptTags[i].parentElement?.removeChild(scriptTags[i])
84
+ }
85
+ }
86
+
87
+ let node = document.createElement('script')
88
+ node.src = url
89
+ node.onload = resolve
90
+ document.body.appendChild(node)
91
+ })
92
+ }
93
+
94
+ export async function modalShow(options: ModalOptions) {
95
+ let props = options.content.props
96
+ if (options.content.url) {
97
+ const res = await http({
98
+ method: 'get',
99
+ url: options.content.url,
100
+ headers: {
101
+ 'X-Modal': '1',
102
+ }
103
+ })
104
+ if (typeof res.data === 'string') {
105
+ throw new Error('modal response is not vail')
106
+ }
107
+ props = res.data
108
+ }
109
+ if (!props) {
110
+ throw new Error('modal props is empty')
111
+ }
112
+ const Component = lazy(() => container.get('Modal.' + upperFirst(props.type)))
113
+
114
+ let afterClose = () => {
115
+ }
116
+ const modal = global.modal.info({
117
+ ...options,
118
+ closable: true,
119
+ icon: null,
120
+ destroyOnClose: true,
121
+ footer: null,
122
+ content: (
123
+ <Suspense fallback={<Spin/>}>
124
+ <ModalContext.Provider value={{
125
+ inModal: true,
126
+ closeModal: () => {
127
+ modal?.destroy()
128
+ },
129
+ contexts: options.contexts,
130
+ setAfterClose(callback: () => void) {
131
+ afterClose = callback
132
+ }
133
+ }}>
134
+ <Component {...props} />
135
+ </ModalContext.Provider>
136
+ </Suspense>
137
+ ),
138
+ afterClose: () => {
139
+ afterClose && afterClose()
140
+ },
141
+ })
142
+ return {
143
+ destroy: modal.destroy,
144
+ update: modal.update,
145
+ }
150
146
  }