Commit 60d72da80be1f0080b1bef7a262ddd401b2e5e07
1 parent
dc8ee0ff
feat(web): @rjsf deps + metadata API client + types + i18n + routes
Showing
7 changed files
with
445 additions
and
2 deletions
web/package-lock.json
| ... | ... | @@ -8,6 +8,9 @@ |
| 8 | 8 | "name": "vibe-erp-web", |
| 9 | 9 | "version": "0.0.0", |
| 10 | 10 | "dependencies": { |
| 11 | + "@rjsf/core": "^5.24.13", | |
| 12 | + "@rjsf/utils": "^5.24.13", | |
| 13 | + "@rjsf/validator-ajv8": "^5.24.13", | |
| 11 | 14 | "react": "^18.3.1", |
| 12 | 15 | "react-dom": "^18.3.1", |
| 13 | 16 | "react-router-dom": "^6.28.0" |
| ... | ... | @@ -807,6 +810,62 @@ |
| 807 | 810 | "node": ">=14.0.0" |
| 808 | 811 | } |
| 809 | 812 | }, |
| 813 | + "node_modules/@rjsf/core": { | |
| 814 | + "version": "5.24.13", | |
| 815 | + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.24.13.tgz", | |
| 816 | + "integrity": "sha512-ONTr14s7LFIjx2VRFLuOpagL76sM/HPy6/OhdBfq6UukINmTIs6+aFN0GgcR0aXQHFDXQ7f/fel0o/SO05Htdg==", | |
| 817 | + "license": "Apache-2.0", | |
| 818 | + "dependencies": { | |
| 819 | + "lodash": "^4.17.21", | |
| 820 | + "lodash-es": "^4.17.21", | |
| 821 | + "markdown-to-jsx": "^7.4.1", | |
| 822 | + "prop-types": "^15.8.1" | |
| 823 | + }, | |
| 824 | + "engines": { | |
| 825 | + "node": ">=14" | |
| 826 | + }, | |
| 827 | + "peerDependencies": { | |
| 828 | + "@rjsf/utils": "^5.24.x", | |
| 829 | + "react": "^16.14.0 || >=17" | |
| 830 | + } | |
| 831 | + }, | |
| 832 | + "node_modules/@rjsf/utils": { | |
| 833 | + "version": "5.24.13", | |
| 834 | + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.24.13.tgz", | |
| 835 | + "integrity": "sha512-rNF8tDxIwTtXzz5O/U23QU73nlhgQNYJ+Sv5BAwQOIyhIE2Z3S5tUiSVMwZHt0julkv/Ryfwi+qsD4FiE5rOuw==", | |
| 836 | + "license": "Apache-2.0", | |
| 837 | + "dependencies": { | |
| 838 | + "json-schema-merge-allof": "^0.8.1", | |
| 839 | + "jsonpointer": "^5.0.1", | |
| 840 | + "lodash": "^4.17.21", | |
| 841 | + "lodash-es": "^4.17.21", | |
| 842 | + "react-is": "^18.2.0" | |
| 843 | + }, | |
| 844 | + "engines": { | |
| 845 | + "node": ">=14" | |
| 846 | + }, | |
| 847 | + "peerDependencies": { | |
| 848 | + "react": "^16.14.0 || >=17" | |
| 849 | + } | |
| 850 | + }, | |
| 851 | + "node_modules/@rjsf/validator-ajv8": { | |
| 852 | + "version": "5.24.13", | |
| 853 | + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.24.13.tgz", | |
| 854 | + "integrity": "sha512-oWHP7YK581M8I5cF1t+UXFavnv+bhcqjtL1a7MG/Kaffi0EwhgcYjODrD8SsnrhncsEYMqSECr4ZOEoirnEUWw==", | |
| 855 | + "license": "Apache-2.0", | |
| 856 | + "dependencies": { | |
| 857 | + "ajv": "^8.12.0", | |
| 858 | + "ajv-formats": "^2.1.1", | |
| 859 | + "lodash": "^4.17.21", | |
| 860 | + "lodash-es": "^4.17.21" | |
| 861 | + }, | |
| 862 | + "engines": { | |
| 863 | + "node": ">=14" | |
| 864 | + }, | |
| 865 | + "peerDependencies": { | |
| 866 | + "@rjsf/utils": "^5.24.x" | |
| 867 | + } | |
| 868 | + }, | |
| 810 | 869 | "node_modules/@rolldown/pluginutils": { |
| 811 | 870 | "version": "1.0.0-beta.27", |
| 812 | 871 | "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", |
| ... | ... | @@ -1314,6 +1373,39 @@ |
| 1314 | 1373 | "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" |
| 1315 | 1374 | } |
| 1316 | 1375 | }, |
| 1376 | + "node_modules/ajv": { | |
| 1377 | + "version": "8.18.0", | |
| 1378 | + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", | |
| 1379 | + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", | |
| 1380 | + "license": "MIT", | |
| 1381 | + "dependencies": { | |
| 1382 | + "fast-deep-equal": "^3.1.3", | |
| 1383 | + "fast-uri": "^3.0.1", | |
| 1384 | + "json-schema-traverse": "^1.0.0", | |
| 1385 | + "require-from-string": "^2.0.2" | |
| 1386 | + }, | |
| 1387 | + "funding": { | |
| 1388 | + "type": "github", | |
| 1389 | + "url": "https://github.com/sponsors/epoberezkin" | |
| 1390 | + } | |
| 1391 | + }, | |
| 1392 | + "node_modules/ajv-formats": { | |
| 1393 | + "version": "2.1.1", | |
| 1394 | + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", | |
| 1395 | + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", | |
| 1396 | + "license": "MIT", | |
| 1397 | + "dependencies": { | |
| 1398 | + "ajv": "^8.0.0" | |
| 1399 | + }, | |
| 1400 | + "peerDependencies": { | |
| 1401 | + "ajv": "^8.0.0" | |
| 1402 | + }, | |
| 1403 | + "peerDependenciesMeta": { | |
| 1404 | + "ajv": { | |
| 1405 | + "optional": true | |
| 1406 | + } | |
| 1407 | + } | |
| 1408 | + }, | |
| 1317 | 1409 | "node_modules/any-promise": { |
| 1318 | 1410 | "version": "1.3.0", |
| 1319 | 1411 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", |
| ... | ... | @@ -1531,6 +1623,27 @@ |
| 1531 | 1623 | "node": ">= 6" |
| 1532 | 1624 | } |
| 1533 | 1625 | }, |
| 1626 | + "node_modules/compute-gcd": { | |
| 1627 | + "version": "1.2.1", | |
| 1628 | + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", | |
| 1629 | + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", | |
| 1630 | + "dependencies": { | |
| 1631 | + "validate.io-array": "^1.0.3", | |
| 1632 | + "validate.io-function": "^1.0.2", | |
| 1633 | + "validate.io-integer-array": "^1.0.0" | |
| 1634 | + } | |
| 1635 | + }, | |
| 1636 | + "node_modules/compute-lcm": { | |
| 1637 | + "version": "1.1.2", | |
| 1638 | + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", | |
| 1639 | + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", | |
| 1640 | + "dependencies": { | |
| 1641 | + "compute-gcd": "^1.2.1", | |
| 1642 | + "validate.io-array": "^1.0.3", | |
| 1643 | + "validate.io-function": "^1.0.2", | |
| 1644 | + "validate.io-integer-array": "^1.0.0" | |
| 1645 | + } | |
| 1646 | + }, | |
| 1534 | 1647 | "node_modules/convert-source-map": { |
| 1535 | 1648 | "version": "2.0.0", |
| 1536 | 1649 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", |
| ... | ... | @@ -1646,6 +1759,12 @@ |
| 1646 | 1759 | "node": ">=6" |
| 1647 | 1760 | } |
| 1648 | 1761 | }, |
| 1762 | + "node_modules/fast-deep-equal": { | |
| 1763 | + "version": "3.1.3", | |
| 1764 | + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", | |
| 1765 | + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", | |
| 1766 | + "license": "MIT" | |
| 1767 | + }, | |
| 1649 | 1768 | "node_modules/fast-glob": { |
| 1650 | 1769 | "version": "3.3.3", |
| 1651 | 1770 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", |
| ... | ... | @@ -1676,6 +1795,22 @@ |
| 1676 | 1795 | "node": ">= 6" |
| 1677 | 1796 | } |
| 1678 | 1797 | }, |
| 1798 | + "node_modules/fast-uri": { | |
| 1799 | + "version": "3.1.0", | |
| 1800 | + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", | |
| 1801 | + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", | |
| 1802 | + "funding": [ | |
| 1803 | + { | |
| 1804 | + "type": "github", | |
| 1805 | + "url": "https://github.com/sponsors/fastify" | |
| 1806 | + }, | |
| 1807 | + { | |
| 1808 | + "type": "opencollective", | |
| 1809 | + "url": "https://opencollective.com/fastify" | |
| 1810 | + } | |
| 1811 | + ], | |
| 1812 | + "license": "BSD-3-Clause" | |
| 1813 | + }, | |
| 1679 | 1814 | "node_modules/fastq": { |
| 1680 | 1815 | "version": "1.20.1", |
| 1681 | 1816 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", |
| ... | ... | @@ -1865,6 +2000,35 @@ |
| 1865 | 2000 | "node": ">=6" |
| 1866 | 2001 | } |
| 1867 | 2002 | }, |
| 2003 | + "node_modules/json-schema-compare": { | |
| 2004 | + "version": "0.2.2", | |
| 2005 | + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", | |
| 2006 | + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", | |
| 2007 | + "license": "MIT", | |
| 2008 | + "dependencies": { | |
| 2009 | + "lodash": "^4.17.4" | |
| 2010 | + } | |
| 2011 | + }, | |
| 2012 | + "node_modules/json-schema-merge-allof": { | |
| 2013 | + "version": "0.8.1", | |
| 2014 | + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", | |
| 2015 | + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", | |
| 2016 | + "license": "MIT", | |
| 2017 | + "dependencies": { | |
| 2018 | + "compute-lcm": "^1.1.2", | |
| 2019 | + "json-schema-compare": "^0.2.2", | |
| 2020 | + "lodash": "^4.17.20" | |
| 2021 | + }, | |
| 2022 | + "engines": { | |
| 2023 | + "node": ">=12.0.0" | |
| 2024 | + } | |
| 2025 | + }, | |
| 2026 | + "node_modules/json-schema-traverse": { | |
| 2027 | + "version": "1.0.0", | |
| 2028 | + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", | |
| 2029 | + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", | |
| 2030 | + "license": "MIT" | |
| 2031 | + }, | |
| 1868 | 2032 | "node_modules/json5": { |
| 1869 | 2033 | "version": "2.2.3", |
| 1870 | 2034 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", |
| ... | ... | @@ -1878,6 +2042,15 @@ |
| 1878 | 2042 | "node": ">=6" |
| 1879 | 2043 | } |
| 1880 | 2044 | }, |
| 2045 | + "node_modules/jsonpointer": { | |
| 2046 | + "version": "5.0.1", | |
| 2047 | + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", | |
| 2048 | + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", | |
| 2049 | + "license": "MIT", | |
| 2050 | + "engines": { | |
| 2051 | + "node": ">=0.10.0" | |
| 2052 | + } | |
| 2053 | + }, | |
| 1881 | 2054 | "node_modules/lilconfig": { |
| 1882 | 2055 | "version": "3.1.3", |
| 1883 | 2056 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", |
| ... | ... | @@ -1898,6 +2071,18 @@ |
| 1898 | 2071 | "dev": true, |
| 1899 | 2072 | "license": "MIT" |
| 1900 | 2073 | }, |
| 2074 | + "node_modules/lodash": { | |
| 2075 | + "version": "4.18.1", | |
| 2076 | + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", | |
| 2077 | + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", | |
| 2078 | + "license": "MIT" | |
| 2079 | + }, | |
| 2080 | + "node_modules/lodash-es": { | |
| 2081 | + "version": "4.18.1", | |
| 2082 | + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", | |
| 2083 | + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", | |
| 2084 | + "license": "MIT" | |
| 2085 | + }, | |
| 1901 | 2086 | "node_modules/loose-envify": { |
| 1902 | 2087 | "version": "1.4.0", |
| 1903 | 2088 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", |
| ... | ... | @@ -1920,6 +2105,23 @@ |
| 1920 | 2105 | "yallist": "^3.0.2" |
| 1921 | 2106 | } |
| 1922 | 2107 | }, |
| 2108 | + "node_modules/markdown-to-jsx": { | |
| 2109 | + "version": "7.7.17", | |
| 2110 | + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.7.17.tgz", | |
| 2111 | + "integrity": "sha512-7mG/1feQ0TX5I7YyMZVDgCC/y2I3CiEhIRQIhyov9nGBP5eoVrOXXHuL5ZP8GRfxVZKRiXWJgwXkb9It+nQZfQ==", | |
| 2112 | + "license": "MIT", | |
| 2113 | + "engines": { | |
| 2114 | + "node": ">= 10" | |
| 2115 | + }, | |
| 2116 | + "peerDependencies": { | |
| 2117 | + "react": ">= 0.14.0" | |
| 2118 | + }, | |
| 2119 | + "peerDependenciesMeta": { | |
| 2120 | + "react": { | |
| 2121 | + "optional": true | |
| 2122 | + } | |
| 2123 | + } | |
| 2124 | + }, | |
| 1923 | 2125 | "node_modules/merge2": { |
| 1924 | 2126 | "version": "1.4.1", |
| 1925 | 2127 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", |
| ... | ... | @@ -2003,7 +2205,6 @@ |
| 2003 | 2205 | "version": "4.1.1", |
| 2004 | 2206 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", |
| 2005 | 2207 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", |
| 2006 | - "dev": true, | |
| 2007 | 2208 | "license": "MIT", |
| 2008 | 2209 | "engines": { |
| 2009 | 2210 | "node": ">=0.10.0" |
| ... | ... | @@ -2229,6 +2430,23 @@ |
| 2229 | 2430 | "dev": true, |
| 2230 | 2431 | "license": "MIT" |
| 2231 | 2432 | }, |
| 2433 | + "node_modules/prop-types": { | |
| 2434 | + "version": "15.8.1", | |
| 2435 | + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", | |
| 2436 | + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", | |
| 2437 | + "license": "MIT", | |
| 2438 | + "dependencies": { | |
| 2439 | + "loose-envify": "^1.4.0", | |
| 2440 | + "object-assign": "^4.1.1", | |
| 2441 | + "react-is": "^16.13.1" | |
| 2442 | + } | |
| 2443 | + }, | |
| 2444 | + "node_modules/prop-types/node_modules/react-is": { | |
| 2445 | + "version": "16.13.1", | |
| 2446 | + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", | |
| 2447 | + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", | |
| 2448 | + "license": "MIT" | |
| 2449 | + }, | |
| 2232 | 2450 | "node_modules/queue-microtask": { |
| 2233 | 2451 | "version": "1.2.3", |
| 2234 | 2452 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", |
| ... | ... | @@ -2275,6 +2493,12 @@ |
| 2275 | 2493 | "react": "^18.3.1" |
| 2276 | 2494 | } |
| 2277 | 2495 | }, |
| 2496 | + "node_modules/react-is": { | |
| 2497 | + "version": "18.3.1", | |
| 2498 | + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", | |
| 2499 | + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", | |
| 2500 | + "license": "MIT" | |
| 2501 | + }, | |
| 2278 | 2502 | "node_modules/react-refresh": { |
| 2279 | 2503 | "version": "0.17.0", |
| 2280 | 2504 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", |
| ... | ... | @@ -2340,6 +2564,15 @@ |
| 2340 | 2564 | "node": ">=8.10.0" |
| 2341 | 2565 | } |
| 2342 | 2566 | }, |
| 2567 | + "node_modules/require-from-string": { | |
| 2568 | + "version": "2.0.2", | |
| 2569 | + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", | |
| 2570 | + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", | |
| 2571 | + "license": "MIT", | |
| 2572 | + "engines": { | |
| 2573 | + "node": ">=0.10.0" | |
| 2574 | + } | |
| 2575 | + }, | |
| 2343 | 2576 | "node_modules/resolve": { |
| 2344 | 2577 | "version": "1.22.11", |
| 2345 | 2578 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", |
| ... | ... | @@ -2694,6 +2927,39 @@ |
| 2694 | 2927 | "dev": true, |
| 2695 | 2928 | "license": "MIT" |
| 2696 | 2929 | }, |
| 2930 | + "node_modules/validate.io-array": { | |
| 2931 | + "version": "1.0.6", | |
| 2932 | + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", | |
| 2933 | + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==", | |
| 2934 | + "license": "MIT" | |
| 2935 | + }, | |
| 2936 | + "node_modules/validate.io-function": { | |
| 2937 | + "version": "1.0.2", | |
| 2938 | + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", | |
| 2939 | + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" | |
| 2940 | + }, | |
| 2941 | + "node_modules/validate.io-integer": { | |
| 2942 | + "version": "1.0.5", | |
| 2943 | + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", | |
| 2944 | + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", | |
| 2945 | + "dependencies": { | |
| 2946 | + "validate.io-number": "^1.0.3" | |
| 2947 | + } | |
| 2948 | + }, | |
| 2949 | + "node_modules/validate.io-integer-array": { | |
| 2950 | + "version": "1.0.0", | |
| 2951 | + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", | |
| 2952 | + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", | |
| 2953 | + "dependencies": { | |
| 2954 | + "validate.io-array": "^1.0.3", | |
| 2955 | + "validate.io-integer": "^1.0.4" | |
| 2956 | + } | |
| 2957 | + }, | |
| 2958 | + "node_modules/validate.io-number": { | |
| 2959 | + "version": "1.0.3", | |
| 2960 | + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", | |
| 2961 | + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" | |
| 2962 | + }, | |
| 2697 | 2963 | "node_modules/vite": { |
| 2698 | 2964 | "version": "5.4.21", |
| 2699 | 2965 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", | ... | ... |
web/package.json
web/src/App.tsx
| ... | ... | @@ -42,6 +42,11 @@ import { ShopFloorPage } from '@/pages/ShopFloorPage' |
| 42 | 42 | import { AccountsPage } from '@/pages/AccountsPage' |
| 43 | 43 | import { JournalEntriesPage } from '@/pages/JournalEntriesPage' |
| 44 | 44 | |
| 45 | +// Stub pages (will be replaced in later tasks) | |
| 46 | +function MetadataAdminPage() { return <div>Metadata Admin - coming soon</div> } | |
| 47 | +function FormDesignerPage() { return <div>Form Designer - coming soon</div> } | |
| 48 | +function ListViewDesignerPage() { return <div>List View Designer - coming soon</div> } | |
| 49 | + | |
| 45 | 50 | export default function App() { |
| 46 | 51 | return ( |
| 47 | 52 | <Routes> |
| ... | ... | @@ -83,6 +88,11 @@ export default function App() { |
| 83 | 88 | <Route path="shop-floor" element={<ShopFloorPage />} /> |
| 84 | 89 | <Route path="accounts" element={<AccountsPage />} /> |
| 85 | 90 | <Route path="journal-entries" element={<JournalEntriesPage />} /> |
| 91 | + <Route path="admin/metadata" element={<MetadataAdminPage />} /> | |
| 92 | + <Route path="admin/metadata/forms/new" element={<FormDesignerPage />} /> | |
| 93 | + <Route path="admin/metadata/forms/:slug/edit" element={<FormDesignerPage />} /> | |
| 94 | + <Route path="admin/metadata/list-views/new" element={<ListViewDesignerPage />} /> | |
| 95 | + <Route path="admin/metadata/list-views/:slug/edit" element={<ListViewDesignerPage />} /> | |
| 86 | 96 | </Route> |
| 87 | 97 | <Route path="*" element={<Navigate to="/" replace />} /> |
| 88 | 98 | </Routes> | ... | ... |
web/src/api/client.ts
| ... | ... | @@ -26,9 +26,14 @@ |
| 26 | 26 | |
| 27 | 27 | import type { |
| 28 | 28 | Account, |
| 29 | + CustomFieldDef, | |
| 30 | + FormDefinition, | |
| 29 | 31 | Item, |
| 30 | 32 | JournalEntry, |
| 33 | + ListViewDefinition, | |
| 31 | 34 | Location, |
| 35 | + MetadataEntity, | |
| 36 | + MetadataPermission, | |
| 32 | 37 | MetaInfo, |
| 33 | 38 | Partner, |
| 34 | 39 | PurchaseOrder, |
| ... | ... | @@ -75,7 +80,7 @@ export function registerUnauthorizedHandler(handler: () => void) { |
| 75 | 80 | onUnauthorized = handler |
| 76 | 81 | } |
| 77 | 82 | |
| 78 | -async function apiFetch<T>( | |
| 83 | +export async function apiFetch<T>( | |
| 79 | 84 | path: string, |
| 80 | 85 | init: RequestInit = {}, |
| 81 | 86 | expectJson = true, |
| ... | ... | @@ -283,6 +288,36 @@ export const production = { |
| 283 | 288 | |
| 284 | 289 | // ─── Finance ───────────────────────────────────────────────────────── |
| 285 | 290 | |
| 291 | +// ─── Metadata admin ───────────────────────────────────────────────── | |
| 292 | + | |
| 293 | +export const metadata = { | |
| 294 | + entities: () => apiFetch<MetadataEntity[]>('/api/v1/_meta/metadata/entities'), | |
| 295 | + permissions: () => apiFetch<MetadataPermission[]>('/api/v1/_meta/metadata/permissions'), | |
| 296 | + menus: () => apiFetch<any[]>('/api/v1/_meta/metadata/menus'), | |
| 297 | + customFields: () => apiFetch<CustomFieldDef[]>('/api/v1/_meta/metadata/custom-fields'), | |
| 298 | + customFieldsFor: (entity: string) => apiFetch<CustomFieldDef[]>(`/api/v1/_meta/metadata/custom-fields/${entity}`), | |
| 299 | + listForms: () => apiFetch<FormDefinition[]>('/api/v1/_meta/metadata/forms'), | |
| 300 | + getForm: (slug: string) => apiFetch<FormDefinition>(`/api/v1/_meta/metadata/forms/${slug}`), | |
| 301 | + saveForm: (slug: string, body: Omit<FormDefinition, 'source'>) => | |
| 302 | + apiFetch<FormDefinition>(`/api/v1/_meta/metadata/forms/${slug}`, { method: 'PUT', body: JSON.stringify(body) }), | |
| 303 | + deleteForm: (slug: string) => | |
| 304 | + apiFetch<void>(`/api/v1/_meta/metadata/forms/${slug}`, { method: 'DELETE' }, false), | |
| 305 | + listListViews: () => apiFetch<ListViewDefinition[]>('/api/v1/_meta/metadata/list-views'), | |
| 306 | + getListView: (slug: string) => apiFetch<ListViewDefinition>(`/api/v1/_meta/metadata/list-views/${slug}`), | |
| 307 | + saveListView: (slug: string, body: Omit<ListViewDefinition, 'source'>) => | |
| 308 | + apiFetch<ListViewDefinition>(`/api/v1/_meta/metadata/list-views/${slug}`, { method: 'PUT', body: JSON.stringify(body) }), | |
| 309 | + deleteListView: (slug: string) => | |
| 310 | + apiFetch<void>(`/api/v1/_meta/metadata/list-views/${slug}`, { method: 'DELETE' }, false), | |
| 311 | + createCustomField: (body: Omit<CustomFieldDef, 'source'>) => | |
| 312 | + apiFetch<CustomFieldDef>('/api/v1/_meta/metadata/custom-fields', { method: 'POST', body: JSON.stringify(body) }), | |
| 313 | + updateCustomField: (key: string, body: Omit<CustomFieldDef, 'source'>) => | |
| 314 | + apiFetch<CustomFieldDef>(`/api/v1/_meta/metadata/custom-fields/${key}`, { method: 'PUT', body: JSON.stringify(body) }), | |
| 315 | + deleteCustomField: (key: string) => | |
| 316 | + apiFetch<void>(`/api/v1/_meta/metadata/custom-fields/${key}`, { method: 'DELETE' }, false), | |
| 317 | +} | |
| 318 | + | |
| 319 | +// ─── Finance ───────────────────────────────────────────────────────── | |
| 320 | + | |
| 286 | 321 | export const finance = { |
| 287 | 322 | listAccounts: () => apiFetch<Account[]>('/api/v1/finance/accounts'), |
| 288 | 323 | createAccount: (body: { | ... | ... |
web/src/i18n/messages.ts
| ... | ... | @@ -35,6 +35,7 @@ export const en = { |
| 35 | 35 | 'nav.system': 'System', |
| 36 | 36 | 'nav.users': 'Users', |
| 37 | 37 | 'nav.roles': 'Roles', |
| 38 | + 'nav.metadataAdmin': 'Metadata', | |
| 38 | 39 | |
| 39 | 40 | // ─── Actions ─────────────────────────────────────────────── |
| 40 | 41 | 'action.confirm': 'Confirm', |
| ... | ... | @@ -62,6 +63,11 @@ export const en = { |
| 62 | 63 | 'action.newRole': '+ New Role', |
| 63 | 64 | 'action.newAccount': '+ New Account', |
| 64 | 65 | 'action.adjustStock': 'Adjust Stock', |
| 66 | + 'action.addField': 'Add Field', | |
| 67 | + 'action.addSection': 'Add Section', | |
| 68 | + 'action.discard': 'Discard', | |
| 69 | + 'action.delete': 'Delete', | |
| 70 | + 'action.newCustomField': 'New Custom Field', | |
| 65 | 71 | |
| 66 | 72 | // ─── Status badges ──────────────────────────────────────── |
| 67 | 73 | 'status.DRAFT': 'Draft', |
| ... | ... | @@ -96,6 +102,30 @@ export const en = { |
| 96 | 102 | 'label.noRows': 'No rows.', |
| 97 | 103 | 'label.loading': 'Loading…', |
| 98 | 104 | 'label.error': 'Error', |
| 105 | + | |
| 106 | + // ─── Metadata admin ─────────────────────────────────────── | |
| 107 | + 'page.metadataAdmin.title': 'Metadata Admin', | |
| 108 | + 'tab.entities': 'Entities', | |
| 109 | + 'tab.customFields': 'Custom Fields', | |
| 110 | + 'tab.permissions': 'Permissions', | |
| 111 | + 'tab.menus': 'Menus', | |
| 112 | + 'tab.forms': 'Forms', | |
| 113 | + 'tab.listViews': 'List Views', | |
| 114 | + 'page.formDesigner.title': 'Form Designer', | |
| 115 | + 'page.listViewDesigner.title': 'List View Designer', | |
| 116 | + 'label.slug': 'Slug', | |
| 117 | + 'label.entity': 'Entity', | |
| 118 | + 'label.purpose': 'Purpose', | |
| 119 | + 'label.preview': 'Preview', | |
| 120 | + 'label.source': 'Source', | |
| 121 | + 'label.columns': 'Columns', | |
| 122 | + 'label.filters': 'Filters', | |
| 123 | + 'label.sorting': 'Sorting', | |
| 124 | + 'label.pageSize': 'Page Size', | |
| 125 | + 'label.fieldKey': 'Field Key', | |
| 126 | + 'label.targetEntity': 'Target Entity', | |
| 127 | + 'label.fieldType': 'Field Type', | |
| 128 | + 'confirm.delete': 'Are you sure?', | |
| 99 | 129 | } as const |
| 100 | 130 | |
| 101 | 131 | export const zhCN: Record<MessageKey, string> = { |
| ... | ... | @@ -122,6 +152,7 @@ export const zhCN: Record<MessageKey, string> = { |
| 122 | 152 | 'nav.system': '系统', |
| 123 | 153 | 'nav.users': '用户', |
| 124 | 154 | 'nav.roles': '角色', |
| 155 | + 'nav.metadataAdmin': '元数据', | |
| 125 | 156 | |
| 126 | 157 | // ─── 操作 ────────────────────────────────────────────────── |
| 127 | 158 | 'action.confirm': '确认', |
| ... | ... | @@ -149,6 +180,11 @@ export const zhCN: Record<MessageKey, string> = { |
| 149 | 180 | 'action.newRole': '+ 新角色', |
| 150 | 181 | 'action.newAccount': '+ 新科目', |
| 151 | 182 | 'action.adjustStock': '库存调整', |
| 183 | + 'action.addField': '添加字段', | |
| 184 | + 'action.addSection': '添加分区', | |
| 185 | + 'action.discard': '放弃', | |
| 186 | + 'action.delete': '删除', | |
| 187 | + 'action.newCustomField': '新建自定义字段', | |
| 152 | 188 | |
| 153 | 189 | // ─── 状态 ────────────────────────────────────────────────── |
| 154 | 190 | 'status.DRAFT': '草稿', |
| ... | ... | @@ -183,6 +219,30 @@ export const zhCN: Record<MessageKey, string> = { |
| 183 | 219 | 'label.noRows': '暂无数据', |
| 184 | 220 | 'label.loading': '加载中…', |
| 185 | 221 | 'label.error': '错误', |
| 222 | + | |
| 223 | + // ─── 元数据管理 ──────────────────────────────────────────── | |
| 224 | + 'page.metadataAdmin.title': '元数据管理', | |
| 225 | + 'tab.entities': '实体', | |
| 226 | + 'tab.customFields': '自定义字段', | |
| 227 | + 'tab.permissions': '权限', | |
| 228 | + 'tab.menus': '菜单', | |
| 229 | + 'tab.forms': '表单', | |
| 230 | + 'tab.listViews': '列表视图', | |
| 231 | + 'page.formDesigner.title': '表单设计器', | |
| 232 | + 'page.listViewDesigner.title': '列表视图设计器', | |
| 233 | + 'label.slug': '标识', | |
| 234 | + 'label.entity': '实体', | |
| 235 | + 'label.purpose': '用途', | |
| 236 | + 'label.preview': '预览', | |
| 237 | + 'label.source': '来源', | |
| 238 | + 'label.columns': '列', | |
| 239 | + 'label.filters': '筛选', | |
| 240 | + 'label.sorting': '排序', | |
| 241 | + 'label.pageSize': '每页行数', | |
| 242 | + 'label.fieldKey': '字段键', | |
| 243 | + 'label.targetEntity': '目标实体', | |
| 244 | + 'label.fieldType': '字段类型', | |
| 245 | + 'confirm.delete': '确定删除?', | |
| 186 | 246 | } |
| 187 | 247 | |
| 188 | 248 | export const locales = { | ... | ... |
web/src/layout/AppLayout.tsx
web/src/types/api.ts
| ... | ... | @@ -284,3 +284,71 @@ export interface JournalEntry { |
| 284 | 284 | postedAt: string |
| 285 | 285 | lines: JournalEntryLine[] |
| 286 | 286 | } |
| 287 | + | |
| 288 | +// ─── Metadata Definitions ─────────────────────────────────────────── | |
| 289 | + | |
| 290 | +export type FormPurpose = 'create' | 'edit' | 'user-task' | 'view' | |
| 291 | + | |
| 292 | +export interface FormDefinition { | |
| 293 | + entityName: string | |
| 294 | + slug: string | |
| 295 | + title: string | |
| 296 | + purpose: FormPurpose | |
| 297 | + jsonSchema: Record<string, unknown> | |
| 298 | + uiSchema: Record<string, unknown> | |
| 299 | + version: number | |
| 300 | + source?: string | |
| 301 | +} | |
| 302 | + | |
| 303 | +export interface ListViewColumnDef { | |
| 304 | + field: string | |
| 305 | + label: string | |
| 306 | + width?: string | |
| 307 | + sortable: boolean | |
| 308 | + format?: 'date' | 'money' | 'status-badge' | 'link' | |
| 309 | +} | |
| 310 | + | |
| 311 | +export interface ListViewDefinition { | |
| 312 | + entityName: string | |
| 313 | + slug: string | |
| 314 | + title: string | |
| 315 | + columns: ListViewColumnDef[] | |
| 316 | + defaultSort?: { field: string; direction: 'asc' | 'desc' } | |
| 317 | + filters?: { field: string; operator: string; label: string }[] | |
| 318 | + pageSize: number | |
| 319 | + version: number | |
| 320 | + source?: string | |
| 321 | +} | |
| 322 | + | |
| 323 | +export interface CustomFieldType { | |
| 324 | + kind: string | |
| 325 | + maxLength?: number | |
| 326 | + precision?: number | |
| 327 | + scale?: number | |
| 328 | + targetEntity?: string | |
| 329 | + allowedValues?: string[] | |
| 330 | +} | |
| 331 | + | |
| 332 | +export interface CustomFieldDef { | |
| 333 | + key: string | |
| 334 | + targetEntity: string | |
| 335 | + type: CustomFieldType | |
| 336 | + required: boolean | |
| 337 | + pii: boolean | |
| 338 | + labelTranslations: Record<string, string> | |
| 339 | + source?: string | |
| 340 | +} | |
| 341 | + | |
| 342 | +export interface MetadataEntity { | |
| 343 | + name: string | |
| 344 | + pbc: string | |
| 345 | + table: string | |
| 346 | + description?: string | |
| 347 | + source?: string | |
| 348 | +} | |
| 349 | + | |
| 350 | +export interface MetadataPermission { | |
| 351 | + key: string | |
| 352 | + description: string | |
| 353 | + source?: string | |
| 354 | +} | ... | ... |