Compare commits
3 Commits
88ce1d498e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e34d290865 | |||
| b1060433d0 | |||
| cf039f4d08 |
@@ -30,6 +30,10 @@
|
||||
"resource": "9232d9e2-9807-4753-808f-07250e5474b0",
|
||||
"scope": "Reports.Read"
|
||||
},
|
||||
{
|
||||
"resource": "9232d9e2-9807-4753-808f-07250e5474b0",
|
||||
"scope": "Logs.Write"
|
||||
},
|
||||
{
|
||||
"resource": "Microsoft Flow Service",
|
||||
"scope": "Flows.Read.All"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/webpack-patch.schema.json",
|
||||
"patchFiles": ["./node_modules/@tnsu/monitoring-web/spfx/webpack-patch.cjs"]
|
||||
}
|
||||
Generated
+132
-24
@@ -17,6 +17,8 @@
|
||||
"@microsoft/sp-webpart-base": "1.22.1",
|
||||
"@pnp/sp": "^4.20.0",
|
||||
"@pnp/spfx-controls-react": "^3.25.0",
|
||||
"@pnp/telemetry-js": "2.0.0",
|
||||
"@tnsu/monitoring-web": "^0.3.4",
|
||||
"@tnsu/ui-kit": "^0.15.0",
|
||||
"jszip": "~3.8.0",
|
||||
"react": "17.0.1",
|
||||
@@ -341,7 +343,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
|
||||
"integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -351,7 +353,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
|
||||
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.29.7",
|
||||
@@ -382,7 +384,7 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -408,7 +410,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
|
||||
"integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.29.7",
|
||||
@@ -425,7 +427,7 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -457,7 +459,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
|
||||
"integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.29.7",
|
||||
@@ -503,7 +505,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
|
||||
"integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -513,7 +515,7 @@
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
|
||||
"integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.29.7",
|
||||
@@ -3979,7 +3981,7 @@
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
@@ -8726,6 +8728,28 @@
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rrweb/rrweb-plugin-console-record": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rrweb/rrweb-plugin-console-record/-/rrweb-plugin-console-record-2.2.0.tgz",
|
||||
"integrity": "sha512-2c6LEsoH3+1NFcHckcwuErg7bkpFadt9++uKJh2x9BtWUDxoVKzLp+qLCq6f90MLTjSIABDkAiCswVskENZT3g==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@rrweb/utils": "^2.1.1",
|
||||
"rrweb": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@rrweb/types": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rrweb/types/-/types-2.2.0.tgz",
|
||||
"integrity": "sha512-2gTA/pRpIbuET123oSdX5ZUDZfWCOIMYBvpSai3fr5pk9LcbccPqqaXflX+roP4oKenLjNtJPGpFK3BfYeBKnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rrweb/utils": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rrweb/utils/-/utils-2.2.0.tgz",
|
||||
"integrity": "sha512-e8FEp8wLswqgjDHpQNUUVfEXeDsrRMOVouvqIGKvnPxKYonjLlh0mU3O/17QNvCixFG5eUFR1B2jgTdiLlZxeQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rushstack/debug-certificate-manager": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/debug-certificate-manager/-/debug-certificate-manager-1.6.2.tgz",
|
||||
@@ -9885,6 +9909,28 @@
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/@tnsu/monitoring-web": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://git.tnsu.kz/api/packages/tansu/npm/%40tnsu%2Fmonitoring-web/-/0.3.4/monitoring-web-0.3.4.tgz",
|
||||
"integrity": "sha512-tQe0ZM1tBVO3XtbNFliRaaooqvCX3gb/Q/j2lV6+rYCXprodBZByQ6PLrCu/P0me/rW8KdQ02hu7avyLXXfkoQ==",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@rrweb/rrweb-plugin-console-record": "^2.2.0",
|
||||
"rrweb": "^2.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tnsu/ui-kit": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://git.tnsu.kz/api/packages/tansu/npm/%40tnsu%2Fui-kit/-/0.15.0/ui-kit-0.15.0.tgz",
|
||||
@@ -10022,6 +10068,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/css-font-loading-module": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz",
|
||||
"integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ejs": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz",
|
||||
@@ -10250,7 +10302,7 @@
|
||||
"version": "26.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz",
|
||||
"integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~8.3.0"
|
||||
@@ -10279,6 +10331,7 @@
|
||||
"version": "15.7.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
||||
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
@@ -10308,6 +10361,7 @@
|
||||
"version": "17.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz",
|
||||
"integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
@@ -10319,6 +10373,7 @@
|
||||
"version": "17.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz",
|
||||
"integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "^17"
|
||||
@@ -10341,6 +10396,7 @@
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.26.0.tgz",
|
||||
"integrity": "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
@@ -11627,6 +11683,12 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@xstate/fsm": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz",
|
||||
"integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
@@ -12513,6 +12575,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@@ -12537,7 +12608,7 @@
|
||||
"version": "2.11.7",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.7.tgz",
|
||||
"integrity": "sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"baseline-browser-mapping": "dist/cli.cjs"
|
||||
@@ -12711,7 +12782,7 @@
|
||||
"version": "4.28.7",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz",
|
||||
"integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -12920,7 +12991,7 @@
|
||||
"version": "1.0.30001806",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
|
||||
"integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -13345,7 +13416,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
@@ -14234,7 +14305,7 @@
|
||||
"version": "1.5.398",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.398.tgz",
|
||||
"integrity": "sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/embla-carousel": {
|
||||
@@ -14564,7 +14635,7 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -15984,7 +16055,7 @@
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -19133,7 +19204,7 @@
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
@@ -19813,6 +19884,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
@@ -19935,7 +20012,6 @@
|
||||
"version": "3.3.16",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
|
||||
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -20077,7 +20153,7 @@
|
||||
"version": "2.0.51",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
|
||||
"integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -20742,7 +20818,6 @@
|
||||
"version": "8.5.25",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz",
|
||||
"integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -22018,6 +22093,40 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rrdom": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/rrdom/-/rrdom-2.2.0.tgz",
|
||||
"integrity": "sha512-gxcBJWVtS/Xz+Ys8xcjPoWqr+C7wz/MS8NgmKw136I47Xygy17FYOGZqoGwEyvBn724jRDK1ljS+8w9FsZStOg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"rrweb-snapshot": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rrweb": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/rrweb/-/rrweb-2.2.0.tgz",
|
||||
"integrity": "sha512-ofVzPq11/yIQ7WhVb++rJGI2LoPPrxdqu0QAvRA4KGeXJ7LH52jQ0VlRH4+VXn5PA/7pz85/rRkQyBUqT1LraQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rrweb/types": "^2.2.0",
|
||||
"@rrweb/utils": "^2.2.0",
|
||||
"@types/css-font-loading-module": "0.0.7",
|
||||
"@xstate/fsm": "^1.4.0",
|
||||
"base64-arraybuffer": "^1.0.1",
|
||||
"mitt": "^3.0.0",
|
||||
"rrdom": "^2.2.0",
|
||||
"rrweb-snapshot": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rrweb-snapshot": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-2.2.0.tgz",
|
||||
"integrity": "sha512-Tg/PiCLy+zV9C0Jfb4IAGABtt5l/UOvwW5xjFk41ZQhBfUjeqPP1rZ9HMDrFPc7cawCUEenWw54+g/4vluO5lg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss": "^8.4.38"
|
||||
}
|
||||
},
|
||||
"node_modules/rtl-css-js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz",
|
||||
@@ -23127,7 +23236,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -24407,7 +24515,7 @@
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
|
||||
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unicorn-magic": {
|
||||
@@ -24461,7 +24569,7 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
||||
"integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
"@microsoft/sp-webpart-base": "1.22.1",
|
||||
"@pnp/sp": "^4.20.0",
|
||||
"@pnp/spfx-controls-react": "^3.25.0",
|
||||
"@pnp/telemetry-js": "2.0.0",
|
||||
"@tnsu/monitoring-web": "^0.3.4",
|
||||
"@tnsu/ui-kit": "^0.15.0",
|
||||
"jszip": "~3.8.0",
|
||||
"react": "17.0.1",
|
||||
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
} from '@microsoft/sp-property-pane';
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
import PnPTelemetry from '@pnp/telemetry-js';
|
||||
import { initMonitoring, spfxTokenProvider } from '@tnsu/monitoring-web';
|
||||
|
||||
import * as strings from 'RequestPortalWebPartStrings';
|
||||
import RequestPortal from './components/RequestPortal';
|
||||
@@ -98,7 +100,14 @@ export default class RequestPortalWebPart extends BaseClientSideWebPart<IRequest
|
||||
}
|
||||
|
||||
protected onInit(): Promise<void> {
|
||||
// Логи, ошибки, console.error и запись экрана в мониторинг (monitoring.tnsu.kz). Токен — молча через
|
||||
// AAD веб-части (разрешение Logs.Write в package-solution.json); при отладке в workbench окружение — development.
|
||||
// Один на страницу: повторный вызов (несколько веб-частей) библиотека игнорирует сама.
|
||||
initMonitoring({ service: 'request-portal', getAccessToken: spfxTokenProvider(this.context.aadTokenProviderFactory) });
|
||||
installErrorLogging(); // до всего остального — чтобы поймать и ранние отклонения
|
||||
// Телеметрия PnP (её включает @pnp/spfx-controls-react) шлёт fetch на pnptelemetryproxy.azurewebsites.net
|
||||
// без catch: где адрес закрыт прокси или блокировщиком, это необработанный отказ промиса в мониторинге.
|
||||
PnPTelemetry.getInstance().optOut();
|
||||
initSP(this.context); // единый клиент PnPjs для записи в списки
|
||||
|
||||
// Адрес approval-route должен быть выставлен ДО загрузки партиций — они
|
||||
|
||||
@@ -207,28 +207,6 @@ export const LANGUAGE_LEVEL_OPTIONS: ISelectOption[] = [
|
||||
{ value: 'Свободный', label: 'Свободный' }
|
||||
];
|
||||
|
||||
/**
|
||||
* Программы (ПО) — ВРЕМЕННЫЙ список, пока нет справочника в API. Используется в
|
||||
* мультивыборе «Необходимые знания в программах». Меняется здесь одним местом.
|
||||
*/
|
||||
export const SOFTWARE_OPTIONS: ISelectOption[] = [
|
||||
{ value: '1С:Предприятие', label: '1С:Предприятие' },
|
||||
{ value: 'MS Word', label: 'MS Word' },
|
||||
{ value: 'MS Excel', label: 'MS Excel' },
|
||||
{ value: 'MS PowerPoint', label: 'MS PowerPoint' },
|
||||
{ value: 'MS Outlook', label: 'MS Outlook' },
|
||||
{ value: 'MS Project', label: 'MS Project' },
|
||||
{ value: 'AutoCAD', label: 'AutoCAD' },
|
||||
{ value: 'Autodesk Forma', label: 'Autodesk Forma' },
|
||||
{ value: 'BIM', label: 'BIM' },
|
||||
{ value: 'Revit', label: 'Revit' },
|
||||
{ value: 'ArchiCAD', label: 'ArchiCAD' },
|
||||
{ value: 'Компас-3D', label: 'Компас-3D' },
|
||||
{ value: 'Primavera', label: 'Primavera' },
|
||||
{ value: 'SAP', label: 'SAP' },
|
||||
{ value: 'Adobe Photoshop', label: 'Adobe Photoshop' }
|
||||
];
|
||||
|
||||
/** Категории «Обеспечение рабочего места» (+ «Другое» через allowOther). */
|
||||
export const WORKPLACE_PROVISION_OPTIONS: ISelectOption[] = [
|
||||
{ value: 'Оргтехника', label: 'Оргтехника' },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { CollapseSection, FormField, TextInput, TextArea, Select, MultiChoiceField } from '../../../shared/ui';
|
||||
import { PositionPicker } from '../../../shared/dictionary';
|
||||
import { PositionPicker, SOFTWARE_OPTIONS } from '../../../shared/dictionary';
|
||||
import { LanguagesField } from './LanguagesField';
|
||||
import {
|
||||
ISectionProps,
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
EDUCATION_OPTIONS,
|
||||
WORK_EXPERIENCE_OPTIONS,
|
||||
RESIDENCE_OPTIONS,
|
||||
SOFTWARE_OPTIONS,
|
||||
OTHER_VALUE
|
||||
} from '../model';
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
**первого** шага согласования и это текущий пользователь; сохраняются кнопкой
|
||||
«Сохранить» и автоматически при «Согласовать» (`updateReviewFields`,
|
||||
`DecisionPanel.onBeforeDecide`). Остальная форма при этом read-only.
|
||||
- **Необходимое ПО** — мультивыбор из общего списка `shared/dictionary/software.ts`
|
||||
(тот же, что в подборе) + своё значение. В SP и в маршрут — по-прежнему ТЕКСТОМ
|
||||
в колонке `Software` через запятую (`softwareList.ts`): условия «Software содержит
|
||||
AutoCAD» и старые заявки со свободным текстом работают как раньше.
|
||||
- **Мебель** — мультивыбор (`FURNITURE_OPTIONS`); при «Другое» появляется поле
|
||||
своего значения. В SP — `WorkplaceFurnitureJson` (JSON-массив) и
|
||||
`WorkplaceFurnitureOther`. Необязательная. Уходит в маршрут как
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { CollapseSection, FormField, TextArea, Toggle } from '../../../shared/ui';
|
||||
import { CollapseSection, FormField, FormModeProvider, MultiChoiceField, TextArea, Toggle } from '../../../shared/ui';
|
||||
import { SOFTWARE_OPTIONS } from '../../../shared/dictionary';
|
||||
import { ISectionProps } from '../model';
|
||||
import { formatSoftware, parseSoftware } from '../softwareList';
|
||||
|
||||
interface IEquipmentSectionProps extends ISectionProps {
|
||||
/** Согласующий-руководитель на этапе согласования может править ПО и доступы,
|
||||
@@ -13,13 +15,25 @@ export const EquipmentSection: React.FC<IEquipmentSectionProps> = ({ data, set,
|
||||
// берёт значение из FormMode (в форме подачи редактируемо, в просмотре — нет).
|
||||
const fieldReadOnly = approverEditable ? false : undefined;
|
||||
|
||||
const software = (
|
||||
<MultiChoiceField
|
||||
value={parseSoftware(data.Software)}
|
||||
onChange={(items) => set('Software', formatSoftware(items))}
|
||||
options={SOFTWARE_OPTIONS}
|
||||
allowOther
|
||||
placeholder="Выберите программу или введите свою"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<CollapseSection title="Оборудование и доступы" icon="monitor">
|
||||
<FormField label="Нужна ли техника" fieldKey="NeedsEquipment">
|
||||
<Toggle checked={data.NeedsEquipment} onChange={(v) => set('NeedsEquipment', v)} onLabel="Да" />
|
||||
</FormField>
|
||||
<FormField label="Необходимое ПО" htmlFor="Software" full>
|
||||
<TextArea id="Software" value={data.Software} onChange={(v) => set('Software', v)} readOnly={fieldReadOnly} />
|
||||
<FormField label="Необходимое ПО" fieldKey="Software" full>
|
||||
{/* У MultiChoiceField нет своего readOnly — право руководителя даём вложенным
|
||||
провайдером режима, как в FurnitureSection. */}
|
||||
{approverEditable ? <FormModeProvider readOnly={false}>{software}</FormModeProvider> : software}
|
||||
</FormField>
|
||||
<FormField label="Доступы" htmlFor="AccessRights" full>
|
||||
<TextArea id="AccessRights" value={data.AccessRights} onChange={(v) => set('AccessRights', v)} readOnly={fieldReadOnly} />
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { formatSoftware, parseSoftware } from './softwareList';
|
||||
|
||||
describe('parseSoftware', () => {
|
||||
it('разбирает сохранённый список', () => {
|
||||
expect(parseSoftware('AutoCAD, MS Excel, Revit')).toEqual(['AutoCAD', 'MS Excel', 'Revit']);
|
||||
});
|
||||
|
||||
it('пустой текст — пустой список', () => {
|
||||
expect(parseSoftware('')).toEqual([]);
|
||||
expect(parseSoftware(' , \n ')).toEqual([]);
|
||||
});
|
||||
|
||||
it('старый свободный текст с переносами строк — тоже чипами', () => {
|
||||
expect(parseSoftware('AutoCAD\nКорпоративная почта')).toEqual(['AutoCAD', 'Корпоративная почта']);
|
||||
});
|
||||
|
||||
it('убирает повторы', () => {
|
||||
expect(parseSoftware('SAP, SAP, Revit')).toEqual(['SAP', 'Revit']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatSoftware', () => {
|
||||
it('склеивает через запятую — формат, который ждут условия маршрута', () => {
|
||||
expect(formatSoftware(['AutoCAD', 'Revit'])).toBe('AutoCAD, Revit');
|
||||
});
|
||||
|
||||
it('туда и обратно — без потерь', () => {
|
||||
const items = ['1С:Предприятие', 'MS Word', 'Своя программа'];
|
||||
expect(parseSoftware(formatSoftware(items))).toEqual(items);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* «Необходимое ПО» — мультивыбор на экране, но в SP и в маршруте это ТЕКСТ в
|
||||
* колонке Software (условия вида «Software содержит AutoCAD» заведены по нему).
|
||||
* Поэтому модель хранит строку, а раздел переводит её в список и обратно.
|
||||
*/
|
||||
|
||||
const SEPARATOR = ', ';
|
||||
|
||||
/**
|
||||
* Текст колонки → список для мультивыбора. Делим по запятым и переносам строк:
|
||||
* у старых заявок ПО написано свободным текстом — так он тоже ляжет чипами.
|
||||
* Повторы убираем: чип с тем же значением был бы дублем.
|
||||
*/
|
||||
export function parseSoftware(text: string): string[] {
|
||||
const items = text
|
||||
.split(/[,\n]/)
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s.length > 0);
|
||||
return items.filter((s, i) => items.indexOf(s) === i);
|
||||
}
|
||||
|
||||
/** Список из мультивыбора → текст для колонки Software. */
|
||||
export function formatSoftware(items: string[]): string {
|
||||
return items.join(SEPARATOR);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { log } from '@tnsu/monitoring-web';
|
||||
import { getSP } from '../pnp/pnpjs';
|
||||
import '@pnp/sp/webs';
|
||||
import '@pnp/sp/lists';
|
||||
@@ -25,6 +26,14 @@ export interface IPendingRow extends IApprovalRow {
|
||||
isDelegator: boolean;
|
||||
}
|
||||
|
||||
// Решение → текст события в логах мониторинга.
|
||||
const DECISION_MESSAGE: Record<ApproverDecision, string> = {
|
||||
approve: 'Заявка согласована',
|
||||
return: 'Заявка возвращена на доработку',
|
||||
reject: 'Заявка отклонена',
|
||||
execute: 'Заявка выполнена исполнителем',
|
||||
};
|
||||
|
||||
// Решение → статус его строки в списке согласования.
|
||||
const ROW_STATUS: Record<ApproverDecision, string> = {
|
||||
approve: REQUEST_STATUS.approved,
|
||||
@@ -336,6 +345,7 @@ export class ApproverService {
|
||||
const rows = await this.approval.getForRequest(requestId);
|
||||
const requestStatus = this.computeRequestStatus(rows);
|
||||
await this.updateRequestStatus(requestId, requestStatus);
|
||||
await this.logDecision(requestId, rowId, decision, comment, requestStatus);
|
||||
emitRequestsChanged();
|
||||
return requestStatus;
|
||||
}
|
||||
@@ -364,6 +374,42 @@ export class ApproverService {
|
||||
return REQUEST_STATUS.execution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Решение — в логи мониторинга, с кодом и названием заявки, чтобы её было видно прямо в списке логов.
|
||||
* Код и название дочитываются отдельно; не получилось — пишем без них: решение уже применено.
|
||||
*/
|
||||
private async logDecision(
|
||||
requestId: number,
|
||||
rowId: number,
|
||||
decision: ApproverDecision,
|
||||
comment: string,
|
||||
requestStatus: string
|
||||
): Promise<void> {
|
||||
let code = '';
|
||||
let title = '';
|
||||
try {
|
||||
const item = (await this.dataList().items.getById(requestId).select('Title', 'RequestUniqueCode')()) as {
|
||||
Title?: string;
|
||||
RequestUniqueCode?: string;
|
||||
};
|
||||
code = item.RequestUniqueCode || '';
|
||||
title = item.Title || '';
|
||||
} catch {
|
||||
// без кода и названия — лог всё равно нужен
|
||||
}
|
||||
const what = [code, title].filter(Boolean).join(' · ') || `№${requestId}`;
|
||||
log.info(`${DECISION_MESSAGE[decision]}: ${what}`, {
|
||||
'request.id': requestId,
|
||||
'request.code': code,
|
||||
'request.title': title,
|
||||
'request.list': this.dataListRef,
|
||||
'request.status': requestStatus,
|
||||
'approval.decision': decision,
|
||||
'approval.rowId': rowId,
|
||||
'approval.comment': comment.slice(0, 500),
|
||||
});
|
||||
}
|
||||
|
||||
private dataList(): IList {
|
||||
return this.dataListRef.startsWith('/')
|
||||
? getSP().web.getList(this.dataListRef)
|
||||
|
||||
@@ -2,10 +2,13 @@ import '@pnp/sp/webs';
|
||||
import '@pnp/sp/lists';
|
||||
import '@pnp/sp/items';
|
||||
import { IList } from '@pnp/sp/lists';
|
||||
import { log } from '@tnsu/monitoring-web';
|
||||
import { getSP } from './pnp/pnpjs';
|
||||
import { buildRequestUniqueCode } from './requestCode';
|
||||
import { dataListTitle } from './listTitles';
|
||||
import { RequestTypeId } from '../models/types';
|
||||
import { REQUEST_TYPES } from '../data/requests';
|
||||
import { isSubmittedStatus } from './approval/models/statuses';
|
||||
|
||||
/**
|
||||
* Список данных, в который фактически пишем: listId (конкретная партиция —
|
||||
@@ -50,6 +53,7 @@ export async function saveRequestItem(
|
||||
|
||||
if (existingId) {
|
||||
await list.items.getById(existingId).update(item);
|
||||
logSaved(formId, existingId, undefined, item, false);
|
||||
return { id: existingId };
|
||||
}
|
||||
|
||||
@@ -58,5 +62,34 @@ export async function saveRequestItem(
|
||||
// Код известен только после создания элемента (нужен его Id).
|
||||
const code = buildRequestUniqueCode(codePrefix, id, new Date());
|
||||
await list.items.getById(id).update({ RequestUniqueCode: code });
|
||||
logSaved(formId, id, code, item, true);
|
||||
return { id, code };
|
||||
}
|
||||
|
||||
/**
|
||||
* События для мониторинга: какая заявка создана и отправлена на согласование (пользователь — из токена).
|
||||
* В тексте — вид, код и название заявки, чтобы её было видно прямо в списке логов. Решения согласующих
|
||||
* пишет approverDecision.service.ts.
|
||||
*/
|
||||
function logSaved(
|
||||
formId: RequestTypeId,
|
||||
id: number,
|
||||
code: string | undefined,
|
||||
item: Record<string, unknown>,
|
||||
created: boolean
|
||||
): void {
|
||||
const typeTitle = REQUEST_TYPES.find((t) => t.id === formId)?.title ?? formId;
|
||||
const title = typeof item.Title === 'string' ? item.Title : '';
|
||||
const status = typeof item.RequestStatus === 'string' ? item.RequestStatus : '';
|
||||
const what = [typeTitle, code, title].filter(Boolean).join(' · ');
|
||||
const attributes = {
|
||||
'request.type': formId,
|
||||
'request.typeTitle': typeTitle,
|
||||
'request.id': id,
|
||||
'request.code': code ?? '',
|
||||
'request.title': title,
|
||||
'request.status': status,
|
||||
};
|
||||
if (created) log.info(`Создана заявка: ${what}`, attributes);
|
||||
if (isSubmittedStatus(status)) log.info(`Заявка отправлена на согласование: ${what}`, attributes);
|
||||
}
|
||||
|
||||
@@ -50,3 +50,4 @@ export {
|
||||
parseOrganizationLine
|
||||
} from './organizationLines';
|
||||
export type { IOrganizationLine } from './organizationLines';
|
||||
export { SOFTWARE_OPTIONS } from './software';
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ISelectOption } from '@tnsu/ui-kit';
|
||||
|
||||
/**
|
||||
* Программы (ПО) — ВРЕМЕННЫЙ список, пока нет справочника в API. Общий для форм:
|
||||
* «Заявка на подбор» (3.8 Необходимые знания в программах) и «Организация
|
||||
* рабочего места» (Необходимое ПО). Пункт добавляется здесь — появляется в обеих.
|
||||
*
|
||||
* Значения уходят в условия маршрута как текст («Software содержит AutoCAD»),
|
||||
* поэтому существующие значения не переименовывать без правки условий в админке.
|
||||
*/
|
||||
export const SOFTWARE_OPTIONS: ISelectOption[] = [
|
||||
{ value: '1С:Предприятие', label: '1С:Предприятие' },
|
||||
{ value: 'MS Word', label: 'MS Word' },
|
||||
{ value: 'MS Excel', label: 'MS Excel' },
|
||||
{ value: 'MS PowerPoint', label: 'MS PowerPoint' },
|
||||
{ value: 'MS Outlook', label: 'MS Outlook' },
|
||||
{ value: 'MS Project', label: 'MS Project' },
|
||||
{ value: 'AutoCAD', label: 'AutoCAD' },
|
||||
{ value: 'Autodesk Forma', label: 'Autodesk Forma' },
|
||||
{ value: 'BIM', label: 'BIM' },
|
||||
{ value: 'Revit', label: 'Revit' },
|
||||
{ value: 'ArchiCAD', label: 'ArchiCAD' },
|
||||
{ value: 'Компас-3D', label: 'Компас-3D' },
|
||||
{ value: 'Primavera', label: 'Primavera' },
|
||||
{ value: 'SAP', label: 'SAP' },
|
||||
{ value: 'Adobe Photoshop', label: 'Adobe Photoshop' }
|
||||
];
|
||||
Reference in New Issue
Block a user