完善页面
This commit is contained in:
parent
85a63d722b
commit
82acef1ffa
148
package-lock.json
generated
148
package-lock.json
generated
@ -8,19 +8,14 @@
|
||||
"name": "ai-copyright",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"antd": "^5.15.2",
|
||||
"axios": "^1.6.7",
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.4",
|
||||
"mockjs": "^1.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"sort-by": "^1.2.0",
|
||||
"stylus": "^0.63.0"
|
||||
"sort-by": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.56",
|
||||
@ -47,7 +42,10 @@
|
||||
"node_modules/@adobe/css-tools": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz",
|
||||
"integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ=="
|
||||
"integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
"version": "2.3.0",
|
||||
@ -962,64 +960,6 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
|
||||
"integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
|
||||
"integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/free-regular-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/free-solid-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
|
||||
"integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
|
||||
"react": ">=16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
@ -1917,7 +1857,8 @@
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
@ -2046,14 +1987,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz",
|
||||
"integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/compute-scroll-into-view": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
|
||||
@ -2062,7 +1995,8 @@
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
@ -2106,6 +2040,7 @@
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
@ -2650,7 +2585,8 @@
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
@ -2679,6 +2615,7 @@
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -2710,6 +2647,7 @@
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -2719,6 +2657,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@ -2813,6 +2752,7 @@
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@ -2821,7 +2761,8 @@
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
@ -3079,21 +3020,11 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/mockjs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz",
|
||||
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
|
||||
"dependencies": {
|
||||
"commander": "*"
|
||||
},
|
||||
"bin": {
|
||||
"random": "bin/random"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
@ -3125,14 +3056,6 @@
|
||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-path": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/object-path/-/object-path-0.6.0.tgz",
|
||||
@ -3145,6 +3068,7 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -3221,6 +3145,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -3298,21 +3223,6 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
@ -4101,7 +4011,10 @@
|
||||
"node_modules/sax": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
|
||||
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="
|
||||
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.0",
|
||||
@ -4194,6 +4107,9 @@
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@ -4245,6 +4161,9 @@
|
||||
"version": "0.63.0",
|
||||
"resolved": "https://registry.npmjs.org/stylus/-/stylus-0.63.0.tgz",
|
||||
"integrity": "sha512-OMlgrTCPzE/ibtRMoeLVhOY0RcNuNWh0rhAVqeKnk/QwcuUKQbnqhZ1kg2vzD8VU/6h3FoPTq4RJPHgLBvX6Bw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@adobe/css-tools": "~4.3.3",
|
||||
"debug": "^4.3.2",
|
||||
@ -4475,7 +4394,8 @@
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
|
@ -10,19 +10,14 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"antd": "^5.15.2",
|
||||
"axios": "^1.6.7",
|
||||
"localforage": "^1.10.0",
|
||||
"match-sorter": "^6.3.4",
|
||||
"mockjs": "^1.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"sort-by": "^1.2.0",
|
||||
"stylus": "^0.63.0"
|
||||
"sort-by": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.56",
|
||||
|
78
src/components/card/CardProj.tsx
Normal file
78
src/components/card/CardProj.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import './card-proj.css';
|
||||
import {DownOutlined, EditOutlined, SearchOutlined, EyeOutlined, FolderOutlined} from '@ant-design/icons';
|
||||
import {MenuProps} from 'antd';
|
||||
import {Dropdown, Space} from 'antd';
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.antgroup.com">
|
||||
1st menu item
|
||||
</a>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function CardProj() {
|
||||
return (
|
||||
<div className="card-proj">
|
||||
<div className="title">
|
||||
<div className="left">
|
||||
<a href="/#">项目名称</a>
|
||||
</div>
|
||||
<div className="right">
|
||||
<span className="context">上下文:SDFSDF</span>
|
||||
<span className="status">未生成</span>
|
||||
<span className="date">2024-03-02 11:15:35</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div className="body">
|
||||
<div className="line">
|
||||
<div className="left">
|
||||
<span>金额¥:500</span>
|
||||
</div>
|
||||
<div className="right">
|
||||
<span>
|
||||
<EditOutlined/>
|
||||
<a href="/#">编辑</a>
|
||||
</span>
|
||||
<span>
|
||||
<SearchOutlined/>
|
||||
<a href="/#">查看</a>
|
||||
</span>
|
||||
<span>
|
||||
<EyeOutlined/>
|
||||
<a href="/#">预览</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="line">
|
||||
<div className="left">
|
||||
<span>
|
||||
<Dropdown menu={{items}}>
|
||||
<a onClick={(e) => e.preventDefault()}>
|
||||
<Space> 功能管理 <DownOutlined/></Space>
|
||||
</a>
|
||||
</Dropdown>
|
||||
</span>
|
||||
<span>
|
||||
<Dropdown menu={{items}}>
|
||||
<a onClick={(e) => e.preventDefault()}>
|
||||
<Space> 资料下载 <DownOutlined/></Space>
|
||||
</a>
|
||||
</Dropdown>
|
||||
</span>
|
||||
</div>
|
||||
<div className="right">
|
||||
<span>
|
||||
<FolderOutlined />
|
||||
<a href="/#">目录</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
76
src/components/card/card-proj.css
Normal file
76
src/components/card/card-proj.css
Normal file
@ -0,0 +1,76 @@
|
||||
.card-proj {
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.card-proj .left {
|
||||
position: unset;
|
||||
}
|
||||
|
||||
.card-proj .right {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card-proj .title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-proj hr {
|
||||
border-color: var(--color-border);
|
||||
border-style: dashed;
|
||||
border-left: 0;
|
||||
border-bottom: 0;
|
||||
border-right: 0;
|
||||
margin-block-start: 10px;
|
||||
margin-block-end: 10px;
|
||||
}
|
||||
|
||||
.card-proj .title .left {
|
||||
padding: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-proj .title .right {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.card-proj .title .right span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.card-proj .title .right span:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.card-proj .body {
|
||||
width: unset;
|
||||
border: unset !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.card-proj .body .line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.card-proj .body .line .left {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card-proj .body .line .left span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.card-proj .body .line .right span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.card-proj .body .line .right span a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
39
src/components/list/ListProj.tsx
Normal file
39
src/components/list/ListProj.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import './list-proj.css'
|
||||
import CardProj from "../card/CardProj.tsx";
|
||||
import {useRef, MutableRefObject} from "react";
|
||||
import {Input, Pagination} from 'antd';
|
||||
import type {SearchProps} from 'antd/es/input/Search';
|
||||
|
||||
const {Search} = Input;
|
||||
|
||||
const onSearch: SearchProps['onSearch'] = (value, _e, info) => console.log(info?.source, value);
|
||||
|
||||
export default function ListProj() {
|
||||
|
||||
const listProjRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
const listRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
const domHeight = window.innerHeight - 301;
|
||||
console.log(domHeight)
|
||||
|
||||
return (
|
||||
<div className="list-proj" ref={listProjRef}>
|
||||
<div className="top">
|
||||
<Search placeholder="按项目名搜索" onSearch={onSearch} style={{width: 200}}/>
|
||||
</div>
|
||||
<div className="body">
|
||||
<div className="list" ref={listRef} style={{height: `${domHeight}px`}}>
|
||||
<CardProj/>
|
||||
<CardProj/>
|
||||
<CardProj/>
|
||||
<CardProj/>
|
||||
<CardProj/>
|
||||
<CardProj/>
|
||||
</div>
|
||||
<div className="page">
|
||||
<Pagination defaultCurrent={1} total={50}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
35
src/components/list/list-proj.css
Normal file
35
src/components/list/list-proj.css
Normal file
@ -0,0 +1,35 @@
|
||||
.list-proj {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.list-proj .top {
|
||||
padding: 0 15px 15px 15px;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.list-proj .body {
|
||||
width: unset;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.list-proj .list {
|
||||
padding: 15px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.list-proj .body .card-proj {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.list-proj .body .card-proj:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.list-proj .body .page {
|
||||
border-top: 1px solid var(--color-border);
|
||||
padding-top: 15px;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
import './menu-tree.css';
|
||||
import {useContext} from "react";
|
||||
import {Axios} from "../../context/Context.ts";
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
|
||||
import {faCheck, faCaretRight, faCaretDown, faEdit, faPlus, faRemove} from '@fortawesome/free-solid-svg-icons';
|
||||
import {
|
||||
CaretRightOutlined,
|
||||
CaretDownOutlined,
|
||||
PlusOutlined,
|
||||
CloseOutlined,
|
||||
EditOutlined,
|
||||
CheckOutlined
|
||||
} from '@ant-design/icons';
|
||||
import {IMenuTree, IMenuTreeItem} from "../../interfaces/menu/IMenuTree.ts";
|
||||
|
||||
export default function MenuTree(props: IMenuTree) {
|
||||
const axios = useContext(Axios);
|
||||
|
||||
const triggerChildren = (item: IMenuTreeItem) => {
|
||||
|
||||
@ -18,14 +21,14 @@ export default function MenuTree(props: IMenuTree) {
|
||||
trigger();
|
||||
}
|
||||
|
||||
const renderBtnGroup = (item: IMenuTreeItem) => {
|
||||
if(item.isEdit) {
|
||||
const renderBtnGroup = (item: IMenuTreeItem, index: number, parent?: IMenuTreeItem) => {
|
||||
if (item.isEdit) {
|
||||
return (
|
||||
<>
|
||||
<FontAwesomeIcon className="icon" icon={faCheck} onClick={() => {
|
||||
<CheckOutlined className="icon" onClick={() => {
|
||||
props.handleEditSaveClick(item);
|
||||
}}/>
|
||||
<FontAwesomeIcon className="icon" icon={faRemove} onClick={() => {
|
||||
<CloseOutlined className="icon" onClick={() => {
|
||||
props.handleEditCancelClick(item);
|
||||
}}/>
|
||||
</>
|
||||
@ -33,35 +36,44 @@ export default function MenuTree(props: IMenuTree) {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<FontAwesomeIcon className="icon" icon={faEdit} onClick={() => {
|
||||
<EditOutlined className="icon" onClick={() => {
|
||||
props.handleEditClick(item);
|
||||
}}/>
|
||||
<FontAwesomeIcon className="icon" icon={faPlus} onClick={() => {
|
||||
<PlusOutlined className="icon" onClick={() => {
|
||||
props.handleAddClick(item);
|
||||
}}/>
|
||||
<FontAwesomeIcon className="icon" icon={faRemove} onClick={() => {
|
||||
props.handleRemoveClick(item);
|
||||
<CloseOutlined className="icon" onClick={() => {
|
||||
props.handleRemoveClick(item, index, parent);
|
||||
}}/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const renderLabel = (item: IMenuTreeItem) => {
|
||||
if(item.isEdit) {
|
||||
return <input className="menu-name-input" value={item.name} onChange={(e) => {
|
||||
item.name = e.target.value;
|
||||
props.handleNameChange(item);
|
||||
}}/>
|
||||
if (item.isEdit) {
|
||||
const width = 180 - 30 - item.level * 10;
|
||||
return <input className="menu-name-input"
|
||||
value={item.name}
|
||||
style={{width: width}}
|
||||
onChange={(e) => {
|
||||
item.name = e.target.value;
|
||||
props.handleNameChange(item);
|
||||
}}/>
|
||||
}
|
||||
const icon = item.isOpen ? faCaretDown : faCaretRight;
|
||||
const icon = item.isOpen ? <CaretDownOutlined onClick={() => {
|
||||
triggerChildren(item)
|
||||
}}/> : <CaretRightOutlined onClick={() => {
|
||||
triggerChildren(item)
|
||||
}}/>;
|
||||
const width = 180 - 50 - (item.level * 10) - (5 + (item.isParent ? 8.75 : 0));
|
||||
return (
|
||||
<>
|
||||
{item.isParent ? <FontAwesomeIcon className="icon" icon={icon} onClick={() => {
|
||||
triggerChildren(item)
|
||||
}}/> : <></>}
|
||||
<span onDoubleClick={() => {
|
||||
triggerChildren(item)
|
||||
}}>{item.name}</span>
|
||||
{item.isParent ? icon : <></>}
|
||||
<span
|
||||
style={{width: width}}
|
||||
onDoubleClick={() => {
|
||||
triggerChildren(item)
|
||||
}}>{item.name}</span>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -76,7 +88,7 @@ export default function MenuTree(props: IMenuTree) {
|
||||
<li key={item.id}>
|
||||
<div className="menu-title">
|
||||
<div className="label">{renderLabel(item)}</div>
|
||||
<div className="icon-group">{renderBtnGroup(item)}</div>
|
||||
<div className="icon-group">{renderBtnGroup(item, index, parent)}</div>
|
||||
</div>
|
||||
{renderChildrenMenu}
|
||||
</li>
|
||||
|
111
src/components/menu/MenuTreeWithTopButton.tsx
Normal file
111
src/components/menu/MenuTreeWithTopButton.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import './menu-tree-with-top-button.css';
|
||||
import MenuTree from "./MenuTree.tsx";
|
||||
import {IMenuTreeItem} from "../../interfaces/menu/IMenuTree.ts";
|
||||
import {useState} from "react";
|
||||
|
||||
class MenuTreeItem implements IMenuTreeItem {
|
||||
children: Array<IMenuTreeItem> | null;
|
||||
id: string;
|
||||
isEdit: boolean;
|
||||
isOpen: boolean;
|
||||
isParent: boolean;
|
||||
level: number;
|
||||
name: string;
|
||||
oldName: string;
|
||||
|
||||
constructor(id: string, name: string, level: number) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.oldName = name;
|
||||
this.level = level;
|
||||
this.isEdit = false;
|
||||
this.isOpen = false;
|
||||
this.isParent = false;
|
||||
this.children = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default function MenuTreeWithTopButton() {
|
||||
|
||||
const menuTrees: Array<IMenuTreeItem> = [];
|
||||
const [menuTreeArray, setMenuTreeArray] = useState(menuTrees);
|
||||
|
||||
return (
|
||||
<div className="menu-tree-with-top-button">
|
||||
<button type="button" className="btn btn-blue" onClick={() => {
|
||||
const menuTreeItem = new MenuTreeItem(`${new Date().getTime()}`, '一级目录', 1);
|
||||
menuTreeItem.isParent = true;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray,
|
||||
menuTreeItem,
|
||||
]);
|
||||
}}>添加目录
|
||||
</button>
|
||||
<MenuTree
|
||||
menus={menuTreeArray}
|
||||
url={''}
|
||||
setMenuTreeArray={() => {
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleExpand={() => {
|
||||
}}
|
||||
handleAddClick={(item) => {
|
||||
item.isParent = true;
|
||||
item.isOpen = true;
|
||||
if (!item.children) {
|
||||
item.children = new Array<IMenuTreeItem>();
|
||||
}
|
||||
const menuTreeItem = new MenuTreeItem(`${new Date().getTime()}`, item.level + '级目录', item.level + 1);
|
||||
menuTreeItem.isOpen = true;
|
||||
item.children.push(menuTreeItem);
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}
|
||||
}
|
||||
handleEditClick={(item) => {
|
||||
item.isEdit = true;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleRemoveClick={(_item, index, parent) => {
|
||||
if (parent) {
|
||||
parent?.children?.splice(index, 1);
|
||||
} else {
|
||||
menuTreeArray.splice(index, 1);
|
||||
}
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleEditSaveClick={(item) => {
|
||||
// 这里发请求,成功之后修改,失败还原
|
||||
if (item.name === '') {
|
||||
return;
|
||||
}
|
||||
item.oldName = item.name;
|
||||
item.isEdit = false;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleEditCancelClick={(item) => {
|
||||
item.name = item.oldName;
|
||||
item.isEdit = false;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleNameChange={() => {
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
7
src/components/menu/menu-tree-with-top-button.css
Normal file
7
src/components/menu/menu-tree-with-top-button.css
Normal file
@ -0,0 +1,7 @@
|
||||
.menu-tree-with-top-button {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.menu-tree-with-top-button .btn {
|
||||
width: 100%;
|
||||
}
|
@ -1,24 +1,43 @@
|
||||
.menu-tree {
|
||||
padding: 0 15px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.menu-tree ul {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.menu-tree ul li {}
|
||||
.menu-tree ul li {
|
||||
|
||||
}
|
||||
.menu-tree ul li .menu-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.menu-tree ul li .menu-title .label {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.menu-tree ul li .menu-title .label span {
|
||||
margin-left: 5px;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.menu-tree ul li .menu-title .label span {
|
||||
|
||||
.menu-tree ul li .menu-title .label .menu-name-input {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-decoration: 1px solid underline;
|
||||
text-underline-offset: 2px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.menu-tree ul li .menu-title .icon-group {
|
||||
@ -29,5 +48,5 @@
|
||||
}
|
||||
.menu-tree ul li .menu-title .icon-group .icon {
|
||||
cursor: pointer;
|
||||
padding-left: 5px;
|
||||
padding-left: 2px;
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
|
||||
.menu-with-top-button ul {
|
||||
padding: 10px;
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
.menu-with-top-button ul li {
|
||||
|
@ -1,5 +1,5 @@
|
||||
:root {
|
||||
--color-border: #eeeeee;
|
||||
--color-border: #d9d9d9;
|
||||
--color-box-shadow: rgba(0, 0, 0, 0.3);
|
||||
--color-red: #ff5722;
|
||||
--color-orange: #ffb800;
|
||||
@ -19,6 +19,12 @@ html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-dark);
|
||||
text-decoration-line: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
@ -21,11 +21,11 @@ export interface IMenuTree {
|
||||
|
||||
handleAddClick(item: IMenuTreeItem): void;
|
||||
|
||||
handleRemoveClick(item: IMenuTreeItem): void;
|
||||
handleRemoveClick(item: IMenuTreeItem, index: number, parent?: IMenuTreeItem): void;
|
||||
|
||||
handleEditSaveClick(item: IMenuTreeItem): void;
|
||||
|
||||
handleEditCancelClick(item: IMenuTreeItem): void;
|
||||
handleEditCancelClick(tem: IMenuTreeItem): void;
|
||||
|
||||
handleNameChange(item: IMenuTreeItem): void;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
.body {
|
||||
margin: 0 auto 10px auto;
|
||||
background-color: red;
|
||||
width: var(--width-workspace);
|
||||
background-color: #FFFFFF;
|
||||
}
|
@ -12,7 +12,8 @@
|
||||
}
|
||||
|
||||
.index .right {
|
||||
margin-left: 235px;
|
||||
margin-left: 220px;
|
||||
border-left: 1px solid var(--color-border);
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
background-color: green;
|
||||
}
|
@ -1,33 +1,9 @@
|
||||
import './index.css';
|
||||
import {MouseEvent, useState} from "react";
|
||||
import {MouseEvent} from "react";
|
||||
import {IMenuListItem, IMenuWithTopButton} from "../../interfaces/menu/IMenuWithTopButton.ts";
|
||||
import MenuWithTopButton from "../../components/menu/MenuWithTopButton.tsx";
|
||||
import MenuTree from "../../components/menu/MenuTree.tsx";
|
||||
import {IMenuTree, IMenuTreeItem} from "../../interfaces/menu/IMenuTree.ts";
|
||||
import {name} from "axios";
|
||||
|
||||
class MenuTreeItem implements IMenuTreeItem {
|
||||
children: Array<IMenuTreeItem> | null;
|
||||
id: string;
|
||||
isEdit: boolean;
|
||||
isOpen: boolean;
|
||||
isParent: boolean;
|
||||
level: number;
|
||||
name: string;
|
||||
oldName: string;
|
||||
|
||||
constructor(id: string, name: string, level: number) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.oldName = name;
|
||||
this.level = level;
|
||||
this.isEdit = false;
|
||||
this.isOpen = false;
|
||||
this.isParent = false;
|
||||
this.children = null;
|
||||
}
|
||||
|
||||
}
|
||||
import MenuTreeWithTopButton from "../../components/menu/MenuTreeWithTopButton.tsx";
|
||||
import ListProj from "../../components/list/ListProj.tsx";
|
||||
|
||||
const projMenu: IMenuWithTopButton = {
|
||||
button: {
|
||||
@ -68,8 +44,6 @@ const agentMenu: IMenuWithTopButton = {
|
||||
}
|
||||
|
||||
export default function Index() {
|
||||
const menuTrees: Array<IMenuTreeItem> = [];
|
||||
const [menuTreeArray, setMenuTreeArray] = useState(menuTrees);
|
||||
return (
|
||||
<div className="index">
|
||||
<div className="left">
|
||||
@ -78,80 +52,16 @@ export default function Index() {
|
||||
list={projMenu.list}
|
||||
handleListItem={projMenu.handleListItem}
|
||||
/>
|
||||
<button type="button" onClick={() => {
|
||||
const menuTreeItem = new MenuTreeItem(`${new Date().getTime()}`, '一级目录', 1);
|
||||
menuTreeItem.isParent = true;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray,
|
||||
menuTreeItem,
|
||||
]);
|
||||
}}>添加目录
|
||||
</button>
|
||||
<MenuTree
|
||||
menus={menuTreeArray}
|
||||
url={''}
|
||||
setMenuTreeArray={(item) => {
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleExpand={(item) => {
|
||||
}}
|
||||
handleAddClick={(item) => {
|
||||
item.isParent = true;
|
||||
item.isOpen = true;
|
||||
if (!item.children) {
|
||||
item.children = new Array<IMenuTreeItem>();
|
||||
}
|
||||
const menuTreeItem = new MenuTreeItem(`${new Date().getTime()}`, item.level + '级目录', item.level + 1);
|
||||
menuTreeItem.isOpen = true;
|
||||
item.children.push(menuTreeItem);
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}
|
||||
}
|
||||
handleEditClick={(item) => {
|
||||
item.isEdit = true;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleRemoveClick={(item) => {
|
||||
|
||||
}}
|
||||
handleEditSaveClick={(item) => {
|
||||
console.log(item);
|
||||
// 这里发请求,成功之后修改,失败还原
|
||||
if(item.name === '') {
|
||||
return;
|
||||
}
|
||||
item.oldName = item.name;
|
||||
item.isEdit = false;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleEditCancelClick={(item) => {
|
||||
item.name = item.oldName;
|
||||
item.isEdit = false;
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
handleNameChange={(item) => {
|
||||
setMenuTreeArray([
|
||||
...menuTreeArray
|
||||
])
|
||||
}}
|
||||
/>
|
||||
<MenuTreeWithTopButton />
|
||||
<MenuWithTopButton
|
||||
button={agentMenu.button}
|
||||
list={agentMenu.list}
|
||||
handleListItem={agentMenu.handleListItem}
|
||||
/>
|
||||
</div>
|
||||
<div className="right"></div>
|
||||
<div className="right">
|
||||
<ListProj/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import {defineConfig} from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [react()],
|
||||
server: {
|
||||
host: '0.0.0.0'
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user