copied mui theme to use as base for carbon theme w/ burnettk cullerton
This commit is contained in:
parent
c3c941126b
commit
bb7324616b
|
@ -18,6 +18,7 @@
|
|||
"@casl/react": "^3.1.0",
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/material": "^5.10.14",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@rjsf/core": "*",
|
||||
"@rjsf/mui": "^5.0.0-beta.13",
|
||||
|
@ -4447,7 +4448,6 @@
|
|||
"version": "5.0.0-alpha.106",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz",
|
||||
"integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
|
@ -4480,7 +4480,6 @@
|
|||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
|
||||
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.8.0"
|
||||
}
|
||||
|
@ -4488,20 +4487,17 @@
|
|||
"node_modules/@mui/base/node_modules/@emotion/memoize": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
|
||||
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
|
||||
"peer": true
|
||||
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
|
||||
},
|
||||
"node_modules/@mui/base/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@mui/core-downloads-tracker": {
|
||||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz",
|
||||
"integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui"
|
||||
|
@ -4537,7 +4533,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz",
|
||||
"integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/base": "5.0.0-alpha.106",
|
||||
|
@ -4581,14 +4576,12 @@
|
|||
"node_modules/@mui/material/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@mui/private-theming": {
|
||||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz",
|
||||
"integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/utils": "^5.10.14",
|
||||
|
@ -4615,7 +4608,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz",
|
||||
"integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
|
@ -4647,7 +4639,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz",
|
||||
"integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/private-theming": "^5.10.14",
|
||||
|
@ -4687,7 +4678,6 @@
|
|||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz",
|
||||
"integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "*"
|
||||
},
|
||||
|
@ -4701,7 +4691,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz",
|
||||
"integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
|
@ -4723,8 +4712,7 @@
|
|||
"node_modules/@mui/utils/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
|
@ -5921,7 +5909,6 @@
|
|||
"version": "17.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
|
||||
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -8977,7 +8964,6 @@
|
|||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
@ -34603,7 +34589,6 @@
|
|||
"version": "5.0.0-alpha.106",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz",
|
||||
"integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
|
@ -34619,7 +34604,6 @@
|
|||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
|
||||
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@emotion/memoize": "^0.8.0"
|
||||
}
|
||||
|
@ -34627,22 +34611,19 @@
|
|||
"@emotion/memoize": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
|
||||
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
|
||||
"peer": true
|
||||
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
|
||||
},
|
||||
"react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@mui/core-downloads-tracker": {
|
||||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz",
|
||||
"integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==",
|
||||
"peer": true
|
||||
"integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ=="
|
||||
},
|
||||
"@mui/icons-material": {
|
||||
"version": "5.10.14",
|
||||
|
@ -34657,7 +34638,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz",
|
||||
"integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/base": "5.0.0-alpha.106",
|
||||
|
@ -34676,8 +34656,7 @@
|
|||
"react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -34685,7 +34664,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz",
|
||||
"integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/utils": "^5.10.14",
|
||||
|
@ -34696,7 +34674,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz",
|
||||
"integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
|
@ -34708,7 +34685,6 @@
|
|||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz",
|
||||
"integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@mui/private-theming": "^5.10.14",
|
||||
|
@ -34724,14 +34700,12 @@
|
|||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz",
|
||||
"integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==",
|
||||
"peer": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@mui/utils": {
|
||||
"version": "5.10.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz",
|
||||
"integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.1",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
|
@ -34743,8 +34717,7 @@
|
|||
"react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"peer": true
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -35627,7 +35600,6 @@
|
|||
"version": "17.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
|
||||
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -37942,8 +37914,7 @@
|
|||
"clsx": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
|
||||
"peer": true
|
||||
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"@casl/react": "^3.1.0",
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/material": "^5.10.14",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@rjsf/core": "*",
|
||||
"@rjsf/mui": "^5.0.0-beta.13",
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom';
|
||||
// import Form from '@rjsf/core';
|
||||
import Form from '@rjsf/mui';
|
||||
import validator from '@rjsf/validator-ajv8';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -9,7 +7,7 @@ import { Button, Stack } from '@carbon/react';
|
|||
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
// import Form from '../themes';
|
||||
import Form from '../themes/carbon';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ErrorContext from '../contexts/ErrorContext';
|
||||
import { modifyProcessModelPath } from '../helpers';
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { IconButtonProps } from '@rjsf/utils';
|
||||
|
||||
const AddButton: React.ComponentType<IconButtonProps> = ({
|
||||
uiSchema,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<IconButton title="Add Item" {...props} color="primary">
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddButton;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './AddButton';
|
||||
export * from './AddButton';
|
|
@ -0,0 +1,72 @@
|
|||
import React, { CSSProperties } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import { ArrayFieldTemplateItemType } from '@rjsf/utils';
|
||||
|
||||
function ArrayFieldItemTemplate(props: ArrayFieldTemplateItemType) {
|
||||
const {
|
||||
children,
|
||||
disabled,
|
||||
hasToolbar,
|
||||
hasMoveDown,
|
||||
hasMoveUp,
|
||||
hasRemove,
|
||||
index,
|
||||
onDropIndexClick,
|
||||
onReorderClick,
|
||||
readonly,
|
||||
uiSchema,
|
||||
registry,
|
||||
} = props;
|
||||
const { MoveDownButton, MoveUpButton, RemoveButton } =
|
||||
registry.templates.ButtonTemplates;
|
||||
const btnStyle: CSSProperties = {
|
||||
flex: 1,
|
||||
paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
fontWeight: 'bold',
|
||||
minWidth: 0,
|
||||
};
|
||||
return (
|
||||
<Grid container alignItems="center">
|
||||
<Grid item xs style={{ overflow: 'auto' }}>
|
||||
<Box mb={2}>
|
||||
<Paper elevation={2}>
|
||||
<Box p={2}>{children}</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Grid>
|
||||
{hasToolbar && (
|
||||
<Grid item>
|
||||
{(hasMoveUp || hasMoveDown) && (
|
||||
<MoveUpButton
|
||||
style={btnStyle}
|
||||
disabled={disabled || readonly || !hasMoveUp}
|
||||
onClick={onReorderClick(index, index - 1)}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
)}
|
||||
{(hasMoveUp || hasMoveDown) && (
|
||||
<MoveDownButton
|
||||
style={btnStyle}
|
||||
disabled={disabled || readonly || !hasMoveDown}
|
||||
onClick={onReorderClick(index, index + 1)}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
)}
|
||||
{hasRemove && (
|
||||
<RemoveButton
|
||||
style={btnStyle}
|
||||
disabled={disabled || readonly}
|
||||
onClick={onDropIndexClick(index)}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
export default ArrayFieldItemTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './ArrayFieldItemTemplate';
|
||||
export * from './ArrayFieldItemTemplate';
|
|
@ -0,0 +1,90 @@
|
|||
import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import {
|
||||
ArrayFieldTemplateItemType,
|
||||
ArrayFieldTemplateProps,
|
||||
getTemplate,
|
||||
getUiOptions,
|
||||
} from '@rjsf/utils';
|
||||
|
||||
function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
|
||||
const {
|
||||
canAdd,
|
||||
disabled,
|
||||
idSchema,
|
||||
uiSchema,
|
||||
items,
|
||||
onAddClick,
|
||||
readonly,
|
||||
registry,
|
||||
required,
|
||||
schema,
|
||||
title,
|
||||
} = props;
|
||||
const uiOptions = getUiOptions(uiSchema);
|
||||
const ArrayFieldDescriptionTemplate =
|
||||
getTemplate<'ArrayFieldDescriptionTemplate'>(
|
||||
'ArrayFieldDescriptionTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
const ArrayFieldItemTemplate = getTemplate<'ArrayFieldItemTemplate'>(
|
||||
'ArrayFieldItemTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
const ArrayFieldTitleTemplate = getTemplate<'ArrayFieldTitleTemplate'>(
|
||||
'ArrayFieldTitleTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
// Button templates are not overridden in the uiSchema
|
||||
const {
|
||||
ButtonTemplates: { AddButton },
|
||||
} = registry.templates;
|
||||
return (
|
||||
<Paper elevation={2}>
|
||||
<Box p={2}>
|
||||
<ArrayFieldTitleTemplate
|
||||
idSchema={idSchema}
|
||||
title={uiOptions.title || title}
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
required={required}
|
||||
registry={registry}
|
||||
/>
|
||||
<ArrayFieldDescriptionTemplate
|
||||
idSchema={idSchema}
|
||||
description={uiOptions.description || schema.description}
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
registry={registry}
|
||||
/>
|
||||
<Grid container key={`array-item-list-${idSchema.$id}`}>
|
||||
{items &&
|
||||
items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => (
|
||||
<ArrayFieldItemTemplate key={key} {...itemProps} />
|
||||
))}
|
||||
{canAdd && (
|
||||
<Grid container justifyContent="flex-end">
|
||||
<Grid item>
|
||||
<Box mt={2}>
|
||||
<AddButton
|
||||
className="array-item-add"
|
||||
onClick={onAddClick}
|
||||
disabled={disabled || readonly}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Box>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default ArrayFieldTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './ArrayFieldTemplate';
|
||||
export * from './ArrayFieldTemplate';
|
|
@ -0,0 +1,82 @@
|
|||
import React from 'react';
|
||||
import TextField, { TextFieldProps } from '@mui/material/TextField';
|
||||
import { getInputProps, WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function BaseInputTemplate({
|
||||
id,
|
||||
placeholder,
|
||||
required,
|
||||
readonly,
|
||||
disabled,
|
||||
type,
|
||||
label,
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
autofocus,
|
||||
options,
|
||||
schema,
|
||||
uiSchema,
|
||||
rawErrors = [],
|
||||
formContext,
|
||||
registry,
|
||||
...textFieldProps
|
||||
}: WidgetProps) {
|
||||
const inputProps = getInputProps(schema, type, options);
|
||||
// Now we need to pull out the step, min, max into an inner `inputProps` for material-ui
|
||||
const { step, min, max, ...rest } = inputProps;
|
||||
const otherProps = {
|
||||
inputProps: {
|
||||
step,
|
||||
min,
|
||||
max,
|
||||
...(schema.examples ? { list: `examples_${id}` } : undefined),
|
||||
},
|
||||
...rest,
|
||||
};
|
||||
const _onChange = ({
|
||||
target: { value },
|
||||
}: React.ChangeEvent<HTMLInputElement>) =>
|
||||
onChange(value === '' ? options.emptyValue : value);
|
||||
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
|
||||
|
||||
const { schemaUtils } = registry;
|
||||
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
id={id}
|
||||
name={id}
|
||||
placeholder={placeholder}
|
||||
label={displayLabel ? label || schema.title : false}
|
||||
autoFocus={autofocus}
|
||||
required={required}
|
||||
disabled={disabled || readonly}
|
||||
{...otherProps}
|
||||
value={value || value === 0 ? value : ''}
|
||||
error={rawErrors.length > 0}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
{...(textFieldProps as TextFieldProps)}
|
||||
/>
|
||||
{schema.examples && (
|
||||
<datalist id={`examples_${id}`}>
|
||||
{(schema.examples as string[])
|
||||
.concat(schema.default ? ([schema.default] as string[]) : [])
|
||||
.map((example: any) => {
|
||||
return <option key={example} value={example} />;
|
||||
})}
|
||||
</datalist>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default BaseInputTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './BaseInputTemplate';
|
||||
export * from './BaseInputTemplate';
|
|
@ -0,0 +1,52 @@
|
|||
import React from 'react';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import { schemaRequiresTrueValue, WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function CheckboxWidget(props: WidgetProps) {
|
||||
const {
|
||||
schema,
|
||||
id,
|
||||
value,
|
||||
disabled,
|
||||
readonly,
|
||||
label,
|
||||
autofocus,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
} = props;
|
||||
// Because an unchecked checkbox will cause html5 validation to fail, only add
|
||||
// the "required" attribute if the field value must be "true", due to the
|
||||
// "const" or "enum" keywords
|
||||
const required = schemaRequiresTrueValue(schema);
|
||||
|
||||
const _onChange = (_: any, checked: boolean) => onChange(checked);
|
||||
const _onBlur = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLButtonElement>) => onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLButtonElement>) => onFocus(id, value);
|
||||
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
id={id}
|
||||
name={id}
|
||||
checked={typeof value === 'undefined' ? false : Boolean(value)}
|
||||
required={required}
|
||||
disabled={disabled || readonly}
|
||||
autoFocus={autofocus}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
/>
|
||||
}
|
||||
label={label || ''}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default CheckboxWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './CheckboxWidget';
|
||||
export * from './CheckboxWidget';
|
|
@ -0,0 +1,93 @@
|
|||
import React from 'react';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import FormGroup from '@mui/material/FormGroup';
|
||||
import FormLabel from '@mui/material/FormLabel';
|
||||
import { WidgetProps } from '@rjsf/utils';
|
||||
|
||||
const selectValue = (value: any, selected: any, all: any) => {
|
||||
const at = all.indexOf(value);
|
||||
const updated = selected.slice(0, at).concat(value, selected.slice(at));
|
||||
|
||||
// As inserting values at predefined index positions doesn't work with empty
|
||||
// arrays, we need to reorder the updated selection to match the initial order
|
||||
return updated.sort((a: any, b: any) => all.indexOf(a) > all.indexOf(b));
|
||||
};
|
||||
|
||||
const deselectValue = (value: any, selected: any) => {
|
||||
return selected.filter((v: any) => v !== value);
|
||||
};
|
||||
|
||||
function CheckboxesWidget({
|
||||
schema,
|
||||
label,
|
||||
id,
|
||||
disabled,
|
||||
options,
|
||||
value,
|
||||
autofocus,
|
||||
readonly,
|
||||
required,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
}: WidgetProps) {
|
||||
const { enumOptions, enumDisabled, inline } = options;
|
||||
|
||||
const _onChange =
|
||||
(option: any) =>
|
||||
({ target: { checked } }: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const all = (enumOptions as any).map(({ value }: any) => value);
|
||||
|
||||
if (checked) {
|
||||
onChange(selectValue(option.value, value, all));
|
||||
} else {
|
||||
onChange(deselectValue(option.value, value));
|
||||
}
|
||||
};
|
||||
|
||||
const _onBlur = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLButtonElement>) => onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLButtonElement>) => onFocus(id, value);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormLabel required={required} htmlFor={id}>
|
||||
{label || schema.title}
|
||||
</FormLabel>
|
||||
<FormGroup id={id} row={!!inline}>
|
||||
{Array.isArray(enumOptions) &&
|
||||
enumOptions.map((option, index: number) => {
|
||||
const checked = value.indexOf(option.value) !== -1;
|
||||
const itemDisabled =
|
||||
Array.isArray(enumDisabled) &&
|
||||
enumDisabled.indexOf(option.value) !== -1;
|
||||
const checkbox = (
|
||||
<Checkbox
|
||||
id={`${id}-${option.value}`}
|
||||
name={id}
|
||||
checked={checked}
|
||||
disabled={disabled || itemDisabled || readonly}
|
||||
autoFocus={autofocus && index === 0}
|
||||
onChange={_onChange(option)}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={checkbox}
|
||||
key={option.value}
|
||||
label={option.label}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CheckboxesWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './CheckboxesWidget';
|
||||
export * from './CheckboxesWidget';
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import { getTemplate, localToUTC, utcToLocal, WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function DateTimeWidget(props: WidgetProps) {
|
||||
const { options, registry } = props;
|
||||
const BaseInputTemplate = getTemplate<'BaseInputTemplate'>(
|
||||
'BaseInputTemplate',
|
||||
registry,
|
||||
options
|
||||
);
|
||||
const value = utcToLocal(props.value);
|
||||
const onChange = (value: any) => {
|
||||
props.onChange(localToUTC(value));
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseInputTemplate
|
||||
type="datetime-local"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
{...props}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default DateTimeWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './DateTimeWidget';
|
||||
export * from './DateTimeWidget';
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import { getTemplate, WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function DateWidget(props: WidgetProps) {
|
||||
const { options, registry } = props;
|
||||
const BaseInputTemplate = getTemplate<'BaseInputTemplate'>(
|
||||
'BaseInputTemplate',
|
||||
registry,
|
||||
options
|
||||
);
|
||||
return (
|
||||
<BaseInputTemplate
|
||||
type="date"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default DateWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './DateWidget';
|
||||
export * from './DateWidget';
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { DescriptionFieldProps } from '@rjsf/utils';
|
||||
|
||||
function DescriptionField({ description, id }: DescriptionFieldProps) {
|
||||
if (description) {
|
||||
return (
|
||||
<Typography id={id} variant="subtitle2" style={{ marginTop: '5px' }}>
|
||||
{description}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default DescriptionField;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './DescriptionField';
|
||||
export * from './DescriptionField';
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import ErrorIcon from '@mui/icons-material/Error';
|
||||
import Box from '@mui/material/Box';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { ErrorListProps } from '@rjsf/utils';
|
||||
|
||||
function ErrorList({ errors }: ErrorListProps) {
|
||||
return (
|
||||
<Paper elevation={2}>
|
||||
<Box mb={2} p={2}>
|
||||
<Typography variant="h6">Errors</Typography>
|
||||
<List dense>
|
||||
{errors.map((error, i: number) => {
|
||||
return (
|
||||
<ListItem key={i}>
|
||||
<ListItemIcon>
|
||||
<ErrorIcon color="error" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={error.stack} />
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Box>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default ErrorList;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './ErrorList';
|
||||
export * from './ErrorList';
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import { FieldErrorProps } from '@rjsf/utils';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import FormHelperText from '@mui/material/FormHelperText';
|
||||
import List from '@mui/material/List';
|
||||
|
||||
/** The `FieldErrorTemplate` component renders the errors local to the particular field
|
||||
*
|
||||
* @param props - The `FieldErrorProps` for the errors being rendered
|
||||
*/
|
||||
export default function FieldErrorTemplate(props: FieldErrorProps) {
|
||||
const { errors = [], idSchema } = props;
|
||||
if (errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const id = `${idSchema.$id}__error`;
|
||||
|
||||
return (
|
||||
<List dense disablePadding>
|
||||
{errors.map((error, i: number) => {
|
||||
return (
|
||||
<ListItem key={i} disableGutters>
|
||||
<FormHelperText id={id}>{error}</FormHelperText>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './FieldErrorTemplate';
|
||||
export * from './FieldErrorTemplate';
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
import { FieldHelpProps } from '@rjsf/utils';
|
||||
import FormHelperText from '@mui/material/FormHelperText';
|
||||
|
||||
/** The `FieldHelpTemplate` component renders any help desired for a field
|
||||
*
|
||||
* @param props - The `FieldHelpProps` to be rendered
|
||||
*/
|
||||
export default function FieldHelpTemplate(props: FieldHelpProps) {
|
||||
const { idSchema, help } = props;
|
||||
if (!help) {
|
||||
return null;
|
||||
}
|
||||
const id = `${idSchema.$id}__help`;
|
||||
return <FormHelperText id={id}>{help}</FormHelperText>;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './FieldHelpTemplate';
|
||||
export * from './FieldHelpTemplate';
|
|
@ -0,0 +1,64 @@
|
|||
import React from 'react';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { FieldTemplateProps, getTemplate, getUiOptions } from '@rjsf/utils';
|
||||
|
||||
function FieldTemplate({
|
||||
id,
|
||||
children,
|
||||
classNames,
|
||||
disabled,
|
||||
displayLabel,
|
||||
hidden,
|
||||
label,
|
||||
onDropPropertyClick,
|
||||
onKeyChange,
|
||||
readonly,
|
||||
required,
|
||||
rawErrors = [],
|
||||
errors,
|
||||
help,
|
||||
rawDescription,
|
||||
schema,
|
||||
uiSchema,
|
||||
registry,
|
||||
}: FieldTemplateProps) {
|
||||
const uiOptions = getUiOptions(uiSchema);
|
||||
const WrapIfAdditionalTemplate = getTemplate<'WrapIfAdditionalTemplate'>(
|
||||
'WrapIfAdditionalTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
|
||||
if (hidden) {
|
||||
return <div style={{ display: 'none' }}>{children}</div>;
|
||||
}
|
||||
return (
|
||||
<WrapIfAdditionalTemplate
|
||||
classNames={classNames}
|
||||
disabled={disabled}
|
||||
id={id}
|
||||
label={label}
|
||||
onDropPropertyClick={onDropPropertyClick}
|
||||
onKeyChange={onKeyChange}
|
||||
readonly={readonly}
|
||||
required={required}
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
registry={registry}
|
||||
>
|
||||
<FormControl fullWidth error={!!rawErrors.length} required={required}>
|
||||
{children}
|
||||
{displayLabel && rawDescription ? (
|
||||
<Typography variant="caption" color="textSecondary">
|
||||
{rawDescription}
|
||||
</Typography>
|
||||
) : null}
|
||||
{errors}
|
||||
{help}
|
||||
</FormControl>
|
||||
</WrapIfAdditionalTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
export default FieldTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './FieldTemplate';
|
||||
export * from './FieldTemplate';
|
|
@ -0,0 +1,55 @@
|
|||
import React from 'react';
|
||||
import IconButton, {
|
||||
IconButtonProps as MuiIconButtonProps,
|
||||
} from '@mui/material/IconButton';
|
||||
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
||||
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
||||
import RemoveIcon from '@mui/icons-material/Remove';
|
||||
import { IconButtonProps } from '@rjsf/utils';
|
||||
|
||||
export default function MuiIconButton(props: IconButtonProps) {
|
||||
const { icon, color, uiSchema, ...otherProps } = props;
|
||||
return (
|
||||
<IconButton
|
||||
{...otherProps}
|
||||
size="small"
|
||||
color={color as MuiIconButtonProps['color']}
|
||||
>
|
||||
{icon}
|
||||
</IconButton>
|
||||
);
|
||||
}
|
||||
|
||||
export function MoveDownButton(props: IconButtonProps) {
|
||||
return (
|
||||
<MuiIconButton
|
||||
title="Move down"
|
||||
{...props}
|
||||
icon={<ArrowDownwardIcon fontSize="small" />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function MoveUpButton(props: IconButtonProps) {
|
||||
return (
|
||||
<MuiIconButton
|
||||
title="Move up"
|
||||
{...props}
|
||||
icon={<ArrowUpwardIcon fontSize="small" />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function RemoveButton(props: IconButtonProps) {
|
||||
const { iconType, ...otherProps } = props;
|
||||
return (
|
||||
<MuiIconButton
|
||||
title="Remove"
|
||||
{...otherProps}
|
||||
color="error"
|
||||
icon={
|
||||
<RemoveIcon fontSize={iconType === 'default' ? undefined : 'small'} />
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './IconButton';
|
||||
export * from './IconButton';
|
|
@ -0,0 +1,8 @@
|
|||
import { ComponentType } from 'react';
|
||||
import { withTheme, FormProps } from '@rjsf/core';
|
||||
|
||||
import Theme from '../Theme';
|
||||
|
||||
const MuiForm: ComponentType<FormProps> = withTheme(Theme);
|
||||
|
||||
export default MuiForm;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './MuiForm';
|
||||
export * from './MuiForm';
|
|
@ -0,0 +1,89 @@
|
|||
import React from 'react';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import {
|
||||
ObjectFieldTemplateProps,
|
||||
canExpand,
|
||||
getTemplate,
|
||||
getUiOptions,
|
||||
} from '@rjsf/utils';
|
||||
|
||||
function ObjectFieldTemplate({
|
||||
description,
|
||||
title,
|
||||
properties,
|
||||
required,
|
||||
disabled,
|
||||
readonly,
|
||||
uiSchema,
|
||||
idSchema,
|
||||
schema,
|
||||
formData,
|
||||
onAddClick,
|
||||
registry,
|
||||
}: ObjectFieldTemplateProps) {
|
||||
const uiOptions = getUiOptions(uiSchema);
|
||||
const TitleFieldTemplate = getTemplate<'TitleFieldTemplate'>(
|
||||
'TitleFieldTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate'>(
|
||||
'DescriptionFieldTemplate',
|
||||
registry,
|
||||
uiOptions
|
||||
);
|
||||
// Button templates are not overridden in the uiSchema
|
||||
const {
|
||||
ButtonTemplates: { AddButton },
|
||||
} = registry.templates;
|
||||
return (
|
||||
<>
|
||||
{(uiOptions.title || title) && (
|
||||
<TitleFieldTemplate
|
||||
id={`${idSchema.$id}-title`}
|
||||
title={title}
|
||||
required={required}
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
registry={registry}
|
||||
/>
|
||||
)}
|
||||
{(uiOptions.description || description) && (
|
||||
<DescriptionFieldTemplate
|
||||
id={`${idSchema.$id}-description`}
|
||||
description={uiOptions.description || description!}
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
registry={registry}
|
||||
/>
|
||||
)}
|
||||
<Grid container spacing={2} style={{ marginTop: '10px' }}>
|
||||
{properties.map((element, index) =>
|
||||
// Remove the <Grid> if the inner element is hidden as the <Grid>
|
||||
// itself would otherwise still take up space.
|
||||
element.hidden ? (
|
||||
element.content
|
||||
) : (
|
||||
<Grid item xs={12} key={index} style={{ marginBottom: '10px' }}>
|
||||
{element.content}
|
||||
</Grid>
|
||||
)
|
||||
)}
|
||||
{canExpand(schema, uiSchema, formData) && (
|
||||
<Grid container justifyContent="flex-end">
|
||||
<Grid item>
|
||||
<AddButton
|
||||
className="object-property-expand"
|
||||
onClick={onAddClick(schema)}
|
||||
disabled={disabled || readonly}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ObjectFieldTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './ObjectFieldTemplate';
|
||||
export * from './ObjectFieldTemplate';
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import FormLabel from '@mui/material/FormLabel';
|
||||
import Radio from '@mui/material/Radio';
|
||||
import RadioGroup from '@mui/material/RadioGroup';
|
||||
import { WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function RadioWidget({
|
||||
id,
|
||||
schema,
|
||||
options,
|
||||
value,
|
||||
required,
|
||||
disabled,
|
||||
readonly,
|
||||
label,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
}: WidgetProps) {
|
||||
const { enumOptions, enumDisabled } = options;
|
||||
|
||||
const _onChange = (_: any, value: any) =>
|
||||
onChange(schema.type == 'boolean' ? value !== 'false' : value);
|
||||
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
|
||||
|
||||
const row = options ? options.inline : false;
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormLabel required={required} htmlFor={id}>
|
||||
{label || schema.title}
|
||||
</FormLabel>
|
||||
<RadioGroup
|
||||
id={id}
|
||||
name={id}
|
||||
value={`${value}`}
|
||||
row={row as boolean}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
>
|
||||
{Array.isArray(enumOptions) &&
|
||||
enumOptions.map((option) => {
|
||||
const itemDisabled =
|
||||
Array.isArray(enumDisabled) &&
|
||||
enumDisabled.indexOf(option.value) !== -1;
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Radio
|
||||
name={id}
|
||||
id={`${id}-${option.value}`}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label={`${option.label}`}
|
||||
value={`${option.value}`}
|
||||
key={option.value}
|
||||
disabled={disabled || itemDisabled || readonly}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</RadioGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RadioWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './RadioWidget';
|
||||
export * from './RadioWidget';
|
|
@ -0,0 +1,47 @@
|
|||
import React from 'react';
|
||||
import FormLabel from '@mui/material/FormLabel';
|
||||
import Slider from '@mui/material/Slider';
|
||||
import { WidgetProps, rangeSpec } from '@rjsf/utils';
|
||||
|
||||
function RangeWidget({
|
||||
value,
|
||||
readonly,
|
||||
disabled,
|
||||
onBlur,
|
||||
onFocus,
|
||||
options,
|
||||
schema,
|
||||
onChange,
|
||||
required,
|
||||
label,
|
||||
id,
|
||||
}: WidgetProps) {
|
||||
const sliderProps = { value, label, id, name: id, ...rangeSpec(schema) };
|
||||
|
||||
const _onChange = (_: any, value?: number | number[]) => {
|
||||
onChange(value ? options.emptyValue : value);
|
||||
};
|
||||
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormLabel required={required} id={id}>
|
||||
{label}
|
||||
</FormLabel>
|
||||
<Slider
|
||||
disabled={disabled || readonly}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
valueLabelDisplay="auto"
|
||||
{...sliderProps}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RangeWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './RangeWidget';
|
||||
export * from './RangeWidget';
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import { WidgetProps, processSelectValue } from '@rjsf/utils';
|
||||
|
||||
function SelectWidget({
|
||||
schema,
|
||||
id,
|
||||
options,
|
||||
label,
|
||||
required,
|
||||
disabled,
|
||||
readonly,
|
||||
value,
|
||||
multiple,
|
||||
autofocus,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
rawErrors = [],
|
||||
}: WidgetProps) {
|
||||
const { enumOptions, enumDisabled } = options;
|
||||
|
||||
const emptyValue = multiple ? [] : '';
|
||||
|
||||
const _onChange = ({
|
||||
target: { value },
|
||||
}: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(processSelectValue(schema, value, options));
|
||||
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onBlur(id, processSelectValue(schema, value, options));
|
||||
const _onFocus = ({
|
||||
target: { value },
|
||||
}: React.FocusEvent<HTMLInputElement>) =>
|
||||
onFocus(id, processSelectValue(schema, value, options));
|
||||
|
||||
return (
|
||||
<TextField
|
||||
id={id}
|
||||
name={id}
|
||||
label={label || schema.title}
|
||||
select
|
||||
value={typeof value === 'undefined' ? emptyValue : value}
|
||||
required={required}
|
||||
disabled={disabled || readonly}
|
||||
autoFocus={autofocus}
|
||||
error={rawErrors.length > 0}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
SelectProps={{
|
||||
multiple: typeof multiple === 'undefined' ? false : multiple,
|
||||
}}
|
||||
>
|
||||
{(enumOptions as any).map(({ value, label }: any, i: number) => {
|
||||
const disabled: any =
|
||||
enumDisabled && (enumDisabled as any).indexOf(value) != -1;
|
||||
return (
|
||||
<MenuItem key={i} value={value} disabled={disabled}>
|
||||
{label}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</TextField>
|
||||
);
|
||||
}
|
||||
|
||||
export default SelectWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './SelectWidget';
|
||||
export * from './SelectWidget';
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
import { SubmitButtonProps, getSubmitButtonOptions } from '@rjsf/utils';
|
||||
|
||||
const SubmitButton: React.ComponentType<SubmitButtonProps> = (props) => {
|
||||
const {
|
||||
submitText,
|
||||
norender,
|
||||
props: submitButtonProps,
|
||||
} = getSubmitButtonOptions(props.uiSchema);
|
||||
if (norender) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Box marginTop={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
{...submitButtonProps}
|
||||
>
|
||||
{submitText}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SubmitButton;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './SubmitButton';
|
||||
export * from './SubmitButton';
|
|
@ -0,0 +1,35 @@
|
|||
import AddButton from '../AddButton';
|
||||
import ArrayFieldItemTemplate from '../ArrayFieldItemTemplate';
|
||||
import ArrayFieldTemplate from '../ArrayFieldTemplate';
|
||||
import BaseInputTemplate from '../BaseInputTemplate';
|
||||
import DescriptionField from '../DescriptionField';
|
||||
import ErrorList from '../ErrorList';
|
||||
import { MoveDownButton, MoveUpButton, RemoveButton } from '../IconButton';
|
||||
import FieldErrorTemplate from '../FieldErrorTemplate';
|
||||
import FieldHelpTemplate from '../FieldHelpTemplate';
|
||||
import FieldTemplate from '../FieldTemplate';
|
||||
import ObjectFieldTemplate from '../ObjectFieldTemplate';
|
||||
import SubmitButton from '../SubmitButton';
|
||||
import TitleField from '../TitleField';
|
||||
import WrapIfAdditionalTemplate from '../WrapIfAdditionalTemplate';
|
||||
|
||||
export default {
|
||||
ArrayFieldItemTemplate,
|
||||
ArrayFieldTemplate,
|
||||
BaseInputTemplate,
|
||||
ButtonTemplates: {
|
||||
AddButton,
|
||||
MoveDownButton,
|
||||
MoveUpButton,
|
||||
RemoveButton,
|
||||
SubmitButton,
|
||||
},
|
||||
DescriptionFieldTemplate: DescriptionField,
|
||||
ErrorListTemplate: ErrorList,
|
||||
FieldErrorTemplate,
|
||||
FieldHelpTemplate,
|
||||
FieldTemplate,
|
||||
ObjectFieldTemplate,
|
||||
TitleFieldTemplate: TitleField,
|
||||
WrapIfAdditionalTemplate,
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './Templates';
|
||||
export * from './Templates';
|
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
import { getTemplate, WidgetProps } from '@rjsf/utils';
|
||||
|
||||
function TextareaWidget(props: WidgetProps) {
|
||||
const { options, registry } = props;
|
||||
const BaseInputTemplate = getTemplate<'BaseInputTemplate'>(
|
||||
'BaseInputTemplate',
|
||||
registry,
|
||||
options
|
||||
);
|
||||
|
||||
let rows: string | number = 5;
|
||||
if (typeof options.rows === 'string' || typeof options.rows === 'number') {
|
||||
rows = options.rows;
|
||||
}
|
||||
|
||||
return <BaseInputTemplate {...props} multiline rows={rows} />;
|
||||
}
|
||||
|
||||
export default TextareaWidget;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './TextareaWidget';
|
||||
export * from './TextareaWidget';
|
|
@ -0,0 +1,11 @@
|
|||
import { ThemeProps } from '@rjsf/core';
|
||||
|
||||
import Templates from '../Templates';
|
||||
import Widgets from '../Widgets';
|
||||
|
||||
const Theme: ThemeProps = {
|
||||
templates: Templates,
|
||||
widgets: Widgets,
|
||||
};
|
||||
|
||||
export default Theme;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './Theme';
|
||||
export * from './Theme';
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { TitleFieldProps } from '@rjsf/utils';
|
||||
|
||||
function TitleField({ id, title }: TitleFieldProps) {
|
||||
return (
|
||||
<Box id={id} mb={1} mt={1}>
|
||||
<Typography variant="h5">{title}</Typography>
|
||||
<Divider />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default TitleField;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './TitleField';
|
||||
export * from './TitleField';
|
|
@ -0,0 +1,19 @@
|
|||
import CheckboxWidget from '../CheckboxWidget/CheckboxWidget';
|
||||
import CheckboxesWidget from '../CheckboxesWidget/CheckboxesWidget';
|
||||
import DateWidget from '../DateWidget/DateWidget';
|
||||
import DateTimeWidget from '../DateTimeWidget/DateTimeWidget';
|
||||
import RadioWidget from '../RadioWidget/RadioWidget';
|
||||
import RangeWidget from '../RangeWidget/RangeWidget';
|
||||
import SelectWidget from '../SelectWidget/SelectWidget';
|
||||
import TextareaWidget from '../TextareaWidget/TextareaWidget';
|
||||
|
||||
export default {
|
||||
CheckboxWidget,
|
||||
CheckboxesWidget,
|
||||
DateWidget,
|
||||
DateTimeWidget,
|
||||
RadioWidget,
|
||||
RangeWidget,
|
||||
SelectWidget,
|
||||
TextareaWidget,
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './Widgets';
|
||||
export * from './Widgets';
|
|
@ -0,0 +1,80 @@
|
|||
import React, { CSSProperties } from 'react';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import Input from '@mui/material/OutlinedInput';
|
||||
import {
|
||||
ADDITIONAL_PROPERTY_FLAG,
|
||||
WrapIfAdditionalTemplateProps,
|
||||
} from '@rjsf/utils';
|
||||
|
||||
function WrapIfAdditionalTemplate({
|
||||
children,
|
||||
classNames,
|
||||
disabled,
|
||||
id,
|
||||
label,
|
||||
onDropPropertyClick,
|
||||
onKeyChange,
|
||||
readonly,
|
||||
required,
|
||||
schema,
|
||||
uiSchema,
|
||||
registry,
|
||||
}: WrapIfAdditionalTemplateProps) {
|
||||
// Button templates are not overridden in the uiSchema
|
||||
const { RemoveButton } = registry.templates.ButtonTemplates;
|
||||
const keyLabel = `${label} Key`; // i18n ?
|
||||
const additional = ADDITIONAL_PROPERTY_FLAG in schema;
|
||||
const btnStyle: CSSProperties = {
|
||||
flex: 1,
|
||||
paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
|
||||
if (!additional) {
|
||||
return <div className={classNames}>{children}</div>;
|
||||
}
|
||||
|
||||
const handleBlur = ({ target }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onKeyChange(target.value);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
key={`${id}-key`}
|
||||
alignItems="center"
|
||||
spacing={2}
|
||||
className={classNames}
|
||||
>
|
||||
<Grid item xs>
|
||||
<FormControl fullWidth required={required}>
|
||||
<InputLabel>{keyLabel}</InputLabel>
|
||||
<Input
|
||||
defaultValue={label}
|
||||
disabled={disabled || readonly}
|
||||
id={`${id}-key`}
|
||||
name={`${id}-key`}
|
||||
onBlur={!readonly ? handleBlur : undefined}
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
{children}
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RemoveButton
|
||||
iconType="default"
|
||||
style={btnStyle}
|
||||
disabled={disabled || readonly}
|
||||
onClick={onDropPropertyClick(label)}
|
||||
uiSchema={uiSchema}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
export default WrapIfAdditionalTemplate;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from './WrapIfAdditionalTemplate';
|
||||
export * from './WrapIfAdditionalTemplate';
|
|
@ -0,0 +1,8 @@
|
|||
import MuiForm from './MuiForm/MuiForm';
|
||||
|
||||
export { default as Form } from './MuiForm';
|
||||
export { default as Templates } from './Templates';
|
||||
export { default as Theme } from './Theme';
|
||||
export { default as Widgets } from './Widgets';
|
||||
|
||||
export default MuiForm;
|
Loading…
Reference in New Issue