form-driver 0.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.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/m3.css +310 -0
- package/dist/m3.js +1 -0
- package/es/m3.css +310 -0
- package/es/m3.js +20919 -0
- package/lib/m3.css +310 -0
- package/lib/m3.js +20959 -0
- package/package.json +132 -0
- package/src/.DS_Store +0 -0
- package/src/framework/Ajax.ts +96 -0
- package/src/framework/Assembly.tsx +165 -0
- package/src/framework/Init.tsx +196 -0
- package/src/framework/M3.tsx +94 -0
- package/src/framework/MContext.ts +15 -0
- package/src/framework/MFieldViewer.tsx +32 -0
- package/src/framework/MUtil.tsx +653 -0
- package/src/framework/MViewer.less +128 -0
- package/src/framework/MViewer.tsx +180 -0
- package/src/framework/MViewerDebug.tsx +95 -0
- package/src/framework/Persistant.ts +90 -0
- package/src/framework/Schema.ts +386 -0
- package/src/framework/SchemaFunc.ts +30 -0
- package/src/framework/Validator.ts +160 -0
- package/src/framework/editorMap.ts +109 -0
- package/src/index.ts +33 -0
- package/src/types/MArrayType.ts +73 -0
- package/src/types/MCascadeType.ts +35 -0
- package/src/types/MCnAddressType.ts +54 -0
- package/src/types/MDateRangeType.ts +52 -0
- package/src/types/MDateTimeType.ts +53 -0
- package/src/types/MDecorationType.ts +6 -0
- package/src/types/MEnumType.ts +65 -0
- package/src/types/MExperienceType.ts +81 -0
- package/src/types/MFloatType.ts +10 -0
- package/src/types/MGB2260Type.ts +56 -0
- package/src/types/MIntDiffType.ts +6 -0
- package/src/types/MIntType.ts +44 -0
- package/src/types/MKvSetType.ts +50 -0
- package/src/types/MMatrixType.ts +52 -0
- package/src/types/MObjectType.ts +89 -0
- package/src/types/MSetType.ts +220 -0
- package/src/types/MStringType.ts +27 -0
- package/src/types/MTelType.ts +14 -0
- package/src/types/MType.ts +77 -0
- package/src/types/MVLPairType.ts +35 -0
- package/src/types/gb2260.json +1 -0
- package/src/ui/BaseViewer.tsx +110 -0
- package/src/ui/editor/.DS_Store +0 -0
- package/src/ui/editor/basic/.DS_Store +0 -0
- package/src/ui/editor/basic/ACascadePicker.tsx +114 -0
- package/src/ui/editor/basic/ACheckBox.tsx +104 -0
- package/src/ui/editor/basic/ADatetimePicker.tsx +76 -0
- package/src/ui/editor/basic/AGB2260.tsx +52 -0
- package/src/ui/editor/basic/AInputBox.tsx +59 -0
- package/src/ui/editor/basic/AIntBox.tsx +39 -0
- package/src/ui/editor/basic/AKvSet.less +9 -0
- package/src/ui/editor/basic/AKvSet.tsx +90 -0
- package/src/ui/editor/basic/ARadio.tsx +86 -0
- package/src/ui/editor/basic/ARangePicker.tsx +129 -0
- package/src/ui/editor/basic/ARate.less +8 -0
- package/src/ui/editor/basic/ARate.tsx +37 -0
- package/src/ui/editor/basic/ARemoteSelector.tsx +116 -0
- package/src/ui/editor/basic/ASelector.tsx +88 -0
- package/src/ui/editor/basic/ASetSelector.tsx +65 -0
- package/src/ui/editor/basic/ASpecInputBox.tsx +20 -0
- package/src/ui/editor/basic/ATreeSelect.tsx +41 -0
- package/src/ui/editor/basic/AUpload.tsx +119 -0
- package/src/ui/editor/basic/NPS.less +21 -0
- package/src/ui/editor/basic/NPS.tsx +47 -0
- package/src/ui/editor/complex/AArray.less +10 -0
- package/src/ui/editor/complex/AArray.tsx +104 -0
- package/src/ui/editor/complex/AArrayGrid.tsx +115 -0
- package/src/ui/editor/complex/ACnAddress.less +15 -0
- package/src/ui/editor/complex/ACnAddress.tsx +61 -0
- package/src/ui/editor/complex/ADialogForm.tsx +45 -0
- package/src/ui/editor/complex/AExperience.tsx +85 -0
- package/src/ui/editor/complex/AForm.less +35 -0
- package/src/ui/editor/complex/AForm.tsx +340 -0
- package/src/ui/editor/complex/AIntDiff.tsx +77 -0
- package/src/ui/editor/complex/AMatrix.less +18 -0
- package/src/ui/editor/complex/AMatrix.tsx +242 -0
- package/src/ui/editor/complex/ATable.less +4 -0
- package/src/ui/editor/complex/ATable.tsx +33 -0
- package/src/ui/editor/complex/JsonEditor.tsx +37 -0
- package/src/ui/readable/A.tsx +33 -0
- package/src/ui/readable/ArrayViewer.tsx +46 -0
- package/src/ui/readable/DecorationViewer.tsx +76 -0
- package/src/ui/readable/DivViewer.tsx +11 -0
- package/src/ui/widget/Collapsible.tsx +156 -0
- package/src/ui/widget/Segment.less +39 -0
- package/src/ui/widget/Segment.tsx +40 -0
- package/src/ui/widget/SegmentEditSwitch.tsx +46 -0
- package/src/ui/widget/SelectBox.tsx +43 -0
- package/src/ui/widget/UnderlineInputBox.less +47 -0
- package/src/ui/widget/UnderlineInputBox.tsx +10 -0
- package/types/framework/Ajax.d.ts +5 -0
- package/types/framework/Assembly.d.ts +59 -0
- package/types/framework/Init.d.ts +4 -0
- package/types/framework/M3.d.ts +6 -0
- package/types/framework/MContext.d.ts +11 -0
- package/types/framework/MFieldViewer.d.ts +8 -0
- package/types/framework/MUtil.d.ts +180 -0
- package/types/framework/MViewer.d.ts +75 -0
- package/types/framework/MViewerDebug.d.ts +11 -0
- package/types/framework/Persistant.d.ts +17 -0
- package/types/framework/Schema.d.ts +306 -0
- package/types/framework/SchemaFunc.d.ts +14 -0
- package/types/framework/Validator.d.ts +53 -0
- package/types/framework/editorMap.d.ts +107 -0
- package/types/index.d.ts +21 -0
- package/types/types/MArrayType.d.ts +2 -0
- package/types/types/MCascadeType.d.ts +11 -0
- package/types/types/MCnAddressType.d.ts +2 -0
- package/types/types/MDateRangeType.d.ts +7 -0
- package/types/types/MDateTimeType.d.ts +11 -0
- package/types/types/MDecorationType.d.ts +7 -0
- package/types/types/MEnumType.d.ts +2 -0
- package/types/types/MExperienceType.d.ts +5 -0
- package/types/types/MFloatType.d.ts +2 -0
- package/types/types/MGB2260Type.d.ts +9 -0
- package/types/types/MIntDiffType.d.ts +2 -0
- package/types/types/MIntType.d.ts +2 -0
- package/types/types/MKvSetType.d.ts +11 -0
- package/types/types/MMatrixType.d.ts +5 -0
- package/types/types/MObjectType.d.ts +11 -0
- package/types/types/MSetType.d.ts +7 -0
- package/types/types/MStringType.d.ts +2 -0
- package/types/types/MTelType.d.ts +4 -0
- package/types/types/MType.d.ts +46 -0
- package/types/types/MVLPairType.d.ts +5 -0
- package/types/ui/BaseViewer.d.ts +45 -0
- package/types/ui/editor/basic/ACascadePicker.d.ts +11 -0
- package/types/ui/editor/basic/ACheckBox.d.ts +17 -0
- package/types/ui/editor/basic/ADatetimePicker.d.ts +15 -0
- package/types/ui/editor/basic/AGB2260.d.ts +10 -0
- package/types/ui/editor/basic/AInputBox.d.ts +8 -0
- package/types/ui/editor/basic/AIntBox.d.ts +9 -0
- package/types/ui/editor/basic/AKvSet.d.ts +19 -0
- package/types/ui/editor/basic/ARadio.d.ts +14 -0
- package/types/ui/editor/basic/ARangePicker.d.ts +30 -0
- package/types/ui/editor/basic/ARate.d.ts +13 -0
- package/types/ui/editor/basic/ARemoteSelector.d.ts +15 -0
- package/types/ui/editor/basic/ASelector.d.ts +14 -0
- package/types/ui/editor/basic/ASetSelector.d.ts +10 -0
- package/types/ui/editor/basic/ASpecInputBox.d.ts +9 -0
- package/types/ui/editor/basic/ATreeSelect.d.ts +18 -0
- package/types/ui/editor/basic/AUpload.d.ts +33 -0
- package/types/ui/editor/basic/NPS.d.ts +13 -0
- package/types/ui/editor/complex/AArray.d.ts +11 -0
- package/types/ui/editor/complex/AArrayGrid.d.ts +13 -0
- package/types/ui/editor/complex/ACnAddress.d.ts +10 -0
- package/types/ui/editor/complex/ADialogForm.d.ts +11 -0
- package/types/ui/editor/complex/AExperience.d.ts +16 -0
- package/types/ui/editor/complex/AForm.d.ts +46 -0
- package/types/ui/editor/complex/AIntDiff.d.ts +14 -0
- package/types/ui/editor/complex/AMatrix.d.ts +48 -0
- package/types/ui/editor/complex/ATable.d.ts +9 -0
- package/types/ui/editor/complex/JsonEditor.d.ts +9 -0
- package/types/ui/readable/A.d.ts +5 -0
- package/types/ui/readable/ArrayViewer.d.ts +5 -0
- package/types/ui/readable/DecorationViewer.d.ts +3 -0
- package/types/ui/readable/DivViewer.d.ts +5 -0
- package/types/ui/widget/Collapsible.d.ts +46 -0
- package/types/ui/widget/Segment.d.ts +18 -0
- package/types/ui/widget/SegmentEditSwitch.d.ts +20 -0
- package/types/ui/widget/SelectBox.d.ts +13 -0
- package/types/ui/widget/UnderlineInputBox.d.ts +6 -0
package/package.json
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "form-driver",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "An efficient framework for creating forms.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"authors": [
|
|
7
|
+
"龙湖 <59775976@qq.com>",
|
|
8
|
+
"云开 <2313303800@qq.com>"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "webpack-dev-server --inline --progress --config webpack.demo.js --compress",
|
|
12
|
+
"clean": "rimraf lib dist es coverage types",
|
|
13
|
+
"build": "rollup -c",
|
|
14
|
+
"b": "npm run clean && npm run build",
|
|
15
|
+
"i": "tnpm install && tnpm install @ali/m3 @ali/m3-plugin-richtext @ali/m3-plugin-hp-org",
|
|
16
|
+
"ri": "rm -rf node_modules && npm run i",
|
|
17
|
+
"pub": "npm run b && npm version patch && npm publish && git push",
|
|
18
|
+
"patch": "npm version patch && npm publish && git push",
|
|
19
|
+
"submodule": "git submodule update --init",
|
|
20
|
+
"ut-pull": "cd ./demo/src/ut_autoTest/ut_case && git pull",
|
|
21
|
+
"ut-test": "cd ./demo/src/ut_autoTest/ut_case && source ./.venv/bin/activate && python run_ui.py",
|
|
22
|
+
"demo:build": "cross-env NODE_ENV=production webpack --config webpack.demo.js",
|
|
23
|
+
"docs:i": "cd docs && tnpm install",
|
|
24
|
+
"docs:ri": "cd docs && rm -rf node_modules && npm run i",
|
|
25
|
+
"docs:start": "cd docs && dumi dev",
|
|
26
|
+
"docs:build": "cd docs && dumi build",
|
|
27
|
+
"docs:upload": "cd docs && hp upload ./dist m3/ --free",
|
|
28
|
+
"docs:pub": "cd docs && npm run build && npm run upload"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"m3",
|
|
32
|
+
"form",
|
|
33
|
+
"form-driver"
|
|
34
|
+
],
|
|
35
|
+
"homepage": "https://github.com/alibaba/form-driver",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/alibaba/form-driver/issues"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/alibaba/form-driver.git"
|
|
42
|
+
},
|
|
43
|
+
"main": "lib/m3.js",
|
|
44
|
+
"module": "es/m3.js",
|
|
45
|
+
"unpkg": "dist/m3.js",
|
|
46
|
+
"types": "types/index.d.ts",
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"lib",
|
|
50
|
+
"es",
|
|
51
|
+
"src",
|
|
52
|
+
"types"
|
|
53
|
+
],
|
|
54
|
+
"displayName": "form-driver",
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@ant-design/icons": "^4.3.0",
|
|
57
|
+
"@babel/runtime": "^7.9.2",
|
|
58
|
+
"@testing-library/jest-dom": "^5.11.4",
|
|
59
|
+
"@testing-library/react": "^11.1.0",
|
|
60
|
+
"@testing-library/user-event": "^12.1.10",
|
|
61
|
+
"antd": "^4.16.5",
|
|
62
|
+
"antd-mobile": "^2.3.4",
|
|
63
|
+
"lodash": "^4.17.20",
|
|
64
|
+
"moment": "^2.29.1",
|
|
65
|
+
"react": "^17.0.1",
|
|
66
|
+
"react-dom": "^17.0.1"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@ant-design/tools": "^13.5.0-beta.1",
|
|
70
|
+
"@babel/cli": "^7.12.10",
|
|
71
|
+
"@babel/core": "^7.12.10",
|
|
72
|
+
"@babel/plugin-external-helpers": "^7.12.1",
|
|
73
|
+
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
|
74
|
+
"@babel/plugin-proposal-decorators": "^7.12.12",
|
|
75
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
|
|
76
|
+
"@babel/plugin-transform-react-display-name": "^7.12.1",
|
|
77
|
+
"@babel/plugin-transform-react-jsx": "^7.12.12",
|
|
78
|
+
"@babel/plugin-transform-runtime": "^7.12.10",
|
|
79
|
+
"@babel/preset-env": "^7.12.11",
|
|
80
|
+
"@babel/preset-react": "^7.12.10",
|
|
81
|
+
"@babel/preset-typescript": "^7.12.7",
|
|
82
|
+
"@rollup/plugin-babel": "^5.0.0",
|
|
83
|
+
"@rollup/plugin-image": "^2.0.6",
|
|
84
|
+
"@rollup/plugin-replace": "^2.3.2",
|
|
85
|
+
"@types/lodash": "^4.14.165",
|
|
86
|
+
"@types/node": "^14.14.10",
|
|
87
|
+
"@types/react": "^17.0.0",
|
|
88
|
+
"@types/react-dom": "^17.0.0",
|
|
89
|
+
"babel-core": "^7.0.0-0",
|
|
90
|
+
"babel-eslint": "^8.0.1",
|
|
91
|
+
"babel-jest": "^22.2.2",
|
|
92
|
+
"babel-loader": "^7.1.2",
|
|
93
|
+
"babel-plugin-import": "^1.13.3",
|
|
94
|
+
"cross-env": "^7.0.3",
|
|
95
|
+
"css-loader": "^0.28.0",
|
|
96
|
+
"css-minimizer-webpack-plugin": "^3.0.0",
|
|
97
|
+
"dingtalk-jsapi": "^2.13.20",
|
|
98
|
+
"happypack": "^5.0.1",
|
|
99
|
+
"html-loader": "^0.5.1",
|
|
100
|
+
"html-webpack-plugin": "^3.2.0",
|
|
101
|
+
"less": "^3.11.1",
|
|
102
|
+
"less-loader": "^7.2.1",
|
|
103
|
+
"mini-css-extract-plugin": "^0.5.0",
|
|
104
|
+
"npm-run-all": "^4.1.1",
|
|
105
|
+
"postcss": "^8.2.4",
|
|
106
|
+
"postcss-cssnext": "^3.1.0",
|
|
107
|
+
"postcss-nested": "^5.0.3",
|
|
108
|
+
"postcss-preset-env": "^6.7.0",
|
|
109
|
+
"postcss-simple-vars": "^6.0.2",
|
|
110
|
+
"react-intl": "^5.18.1",
|
|
111
|
+
"rimraf": "^2.5.2",
|
|
112
|
+
"rollup": "^2.38.0",
|
|
113
|
+
"rollup-plugin-babel": "^4.4.0",
|
|
114
|
+
"rollup-plugin-commonjs": "^10.1.0",
|
|
115
|
+
"rollup-plugin-json": "^4.0.0",
|
|
116
|
+
"rollup-plugin-node-resolve": "^5.2.0",
|
|
117
|
+
"rollup-plugin-postcss": "^4.0.0",
|
|
118
|
+
"rollup-plugin-serve": "^1.0.1",
|
|
119
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
120
|
+
"rollup-plugin-typescript2": "^0.29.0",
|
|
121
|
+
"style-loader": "^0.20.0",
|
|
122
|
+
"ts-loader": "^8.0.14",
|
|
123
|
+
"ts-node-dev": "^1.0.0",
|
|
124
|
+
"typescript": "^3.8.3",
|
|
125
|
+
"webpack": "^4.16.1",
|
|
126
|
+
"webpack-cli": "^3.1.0",
|
|
127
|
+
"webpack-dev-server": "^3.1.11"
|
|
128
|
+
},
|
|
129
|
+
"engines": {
|
|
130
|
+
"node": ">=v14.15.4"
|
|
131
|
+
}
|
|
132
|
+
}
|
package/src/.DS_Store
ADDED
|
Binary file
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { message } from 'antd';
|
|
2
|
+
|
|
3
|
+
function generateQueryStr(obj = {}) {
|
|
4
|
+
let str = ''
|
|
5
|
+
const keys = Object.keys(obj)
|
|
6
|
+
if (keys.length > 0) {
|
|
7
|
+
const arr = []
|
|
8
|
+
keys.forEach(k => {
|
|
9
|
+
arr.push(`${k}=${encodeURIComponent(obj[k])}`)
|
|
10
|
+
})
|
|
11
|
+
str = `?${arr.join('&')}`
|
|
12
|
+
}
|
|
13
|
+
return str
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Ajax = {
|
|
17
|
+
req(method:'GET'|'POST'|'PUT', apiPath:string, urlArgs:any, body:any, headers:any,
|
|
18
|
+
prompt:any = {succ:"提交完成", networkFail:"网络异常", bizFail:"提交失败"}):Promise<any> {
|
|
19
|
+
const args = {
|
|
20
|
+
method: method,
|
|
21
|
+
body: JSON.stringify(body),
|
|
22
|
+
headers: {'Content-Type': 'application/json', ...headers}
|
|
23
|
+
}
|
|
24
|
+
return new Promise<any>(function(resolve, reject) {
|
|
25
|
+
fetch(`${apiPath}${generateQueryStr(urlArgs)}`, args)
|
|
26
|
+
.then(d => d.json())
|
|
27
|
+
.then(resp => {
|
|
28
|
+
if(resp.errorCode === 0) {
|
|
29
|
+
if(prompt.succ){
|
|
30
|
+
message.success(prompt.succ);
|
|
31
|
+
}
|
|
32
|
+
resolve(resp);
|
|
33
|
+
} else {
|
|
34
|
+
message.error(resp.message ?? prompt.bizFail);
|
|
35
|
+
reject(resp);
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
.catch(e=>{
|
|
39
|
+
console.log(e);
|
|
40
|
+
message.error(prompt.networkFail);
|
|
41
|
+
reject();
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
post(apiPath:string, data:any, succMsg:string = "提交完成"):Promise<any> {
|
|
47
|
+
const args = {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
body:JSON.stringify(data),
|
|
50
|
+
headers: {'Content-Type': 'application/json'}
|
|
51
|
+
}
|
|
52
|
+
return new Promise<any>(function(resolve, reject){
|
|
53
|
+
fetch(apiPath, args)
|
|
54
|
+
.then(d => d.json())
|
|
55
|
+
.then(resp => {
|
|
56
|
+
if(resp.errorCode === 0) {
|
|
57
|
+
if(succMsg){
|
|
58
|
+
message.success(succMsg);
|
|
59
|
+
}
|
|
60
|
+
resolve(resp);
|
|
61
|
+
} else {
|
|
62
|
+
message.error(resp.message);
|
|
63
|
+
reject(resp);
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
.catch(e=>{
|
|
67
|
+
console.log(e);
|
|
68
|
+
message.error("网络异常");
|
|
69
|
+
reject();
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
get(apiPath:string, data?:object):Promise<any> {
|
|
75
|
+
if (data) {
|
|
76
|
+
apiPath = `${apiPath}${generateQueryStr(data)}`
|
|
77
|
+
}
|
|
78
|
+
return new Promise<void>(function(resolve, reject){
|
|
79
|
+
fetch(apiPath)
|
|
80
|
+
.then(res => res.json())
|
|
81
|
+
.then(resp => {
|
|
82
|
+
if(resp.errorCode === 0) {
|
|
83
|
+
resolve(resp);
|
|
84
|
+
} else {
|
|
85
|
+
message.error(resp.message);
|
|
86
|
+
reject();
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
.catch(e=>{
|
|
90
|
+
message.error("网络异常");
|
|
91
|
+
reject();
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import React, { ClassType } from "react";
|
|
2
|
+
import { MValidationResult, MFieldSchemaAnonymity, MProp, MValidationFail } from './Schema';
|
|
3
|
+
import _ from "lodash";
|
|
4
|
+
import { MUtil } from './MUtil';
|
|
5
|
+
import { MType, PluginType } from "../types/MType";
|
|
6
|
+
|
|
7
|
+
export type MORPH = "readable" | "editor";
|
|
8
|
+
export type VIEWER = ClassType<MProp, any, any>
|
|
9
|
+
|
|
10
|
+
/** 统一的视觉样式 */
|
|
11
|
+
export interface MTheme {
|
|
12
|
+
// 负向数据展示文案
|
|
13
|
+
/** 数据未知时展示 */
|
|
14
|
+
readonly READABLE_UNKNOWN: string;
|
|
15
|
+
/** 数据为空的时候展示 */
|
|
16
|
+
readonly READABLE_BLANK: string;
|
|
17
|
+
/** 数据有问题时展示 */
|
|
18
|
+
readonly READABLE_INVALID: string;
|
|
19
|
+
/** 代码有问题时展示 */
|
|
20
|
+
readonly READABLE_ERROR: string;
|
|
21
|
+
|
|
22
|
+
/** @deprecated theme的名字 */
|
|
23
|
+
readonly themeName: "antMiddle" | string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface EDITOR {
|
|
27
|
+
// 编辑器
|
|
28
|
+
editor: string;
|
|
29
|
+
// 数据类型
|
|
30
|
+
type: string;
|
|
31
|
+
// 阅读器
|
|
32
|
+
readable: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const defaultTheme: MTheme = {
|
|
36
|
+
READABLE_UNKNOWN: "?",
|
|
37
|
+
READABLE_BLANK: "-",
|
|
38
|
+
READABLE_INVALID: "❓",
|
|
39
|
+
READABLE_ERROR: "❗",
|
|
40
|
+
|
|
41
|
+
themeName: "antMiddle"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let rootHideMap = {}
|
|
45
|
+
/**
|
|
46
|
+
* 注册viewer,type,morph(viewer和type之间的关联)
|
|
47
|
+
*/
|
|
48
|
+
export class Assembly {
|
|
49
|
+
types: { [name: string]: MType } = {};
|
|
50
|
+
viewers: { [name: string]: VIEWER } = {};
|
|
51
|
+
editors: { [name: string]: EDITOR } = {};
|
|
52
|
+
morph: { [name: /*MORPH*/ string]: { [typeName: string]: string | ClassType<MProp, any, any> /* viewer name or viewer */ } } = {}
|
|
53
|
+
|
|
54
|
+
theme: MTheme = defaultTheme;
|
|
55
|
+
|
|
56
|
+
toReadable = (s: MFieldSchemaAnonymity, v: any, parent: any): string => {
|
|
57
|
+
const t = this.types[s.type];
|
|
58
|
+
if (t) {
|
|
59
|
+
let r;
|
|
60
|
+
if (_.isString(s.toReadable)) {
|
|
61
|
+
// eslint-disable-next-line no-new-func
|
|
62
|
+
r = new Function("_", "value", "theme",
|
|
63
|
+
"const {READABLE_UNKNOWN, READABLE_BLANK, READABLE_INVALID, READABLE_ERROR} = theme; return " + s.toReadable)(_, v, this.theme);
|
|
64
|
+
} else if (_.isFunction(s.toReadable)) {
|
|
65
|
+
r = s.toReadable(v, parent, this);
|
|
66
|
+
}
|
|
67
|
+
r = r ?? t.toReadable(this, s, v);
|
|
68
|
+
|
|
69
|
+
if (s.postfix) {
|
|
70
|
+
r += s.postfix;
|
|
71
|
+
}
|
|
72
|
+
return r;
|
|
73
|
+
} else {
|
|
74
|
+
return s.type + "类型无效"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** 根据定义返回View,返回nil表示没有可用的View */
|
|
79
|
+
getViewerOf(f: MFieldSchemaAnonymity, morph: MORPH): ClassType<any, any, any> {
|
|
80
|
+
if (f.editor && morph === "editor") {
|
|
81
|
+
if (_.isString(f.editor)) {
|
|
82
|
+
return _.get(this.viewers, f.editor);
|
|
83
|
+
} else {
|
|
84
|
+
return f.editor;
|
|
85
|
+
}
|
|
86
|
+
} else if (f.readable && morph === "readable") {
|
|
87
|
+
if (_.isString(f.readable)) {
|
|
88
|
+
return _.get(this.viewers, f.readable);
|
|
89
|
+
} else {
|
|
90
|
+
return f.readable;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const viewer: string | ClassType<MProp, any, any> = _.get(this.morph, morph + "." + f.type);
|
|
94
|
+
if (_.isString(viewer)) {
|
|
95
|
+
return _.get(this.viewers, viewer);
|
|
96
|
+
} else {
|
|
97
|
+
return viewer
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
validate(s: MFieldSchemaAnonymity, v: any, path: string = ""): MValidationFail | undefined {
|
|
103
|
+
let result: MValidationResult = undefined;
|
|
104
|
+
for (let validator of this.types[s.type].validators) {
|
|
105
|
+
result = validator(this, s, v, path);
|
|
106
|
+
if (result === "pass") {
|
|
107
|
+
return undefined;
|
|
108
|
+
} else if (result) {
|
|
109
|
+
MUtil.debug("校验", path, result.message);
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
addViewer(name: string, v: VIEWER) {
|
|
117
|
+
if (this.viewers[name]) {
|
|
118
|
+
console.error(`addViewer: 已经存在名为 ${name} 的 Viewer,无法再次添加!`)
|
|
119
|
+
return
|
|
120
|
+
} else {
|
|
121
|
+
this.viewers[name] = v;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
addEditor(name: string, v: EDITOR) {
|
|
126
|
+
if (this.editors[name]) {
|
|
127
|
+
console.error(`addEditor: 已经存在名为 ${name} 的 Editor,无法再次添加!`)
|
|
128
|
+
return
|
|
129
|
+
} else {
|
|
130
|
+
this.editors[name] = v;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 增加一种数据类型
|
|
136
|
+
* 例:
|
|
137
|
+
* const hpOrg = {name: "hpOrg", type: {validators: ..., toReadable: ...}, editor: HPOrgEditor, readable: "DivViewer"}
|
|
138
|
+
* addType(hpOrg)
|
|
139
|
+
* @param typeParam 类型的描述对象
|
|
140
|
+
*/
|
|
141
|
+
addType(typeParam: PluginType) {
|
|
142
|
+
const { name, type, editor, readable = "DivViewer" } = typeParam
|
|
143
|
+
this.types[name] = type;
|
|
144
|
+
_.set(this.morph, "editor." + name, editor);
|
|
145
|
+
_.set(this.morph, "readable." + name, readable);
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
constructor() {
|
|
150
|
+
// 校验types是否使用了无效的编辑器名字
|
|
151
|
+
for (let morphName in this.morph) {
|
|
152
|
+
for (let typeName in this.morph[morphName]) {
|
|
153
|
+
if (!this.types[typeName]) {
|
|
154
|
+
throw SyntaxError(`类型${typeName}未定义`);
|
|
155
|
+
}
|
|
156
|
+
const viewerName = this.morph[morphName][typeName];
|
|
157
|
+
if (!this.viewers[viewerName]) {
|
|
158
|
+
throw SyntaxError(`视图${viewerName}未定义`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const assembly: Assembly = new Assembly();
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { assembly } from './Assembly';
|
|
2
|
+
import { MEnumType } from "../types/MEnumType";
|
|
3
|
+
import { MGB2260Type } from "../types/MGB2260Type";
|
|
4
|
+
import { MDateTimeType } from '../types/MDateTimeType';
|
|
5
|
+
import { MSetType } from '../types/MSetType';
|
|
6
|
+
import { MArrayType } from "../types/MArrayType";
|
|
7
|
+
import { MStringType } from '../types/MStringType';
|
|
8
|
+
import { MIntDiffType } from '../types/MIntDiffType';
|
|
9
|
+
import { MIntType } from '../types/MIntType';
|
|
10
|
+
import { MMatrixType } from "../types/MMatrixType";
|
|
11
|
+
import { MObjectType } from "../types/MObjectType";
|
|
12
|
+
import { MExperienceType } from "../types/MExperienceType";
|
|
13
|
+
import { MCnAddress } from "../types/MCnAddressType";
|
|
14
|
+
import { MTelType, MCnPhoneType, MEmailType } from '../types/MTelType';
|
|
15
|
+
import { MDateRangeType } from "../types/MDateRangeType";
|
|
16
|
+
import { ArrayViewer } from '../ui/readable/ArrayViewer';
|
|
17
|
+
import { ADatetimePicker } from "../ui/editor/basic/ADatetimePicker";
|
|
18
|
+
import { AGB2260 } from "../ui/editor/basic/AGB2260";
|
|
19
|
+
import { ARadio } from "../ui/editor/basic/ARadio";
|
|
20
|
+
import { ARate } from "../ui/editor/basic/ARate";
|
|
21
|
+
import { AUpload } from "../ui/editor/basic/AUpload";
|
|
22
|
+
import { ATreeSelect } from "../ui/editor/basic/ATreeSelect";
|
|
23
|
+
import { NPS } from "../ui/editor/basic/NPS";
|
|
24
|
+
import { AIntBox } from "../ui/editor/basic/AIntBox";
|
|
25
|
+
import { ACheckBox } from "../ui/editor/basic/ACheckBox";
|
|
26
|
+
import { AInputBox } from "../ui/editor/basic/AInputBox";
|
|
27
|
+
import { AMatrix } from '../ui/editor/complex/AMatrix';
|
|
28
|
+
import { ASpecInputBox } from '../ui/editor/basic/ASpecInputBox';
|
|
29
|
+
import { AForm } from '../ui/editor/complex/AForm';
|
|
30
|
+
import { DivViewer } from '../ui/readable/DivViewer';
|
|
31
|
+
import { ASelector } from "../ui/editor/basic/ASelector";
|
|
32
|
+
import { ASetSelector } from '../ui/editor/basic/ASetSelector';
|
|
33
|
+
import { AExperience } from '../ui/editor/complex/AExperience';
|
|
34
|
+
import { ACnAddress } from '../ui/editor/complex/ACnAddress';
|
|
35
|
+
import { AArray } from '../ui/editor/complex/AArray';
|
|
36
|
+
import { AArrayGrid } from '../ui/editor/complex/AArrayGrid';
|
|
37
|
+
import { ARangePicker } from '../ui/editor/basic/ARangePicker';
|
|
38
|
+
import { AIntDiff } from '../ui/editor/complex/AIntDiff';
|
|
39
|
+
import { MFloatType } from '../types/MFloatType';
|
|
40
|
+
import { MDecorationType } from '../types/MDecorationType';
|
|
41
|
+
import { DecorationViewer } from '../ui/readable/DecorationViewer';
|
|
42
|
+
import { ATable } from '../ui/editor/complex/ATable';
|
|
43
|
+
import { ARemoteSelector } from '../ui/editor/basic/ARemoteSelector';
|
|
44
|
+
import { JsonEditor } from '../ui/editor/complex/JsonEditor';
|
|
45
|
+
import _ from "lodash";
|
|
46
|
+
import { A } from '../ui/readable/A';
|
|
47
|
+
import { ADialogForm } from '../ui/editor/complex/ADialogForm';
|
|
48
|
+
import { MVLPairType } from '../types/MVLPairType';
|
|
49
|
+
import { MKvSetType } from '../types/MKvSetType';
|
|
50
|
+
import { AKvSet } from '../ui/editor/basic/AKvSet';
|
|
51
|
+
import { ACascadePicker } from '../ui/editor/basic/ACascadePicker';
|
|
52
|
+
import { MCascadeType } from '../types/MCascadeType';
|
|
53
|
+
import editorMap from './editorMap';
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
let init = false;
|
|
57
|
+
/**
|
|
58
|
+
* 确保m3已经初始化ensureM3
|
|
59
|
+
*/
|
|
60
|
+
export function ensureM3(){
|
|
61
|
+
if(init){
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
init = true;
|
|
65
|
+
assembly.types = _.merge(assembly.types, {
|
|
66
|
+
"enum": MEnumType,
|
|
67
|
+
"gb2260": MGB2260Type,
|
|
68
|
+
"datetime": MDateTimeType,
|
|
69
|
+
"year": MDateTimeType,
|
|
70
|
+
"yearMonth": MDateTimeType,
|
|
71
|
+
"yearMonthDay": MDateTimeType,
|
|
72
|
+
"set": MSetType,
|
|
73
|
+
"array": MArrayType,
|
|
74
|
+
"string": MStringType,
|
|
75
|
+
"intDiff": MIntDiffType,
|
|
76
|
+
"int": MIntType,
|
|
77
|
+
"float": MFloatType,
|
|
78
|
+
"matrix": MMatrixType,
|
|
79
|
+
"object": MObjectType,
|
|
80
|
+
"experience": MExperienceType,
|
|
81
|
+
"cnAddress": MCnAddress,
|
|
82
|
+
"tel": MTelType,
|
|
83
|
+
"email": MEmailType,
|
|
84
|
+
"cnPhone": MCnPhoneType,
|
|
85
|
+
"dateRange": MDateRangeType,
|
|
86
|
+
"decoration": MDecorationType,
|
|
87
|
+
"vl": MVLPairType,
|
|
88
|
+
"kvSet": MKvSetType,
|
|
89
|
+
"cascade": MCascadeType,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 实验性组件 AArray、ATable、ADialogForm、AForm、ASetSelector、JsonEditor
|
|
93
|
+
assembly.viewers = _.merge(assembly.viewers, {
|
|
94
|
+
"ADatetimePicker": ADatetimePicker,
|
|
95
|
+
"AGB2260": AGB2260,
|
|
96
|
+
"ARadio": ARadio,
|
|
97
|
+
"ARate": ARate,
|
|
98
|
+
"AUpload": AUpload,
|
|
99
|
+
"ATreeSelect": ATreeSelect,
|
|
100
|
+
"NPS": NPS,
|
|
101
|
+
"ACheckBox": ACheckBox,
|
|
102
|
+
"AIntBox": AIntBox,
|
|
103
|
+
"AInputBox": AInputBox,
|
|
104
|
+
"AMatrix": AMatrix,
|
|
105
|
+
"ASpecInputBox": ASpecInputBox,
|
|
106
|
+
"AForm": AForm,
|
|
107
|
+
"AArray": AArray,
|
|
108
|
+
"AArrayGrid": AArrayGrid,
|
|
109
|
+
"ARangePicker": ARangePicker,
|
|
110
|
+
"AIntDiff": AIntDiff,
|
|
111
|
+
"ACnAddress": ACnAddress,
|
|
112
|
+
"AExperience": AExperience,
|
|
113
|
+
"ASetSelector": ASetSelector,
|
|
114
|
+
"ASelector": ASelector,
|
|
115
|
+
"DivViewer": DivViewer,
|
|
116
|
+
"ArrayViewer": ArrayViewer,
|
|
117
|
+
"DecorationViewer": DecorationViewer,
|
|
118
|
+
"ATable": ATable,
|
|
119
|
+
"ARemoteSelector": ARemoteSelector,
|
|
120
|
+
"JsonEditor": JsonEditor,
|
|
121
|
+
"A": A,
|
|
122
|
+
"ADialogForm": ADialogForm,
|
|
123
|
+
"AKvSet": AKvSet,
|
|
124
|
+
"ACascadePicker": ACascadePicker,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
assembly.morph = _.merge(assembly.morph, {
|
|
128
|
+
// 编辑
|
|
129
|
+
"editor": {
|
|
130
|
+
"enum": "ASelector",
|
|
131
|
+
"gb2260":"AGB2260",
|
|
132
|
+
"datetime": "ADatetimePicker",
|
|
133
|
+
"year": "ADatetimePicker",
|
|
134
|
+
"yearMonth": "ADatetimePicker",
|
|
135
|
+
"yearMonthDay": "ADatetimePicker",
|
|
136
|
+
"set": "ACheckBox",
|
|
137
|
+
"array": "AArray",
|
|
138
|
+
"string": "AInputBox",
|
|
139
|
+
|
|
140
|
+
"intDiff": "AIntDiff",
|
|
141
|
+
"int": "AIntBox",
|
|
142
|
+
"float": "AIntBox",
|
|
143
|
+
|
|
144
|
+
"matrix": "AMatrix",
|
|
145
|
+
"object": "AForm",
|
|
146
|
+
|
|
147
|
+
"experience": "AExperience",
|
|
148
|
+
"kvSet": "AKvSet",
|
|
149
|
+
|
|
150
|
+
// TODO 这些类型还没有校验
|
|
151
|
+
"cnAddress": "ACnAddress",
|
|
152
|
+
"tel": "ASpecInputBox",
|
|
153
|
+
"email": "ASpecInputBox",
|
|
154
|
+
"cnPhone": "ASpecInputBox",
|
|
155
|
+
"dateRange": "ARangePicker",
|
|
156
|
+
"decoration": "DecorationViewer",
|
|
157
|
+
|
|
158
|
+
"vl": "ARemoteSelector",
|
|
159
|
+
"cascade": "ACascadePicker"
|
|
160
|
+
},
|
|
161
|
+
// 详情
|
|
162
|
+
"readable": {
|
|
163
|
+
"enum": "DivViewer",
|
|
164
|
+
"gb2260": "DivViewer",
|
|
165
|
+
"datetime": "DivViewer",
|
|
166
|
+
"year": "DivViewer",
|
|
167
|
+
"yearMonth": "DivViewer",
|
|
168
|
+
"yearMonthDay": "DivViewer",
|
|
169
|
+
|
|
170
|
+
"set": "DivViewer",
|
|
171
|
+
"array": "ArrayViewer",
|
|
172
|
+
"string": "DivViewer",
|
|
173
|
+
|
|
174
|
+
"intDiff": "DivViewer",
|
|
175
|
+
"int": "DivViewer",
|
|
176
|
+
"float": "DivViewer",
|
|
177
|
+
|
|
178
|
+
"matrix": "DivViewer",
|
|
179
|
+
"object": "AForm",
|
|
180
|
+
"experience": "DivViewer",
|
|
181
|
+
"kvSet": "DivViewer",
|
|
182
|
+
|
|
183
|
+
"cnAddress": "DivViewer",
|
|
184
|
+
"tel": "DivViewer",
|
|
185
|
+
"email": "DivViewer",
|
|
186
|
+
"cnPhone": "DivViewer",
|
|
187
|
+
"dateRange":"DivViewer",
|
|
188
|
+
"decoration": "DecorationViewer",
|
|
189
|
+
"vl": "DivViewer",
|
|
190
|
+
|
|
191
|
+
"cascade": "DivViewer"
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
assembly.editors = _.merge(assembly.editors, editorMap)
|
|
196
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import { M3Prop, MViewer } from './MViewer';
|
|
3
|
+
import { MViewerDebug } from './MViewerDebug';
|
|
4
|
+
import editorMap from './editorMap';
|
|
5
|
+
import { MFieldSchema, M3UISpec, MFieldSchemaAnonymity } from "../../src/framework/Schema";
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
|
|
8
|
+
// 外部 schema 转化为内部
|
|
9
|
+
function deal(fieldSchema: MFieldSchemaAnonymity | MFieldSchema) {
|
|
10
|
+
if(fieldSchema.arrayMember){
|
|
11
|
+
deal(fieldSchema.arrayMember);
|
|
12
|
+
} else if(fieldSchema.objectFields){
|
|
13
|
+
for(let f of fieldSchema.objectFields){
|
|
14
|
+
deal(f);
|
|
15
|
+
}
|
|
16
|
+
} else {
|
|
17
|
+
let opt = fieldSchema.option ?? fieldSchema.setFields ?? fieldSchema.enumFields
|
|
18
|
+
if (opt) {
|
|
19
|
+
if (typeof opt === 'string') {
|
|
20
|
+
fieldSchema.option = opt.split(" ").map(
|
|
21
|
+
aEnum => {
|
|
22
|
+
const kv = aEnum.split("=");
|
|
23
|
+
return { label: kv[0], value: kv[1] ?? kv[0] };
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
fieldSchema.option = opt
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fieldSchema.openOption = fieldSchema.openOption ?? fieldSchema.setOpen ?? fieldSchema.enumOpen
|
|
32
|
+
|
|
33
|
+
if (!fieldSchema.type && fieldSchema.editor) {
|
|
34
|
+
Object.assign(fieldSchema, editorMap[fieldSchema.editor])
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 标准化 schema
|
|
40
|
+
function standardSchema(schema: MFieldSchema | MFieldSchema[], layout?: M3UISpec) {
|
|
41
|
+
const _schema = _.cloneDeep(schema)
|
|
42
|
+
if (_.isArray(_schema)) {
|
|
43
|
+
_schema.forEach(item => {
|
|
44
|
+
deal(item)
|
|
45
|
+
})
|
|
46
|
+
const temp: MFieldSchema = {
|
|
47
|
+
name: '__root__',
|
|
48
|
+
type: 'object',
|
|
49
|
+
objectFields: _schema
|
|
50
|
+
}
|
|
51
|
+
if (layout) {
|
|
52
|
+
temp.uispec = layout
|
|
53
|
+
}
|
|
54
|
+
return _.cloneDeep(temp)
|
|
55
|
+
} else {
|
|
56
|
+
deal(_schema)
|
|
57
|
+
return _schema
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const M3 = (props: React.PropsWithChildren<M3Prop & { debug?: boolean }>) => {
|
|
63
|
+
const [prevProp, setPrevProp] = useState(props);
|
|
64
|
+
|
|
65
|
+
let [database, setDatabase] = useState(_.cloneDeep(props.database))
|
|
66
|
+
let [schema, setSchema] = useState(standardSchema(props.schema))
|
|
67
|
+
let [k, setK] = useState(0)
|
|
68
|
+
|
|
69
|
+
// debug 属性为真 且 页面地址携带 debug 参数,开启调试模式
|
|
70
|
+
let debug = props.debug || (window.location.search.indexOf("debug") >= 0 || window.location.hash.indexOf("debug") >= 0);
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if(props.schema != prevProp.schema) {
|
|
74
|
+
setSchema(standardSchema(props.schema))
|
|
75
|
+
setPrevProp(props);
|
|
76
|
+
setK(++k)
|
|
77
|
+
}
|
|
78
|
+
}, [props.schema])
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if(props.database != prevProp.database) {
|
|
82
|
+
setDatabase(_.cloneDeep(props.database))
|
|
83
|
+
setPrevProp(props);
|
|
84
|
+
setK(++k)
|
|
85
|
+
}
|
|
86
|
+
}, [props.database])
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
debug ? <MViewerDebug key={k} {...props} database={database} schema={schema} /> :
|
|
90
|
+
<MViewer key={k} {...props} database={database} schema={schema} />
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default M3;
|