33 changed files with 5158 additions and 723 deletions
+1 -1
View File
@@ -169,7 +169,7 @@ function App() {
{/* Header, contenuto e footer della pagina */} {/* Header, contenuto e footer della pagina */}
<div className="grid_12 console_main"> <div className="grid_12 console_main">
<div className="inside"> <div className="inside">
<div className="receipt"> <div className="mainview">
<div className="container"> <div className="container">
<h1>Titolo Pagina</h1> <h1>Titolo Pagina</h1>
{elixFormsReactRender} {elixFormsReactRender}
+2 -2
View File
@@ -76,7 +76,7 @@ Le pagine seguono un layout standard elixForms con classi CSS specifiche:
<div class="fe-module-header-container"> <div class="fe-module-header-container">
<h2>Titolo Modulo</h2> <h2>Titolo Modulo</h2>
</div> </div>
<div class="receipt"> <div class="mainview">
<div class="container"> <div class="container">
<!-- Contenuto custom della pagina --> <!-- Contenuto custom della pagina -->
</div> </div>
@@ -115,7 +115,7 @@ Le pagine seguono un layout standard elixForms con classi CSS specifiche:
| `console_header` | Header della console | | `console_header` | Header della console |
| `console_main` | Area contenuto principale | | `console_main` | Area contenuto principale |
| `fe-module-header-container` | Header del modulo/form | | `fe-module-header-container` | Header del modulo/form |
| `receipt` | Container del contenuto del form | | `mainview` | Container del contenuto del form |
### Layout Campi Form (ElixFormsElement) ### Layout Campi Form (ElixFormsElement)
| Classe | Scopo | | Classe | Scopo |
View File
+43 -2
View File
@@ -4,12 +4,36 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Recupero Proposta CCT da contratti (BROWSER)",
"cwd": "${workspaceFolder}/react/recupero-proposta-cct-da-contratti",
"env": {
"NO_COLOR": "true"
},
"outputCapture": "console",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**",
"**/@vite/client/**"
],
"serverReadyAction": {
"action": "debugWithChrome",
"pattern": "Local:\\s+http://localhost:([0-9]+)/",
"uriFormat": "http://localhost:%s",
"webRoot": "${workspaceFolder}/react/recupero-proposta-cct-da-contratti/src"
},
},
{ {
"name": "Scelta Carriere (BROWSER)", "name": "Scelta Carriere (BROWSER)",
"cwd": "${workspaceFolder}/react/scelta-carriera", "cwd": "${workspaceFolder}/react/scelta-carriera",
"env": { "env": {
"NO_COLOR": "1" "NO_COLOR": "true"
}, },
"outputCapture": "console", "outputCapture": "console",
"type": "node", "type": "node",
@@ -32,7 +56,24 @@
"name": "Scelta Carriere (DEBUG ONLY)", "name": "Scelta Carriere (DEBUG ONLY)",
"cwd": "${workspaceFolder}/react/scelta-carriera", "cwd": "${workspaceFolder}/react/scelta-carriera",
"env": { "env": {
"NO_COLOR": "1" "NO_COLOR": "true"
},
"outputCapture": "console",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**",
"**/@vite/client/**"
]
},
{
"name": "Recupero Proposta CCT da contratti (DEBUG ONLY)",
"cwd": "${workspaceFolder}/react/recupero-proposta-cct-da-contratti",
"env": {
"NO_COLOR": "true"
}, },
"outputCapture": "console", "outputCapture": "console",
"type": "node", "type": "node",
+11
View File
@@ -0,0 +1,11 @@
# Mock server
## JSON-Server
See: <https://github.com/typicode/json-server>
To start server:
```pwsh
npx json-server db.json
```
+52
View File
@@ -0,0 +1,52 @@
{
"$schema": [
"./node_modules/json-server/schema.json"
],
"posts": [
{
"id": "1",
"title": "a title",
"views": 100
},
{
"id": "2",
"title": "another title",
"views": 200
}
],
"comments": [
{
"id": "1",
"text": "a comment about post 1",
"postId": "1"
},
{
"id": "2",
"text": "another comment about post 1",
"postId": "1"
}
],
"contratti": [
{
"idContratto": "ID_CONTRATTO_1",
"titoloContratto": "Titolo del contratto #1",
"idDomanda": "12345",
"idRicevuta": "ABCDE"
},
{
"idContratto": "ID_CONTRATTO_2",
"titoloContratto": "Titolo del secondo contratto",
"idDomanda": "67890",
"idRicevuta": "FGHIJ"
},
{
"idContratto": "ID_CONTRATTO_3",
"titoloContratto": "Terzo titolo",
"idDomanda": "13579",
"idRicevuta": "KLMNO"
}
],
"profile": {
"name": "typicode"
}
}
+532
View File
@@ -0,0 +1,532 @@
{
"name": "mock-server",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"json-server": "^1.0.0-beta.15"
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
"integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
"license": "MIT"
},
"node_modules/@tinyhttp/accepts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@tinyhttp/accepts/-/accepts-2.3.0.tgz",
"integrity": "sha512-hdKkMGAUqnagpWO1R8rVBYqbu4sWQ2Fo682gkJmO0nl54DPvnzxx81b2WZtV3VwB7EdLfUoasj2BAkyTcyZ5aw==",
"license": "MIT",
"dependencies": {
"mime": "4.1.0"
},
"engines": {
"node": ">=14.13.1"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/app": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@tinyhttp/app/-/app-3.0.7.tgz",
"integrity": "sha512-btit/gSWisksJ19crNLct1mwZvX+/AYwh/H1x8SB/VGDmNFkSsdRDZaa54wW1Eq3bM7mCIr7+l7Oh3tAi/C+Bw==",
"license": "MIT",
"dependencies": {
"@tinyhttp/accepts": "^2.3.0",
"@tinyhttp/cookie": "2.1.1",
"@tinyhttp/proxy-addr": "3.0.1",
"@tinyhttp/req": "2.2.8",
"@tinyhttp/res": "2.2.11",
"@tinyhttp/router": "2.2.5",
"regexparam": "^2.0.2"
},
"engines": {
"node": ">=16.10.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/content-disposition": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@tinyhttp/content-disposition/-/content-disposition-2.2.4.tgz",
"integrity": "sha512-5Kc5CM2Ysn3vTTArBs2vESUt0AQiWZA86yc1TI3B+lxXmtEq133C1nxXNOgnzhrivdPZIh3zLj5gDnZjoLL5GA==",
"license": "MIT",
"engines": {
"node": ">=12.17.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/content-type": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@tinyhttp/content-type/-/content-type-0.1.4.tgz",
"integrity": "sha512-dl6f3SHIJPYbhsW1oXdrqOmLSQF/Ctlv3JnNfXAE22kIP7FosqJHxkz/qj2gv465prG8ODKH5KEyhBkvwrueKQ==",
"license": "MIT",
"engines": {
"node": ">=12.4"
}
},
"node_modules/@tinyhttp/cookie": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cookie/-/cookie-2.1.1.tgz",
"integrity": "sha512-h/kL9jY0e0Dvad+/QU3efKZww0aTvZJslaHj3JTPmIPC9Oan9+kYqmh3M6L5JUQRuTJYFK2nzgL2iJtH2S+6dA==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
},
"funding": {
"type": "individual",
"url": "https://github.com/tinyhttp/tinyhttp?sponsor=1"
}
},
"node_modules/@tinyhttp/cookie-signature": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cookie-signature/-/cookie-signature-2.1.1.tgz",
"integrity": "sha512-VDsSMY5OJfQJIAtUgeQYhqMPSZptehFSfvEEtxr+4nldPA8IImlp3QVcOVuK985g4AFR4Hl1sCbWCXoqBnVWnw==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/cors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/cors/-/cors-2.0.1.tgz",
"integrity": "sha512-qrmo6WJuaiCzKWagv2yA/kw6hIISfF/hOqPWwmI6w0o8apeTMmRN3DoCFvQ/wNVuWVdU5J4KU7OX8aaSOEq51A==",
"license": "MIT",
"dependencies": {
"@tinyhttp/vary": "^0.1.3"
},
"engines": {
"node": ">=12.20 || 14.x || >=16"
}
},
"node_modules/@tinyhttp/encode-url": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/encode-url/-/encode-url-2.1.1.tgz",
"integrity": "sha512-AhY+JqdZ56qV77tzrBm0qThXORbsVjs/IOPgGCS7x/wWnsa/Bx30zDUU/jPAUcSzNOzt860x9fhdGpzdqbUeUw==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/etag": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/etag/-/etag-2.1.2.tgz",
"integrity": "sha512-j80fPKimGqdmMh6962y+BtQsnYPVCzZfJw0HXjyH70VaJBHLKGF+iYhcKqzI3yef6QBNa8DKIPsbEYpuwApXTw==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/forwarded": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@tinyhttp/forwarded/-/forwarded-2.1.2.tgz",
"integrity": "sha512-9H/eulJ68ElY/+zYpTpNhZ7vxGV+cnwaR6+oQSm7bVgZMyuQfgROW/qvZuhmgDTIxnGMXst+Ba4ij6w6Krcs3w==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/logger": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tinyhttp/logger/-/logger-2.1.0.tgz",
"integrity": "sha512-Ma1fJ9CwUbn9r61/4HW6+nflsVoslpOnCrfQ6UeZq7GGIgwLzofms3HoSVG7M+AyRMJpxlfcDdbH5oFVroDMKA==",
"license": "MIT",
"dependencies": {
"colorette": "^2.0.20",
"dayjs": "^1.11.13",
"http-status-emojis": "^2.2.0"
},
"engines": {
"node": ">=14.18 || >=16.20"
}
},
"node_modules/@tinyhttp/proxy-addr": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/proxy-addr/-/proxy-addr-3.0.1.tgz",
"integrity": "sha512-vP0JVsy9ZMIldsaP/QHdMF+sb3B6wn7e2QXRdqpX/Cqz1ie35Am29DK88DeVmiwdTQle3FtYaVNtU3RgTGYZ+w==",
"license": "MIT",
"dependencies": {
"@tinyhttp/forwarded": "2.1.2"
},
"engines": {
"node": ">=16.10.0"
}
},
"node_modules/@tinyhttp/req": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/@tinyhttp/req/-/req-2.2.8.tgz",
"integrity": "sha512-HCsceFNgMpssUsnRao16iJyyfdWRwKlhL7OMTPUEjZsZGREnBzpjlrPHA31G5xNNzR7XOWVXDXGyrGgSpcwGSA==",
"license": "MIT",
"dependencies": {
"@tinyhttp/accepts": "2.3.0",
"@tinyhttp/type-is": "2.2.5",
"@tinyhttp/url": "2.1.1",
"header-range-parser": "^1.1.3"
},
"engines": {
"node": ">=14.13.1"
}
},
"node_modules/@tinyhttp/res": {
"version": "2.2.11",
"resolved": "https://registry.npmjs.org/@tinyhttp/res/-/res-2.2.11.tgz",
"integrity": "sha512-t7GJzjqpG2svJ11RYvqaYU+xTV9MsEr0usbTIAWa5B8d7IIzpMC6AlT2K6wCIu1XGUYRpZY7qMM5cMgluvsfeg==",
"license": "MIT",
"dependencies": {
"@tinyhttp/content-disposition": "2.2.4",
"@tinyhttp/cookie": "2.1.1",
"@tinyhttp/cookie-signature": "2.1.1",
"@tinyhttp/encode-url": "2.1.1",
"@tinyhttp/req": "2.2.8",
"@tinyhttp/send": "2.2.5",
"@tinyhttp/vary": "^0.1.3",
"mime": "4.1.0"
},
"engines": {
"node": ">=14.13.1"
}
},
"node_modules/@tinyhttp/router": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@tinyhttp/router/-/router-2.2.5.tgz",
"integrity": "sha512-HI9Mpo9+IVpCzx/36okjJvtvifBSh3Ufhl9n1vylAbNLEykceJiMBkr06+W0qqRlo8TiZeUtg2XinEJu+GFcRA==",
"license": "MIT",
"dependencies": {
"regexparam": "^2.0.2"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@tinyhttp/send": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@tinyhttp/send/-/send-2.2.5.tgz",
"integrity": "sha512-XhBwziPOCydOJzb9rVw0xuKX6HmMA0gXKHHqec7V97jU6JtSCCIvwW2FBMh/XrG9S5W8DRETroPohASrIwf7Uw==",
"license": "MIT",
"dependencies": {
"@tinyhttp/content-type": "^0.1.4",
"@tinyhttp/etag": "2.1.2",
"mime": "4.1.0"
},
"engines": {
"node": ">=14.13.1"
}
},
"node_modules/@tinyhttp/type-is": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@tinyhttp/type-is/-/type-is-2.2.5.tgz",
"integrity": "sha512-BCPEB+NV8v/9lzEE9GbfRPAKVsyayp84m6SSWn70j8yFkPBXeuVeq004pwVrjW1CRdmAZz9ZSH147pqqzAdr5g==",
"license": "MIT",
"dependencies": {
"@tinyhttp/content-type": "^0.1.4",
"mime": "4.1.0"
},
"engines": {
"node": ">=14.13.1"
}
},
"node_modules/@tinyhttp/url": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tinyhttp/url/-/url-2.1.1.tgz",
"integrity": "sha512-POJeq2GQ5jI7Zrdmj22JqOijB5/GeX+LEX7DUdml1hUnGbJOTWDx7zf2b5cCERj7RoXL67zTgyzVblBJC+NJWg==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/@tinyhttp/vary": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@tinyhttp/vary/-/vary-0.1.3.tgz",
"integrity": "sha512-SoL83sQXAGiHN1jm2VwLUWQSQeDAAl1ywOm6T0b0Cg1CZhVsjoiZadmjhxF6FHCCY7OHHVaLnTgSMxTPIDLxMg==",
"license": "MIT",
"engines": {
"node": ">=12.20"
}
},
"node_modules/chalk": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"license": "MIT",
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"license": "MIT"
},
"node_modules/dayjs": {
"version": "1.11.21",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz",
"integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
"license": "MIT"
},
"node_modules/dot-prop": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.1.0.tgz",
"integrity": "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==",
"license": "MIT",
"dependencies": {
"type-fest": "^5.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eta": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/eta/-/eta-4.6.0.tgz",
"integrity": "sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==",
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/bgub/eta?sponsor=1"
}
},
"node_modules/header-range-parser": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/header-range-parser/-/header-range-parser-1.1.5.tgz",
"integrity": "sha512-n5JOx67HBL0MGqtu6NFoEYWb+xDYAOgBI5dBkyMDff1xHbhGnjCMglj1aiMNPHps6HwXO+2i5jbPU/zJSk7etQ==",
"license": "MIT",
"engines": {
"node": ">=12.22.0"
}
},
"node_modules/http-status-emojis": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/http-status-emojis/-/http-status-emojis-2.2.0.tgz",
"integrity": "sha512-ompKtgwpx8ff0hsbpIB7oE4ax1LXoHmftsHHStMELX56ivG3GhofTX8ZHWlUaFKfGjcGjw6G3rPk7dJRXMmbbg==",
"license": "MIT"
},
"node_modules/inflection": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-3.0.2.tgz",
"integrity": "sha512-+Bg3+kg+J6JUWn8J6bzFmOWkTQ6L/NHfDRSYU+EVvuKHDxUDHAXgqixHfVlzuBQaPOTac8hn43aPhMNk6rMe3g==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/json-server": {
"version": "1.0.0-beta.15",
"resolved": "https://registry.npmjs.org/json-server/-/json-server-1.0.0-beta.15.tgz",
"integrity": "sha512-I5UB/OWHLGoQW9IVld2yzZFYYiGYNBn2OYRlGbkfj5xDidT26yKYkV7Sr093zJtPh9zbofaLgyT89Ov5U0RRBQ==",
"license": "MIT",
"dependencies": {
"@tinyhttp/app": "^3.0.1",
"@tinyhttp/cors": "^2.0.1",
"@tinyhttp/logger": "^2.1.0",
"chalk": "^5.6.2",
"chokidar": "^5.0.0",
"dot-prop": "^10.1.0",
"eta": "^4.5.0",
"inflection": "^3.0.2",
"json5": "^2.2.3",
"lowdb": "^7.0.1",
"milliparsec": "^5.1.0",
"sirv": "^3.0.2",
"sort-on": "^7.0.0"
},
"bin": {
"json-server": "lib/bin.js"
},
"engines": {
"node": ">=22.12.0"
}
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/lowdb": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz",
"integrity": "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==",
"license": "MIT",
"dependencies": {
"steno": "^4.0.2"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/milliparsec": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/milliparsec/-/milliparsec-5.1.1.tgz",
"integrity": "sha512-jkEDaSWZp4/Q3vprqdqukBqUEyNNqC1pwTjZ5cp9YkaR1wv5fvTCd8VFsecbw7i8DNBGjzhJ83MDoPZlcTaPQg==",
"license": "MIT",
"engines": {
"node": ">=18.13 || >=19.20 || >=20"
}
},
"node_modules/mime": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz",
"integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==",
"funding": [
"https://github.com/sponsors/broofa"
],
"license": "MIT",
"bin": {
"mime": "bin/cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/mrmime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"license": "MIT",
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/regexparam": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.2.tgz",
"integrity": "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/sirv": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
"integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
"license": "MIT",
"dependencies": {
"@polka/url": "^1.0.0-next.24",
"mrmime": "^2.0.0",
"totalist": "^3.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/sort-on": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/sort-on/-/sort-on-7.0.0.tgz",
"integrity": "sha512-e+4RRxt7jsWdGPp4H5PKOER/ELYlemNB1plvW686Qi3j4WVaCjCpro2zaTD7Cn0VtBImq/hg3x1JfovMNXXfJQ==",
"license": "MIT",
"dependencies": {
"dot-prop": "^10.1.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/steno": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/steno/-/steno-4.0.2.tgz",
"integrity": "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/tagged-tag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
"integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==",
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/type-fest": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz",
"integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==",
"license": "(MIT OR CC0-1.0)",
"dependencies": {
"tagged-tag": "^1.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
}
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"dependencies": {
"json-server": "^1.0.0-beta.15"
}
}
+2 -2
View File
@@ -1,11 +1,11 @@
{ {
"name": "common", "name": "@elixforms/common",
"version": "0.0.1", "version": "0.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "common", "name": "@elixforms/common",
"version": "0.0.1", "version": "0.0.1",
"license": "ISC" "license": "ISC"
} }
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"name": "common", "name": "@elixforms/common",
"version": "0.0.1", "version": "0.0.1",
"description": "Common components to build elixForms custom pages", "description": "Common components to build elixForms custom pages",
"license": "ISC", "license": "ISC",
+55
View File
@@ -0,0 +1,55 @@
@import url('https://fonts.googleapis.com/css2?family=Titillium+Web:wght@300;400;600;700&display=swap');
@import url("https://console-unipr.elixforms.it/elixFormsCustom/css/elixForms.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/bootstrap_adaptation.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/bootstrap_overrides.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/console_user.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/designitalia_adaptation.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/fonts.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/isipcss_overrides.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/iulib.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/print.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/responsive.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/style-bs.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/style.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/design-bs/util.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/plugins/modaldisplay.css");
@import url("https://console-unipr.elixforms.it/rwe2/css/themes/blu-italia.css");
@import url("https://console-unipr.elixforms.it/rwe2/isipcss/css/grid_fluid.css");
/* Submit button styling (elixForms main submit) */
.mainview .container .submit {
width: auto;
text-align: right;
}
.mainview .container form input[type="submit"] {
background-color: #0066cc;
color: #ffffff;
border: none;
border-radius: 6px;
padding: 10px 20px;
font-weight: 700;
font-size: 15px;
cursor: pointer;
box-shadow: none;
transition:
transform 120ms ease,
opacity 120ms ease;
display: inline-block;
}
.mainview .container form input[type="submit"]:hover {
background-color: #0053a6;
}
.mainview .container form input[type="submit"]:active {
opacity: 0.5;
}
@media (max-width: 480px) {
.mainview .container form input[type="submit"] {
width: 100%;
padding-left: 18px;
padding-right: 18px;
}
}
+15 -10
View File
@@ -1,3 +1,4 @@
import './App.css'
import * as FluentUI from '@fluentui/react'; import * as FluentUI from '@fluentui/react';
import type { IElixFormsComponentFormState } from './IElixFormsComponentFormState'; import type { IElixFormsComponentFormState } from './IElixFormsComponentFormState';
import type { IElixFormsComponentProperties } from './IElixFormsComponentProperties'; import type { IElixFormsComponentProperties } from './IElixFormsComponentProperties';
@@ -129,9 +130,10 @@ export default abstract class ElixFormsComponentAbstract extends Component<IElix
hasTeamsContext, hasTeamsContext,
userDisplayName, userDisplayName,
additionalFieldsJson, additionalFieldsJson,
moduleTitle, headerTitle,
pageTitle, pageTitle,
pageDescription, pageDescription,
submitDescription,
heroImageSrc heroImageSrc
} = this.props; } = this.props;
@@ -166,14 +168,14 @@ export default abstract class ElixFormsComponentAbstract extends Component<IElix
<div className="grid_12 console_main"> <div className="grid_12 console_main">
<div className="inside"> <div className="inside">
{moduleTitle && ( {headerTitle && (
<div> <div>
<div className="fe-module-header-container"> <div className="fe-module-header-container">
<h2>{moduleTitle}</h2> <h2>{headerTitle}</h2>
</div> </div>
</div> </div>
)} )}
<div className="receipt"> <div className="mainview">
<div className="container"> <div className="container">
{pageTitle && <h1>{pageTitle}</h1>} {pageTitle && <h1>{pageTitle}</h1>}
{heroImageSrc && <img src={heroImageSrc} alt="Hero Image" className="hero-image" />} {heroImageSrc && <img src={heroImageSrc} alt="Hero Image" className="hero-image" />}
@@ -194,7 +196,10 @@ export default abstract class ElixFormsComponentAbstract extends Component<IElix
{this.createMandatoryFormFields(queryParams)} {this.createMandatoryFormFields(queryParams)}
{this.createAdditionalFormFields()} {this.createAdditionalFormFields()}
{this.renderCustomFormFields()} {this.renderCustomFormFields()}
<input type="submit" value="Submit" /> <br />
<div className='submit'>
<input type="submit" value={submitDescription ?? 'Submit'} />
</div>
</form> </form>
{this.renderExtraContentPost()} {this.renderExtraContentPost()}
@@ -260,8 +265,8 @@ export default abstract class ElixFormsComponentAbstract extends Component<IElix
}); });
const currentValue = this.state.formData[paramName] !== undefined const currentValue = this.state.formData[paramName] !== undefined
? this.state.formData[paramName] ? this.state.formData[paramName]
: (this.checkboxValues.get(paramName)?.join(',').trim() ?? ''); : (this.checkboxValues.get(paramName)?.join(',').trim() ?? '');
return new ElixFormsElement( return new ElixFormsElement(
<><FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label></>, <><FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label></>,
@@ -394,9 +399,9 @@ export default abstract class ElixFormsComponentAbstract extends Component<IElix
private createDropdownInput(paramName: string, label: string, values: Array<ElixFormsDropdownOption>, required: boolean = false): JSX.Element { private createDropdownInput(paramName: string, label: string, values: Array<ElixFormsDropdownOption>, required: boolean = false): JSX.Element {
const queryValue = QueryParamHelper.getOptionFromQuery(paramName); const queryValue = QueryParamHelper.getOptionFromQuery(paramName);
const currentValue = this.state.formData[paramName] !== undefined const currentValue = this.state.formData[paramName] !== undefined
? this.state.formData[paramName] ? this.state.formData[paramName]
: (queryValue?.toString() ?? ''); : (queryValue?.toString() ?? '');
const options: FluentUI.IDropdownOption[] = []; const options: FluentUI.IDropdownOption[] = [];
@@ -1,6 +1,3 @@
import type { JSX } from "react";
import type { IElixFormsComponentCustomFormFieldFactory } from "./IElixFormsComponentCustomFormFieldFactory";
export interface IElixFormsComponentProperties { export interface IElixFormsComponentProperties {
description: string; description: string;
isDarkTheme: boolean; isDarkTheme: boolean;
@@ -13,6 +10,7 @@ export interface IElixFormsComponentProperties {
headerTitle?: string; headerTitle?: string;
pageTitle?: string; pageTitle?: string;
pageDescription?: string; pageDescription?: string;
submitDescription?: string;
heroImageSrc?: string; heroImageSrc?: string;
} }
+3
View File
@@ -0,0 +1,3 @@
declare module "*.css";
declare module "*.svg";
declare module "*.png";
+1 -1
View File
@@ -9,7 +9,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"isolatedModules": true, "isolatedModules": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"skipLibCheck": true, "skipLibCheck": true
}, },
"include": [ "include": [
"**/*" "**/*"
+302 -303
View File
@@ -1,303 +1,302 @@
{ {
"name": "react", "name": "react",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"@fluentui/react": "^8.125.6", "@fluentui/react": "^8.125.6",
"react": "^19.2.7", "react": "^19.2.7",
"react-dom": "^19.2.5" "react-dom": "^19.2.5"
} }
}, },
"node_modules/@fluentui/date-time-utilities": { "node_modules/@fluentui/date-time-utilities": {
"version": "8.6.11", "version": "8.6.11",
"resolved": "https://registry.npmjs.org/@fluentui/date-time-utilities/-/date-time-utilities-8.6.11.tgz", "resolved": "https://registry.npmjs.org/@fluentui/date-time-utilities/-/date-time-utilities-8.6.11.tgz",
"integrity": "sha512-zq49tveFzmzwgaJ73rVvxu9+rqhPBIAJSbevciIQnmvv6dlh2GzZcL14Zevk9QV+q6CWaF6yzvhT11E2TpAv8Q==", "integrity": "sha512-zq49tveFzmzwgaJ73rVvxu9+rqhPBIAJSbevciIQnmvv6dlh2GzZcL14Zevk9QV+q6CWaF6yzvhT11E2TpAv8Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/dom-utilities": { "node_modules/@fluentui/dom-utilities": {
"version": "2.3.10", "version": "2.3.10",
"resolved": "https://registry.npmjs.org/@fluentui/dom-utilities/-/dom-utilities-2.3.10.tgz", "resolved": "https://registry.npmjs.org/@fluentui/dom-utilities/-/dom-utilities-2.3.10.tgz",
"integrity": "sha512-6WDImiLqTOpkEtfUKSStcTDpzmJfL6ZammomcjawN9xH/8u8G3Hx72CIt2MNck9giw/oUlNLJFdWRAjeP3rmPQ==", "integrity": "sha512-6WDImiLqTOpkEtfUKSStcTDpzmJfL6ZammomcjawN9xH/8u8G3Hx72CIt2MNck9giw/oUlNLJFdWRAjeP3rmPQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/font-icons-mdl2": { "node_modules/@fluentui/font-icons-mdl2": {
"version": "8.5.73", "version": "8.5.74",
"resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.73.tgz", "resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.74.tgz",
"integrity": "sha512-pyR9OE8LJMEVDAUTaTu/rGXaMCsyRqpp5124DhBoFNf6q5kI660IgbzuQadCpyMBEQadYI5/GLkLN7b1Lgou9Q==", "integrity": "sha512-q3QiQ2CuFdMjtiP9U5+Qi8LMhxKqWEi7C8R+O6SuaGbGS+3YOO/1iuenhKtt961OHn5ev/0M4j4okUZ1112GSw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/style-utilities": "^8.15.1", "@fluentui/style-utilities": "^8.15.2",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/foundation-legacy": { "node_modules/@fluentui/foundation-legacy": {
"version": "8.6.6", "version": "8.6.7",
"resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.6.6.tgz", "resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.6.7.tgz",
"integrity": "sha512-PIcMLOymLvIunp9DrBHUT+dZqwyslKsIOPi+5g/fLU/ySzCg3fs6wQyWHxN3esI5FsSfWi+yCpp+6u5+N00kJQ==", "integrity": "sha512-mu1wHlkom+XT+mlaGe7GW4eIZeIT9OjgdXg2Az/P670N7JA1OKcjHd8F/9ktMb5FGrXJ287AjQDNCDfWnjnCYA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/style-utilities": "^8.15.1", "@fluentui/style-utilities": "^8.15.2",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/keyboard-key": { "node_modules/@fluentui/keyboard-key": {
"version": "0.4.23", "version": "0.4.23",
"resolved": "https://registry.npmjs.org/@fluentui/keyboard-key/-/keyboard-key-0.4.23.tgz", "resolved": "https://registry.npmjs.org/@fluentui/keyboard-key/-/keyboard-key-0.4.23.tgz",
"integrity": "sha512-9GXeyUqNJUdg5JiQUZeGPiKnRzMRi9YEUn1l9zq6X/imYdMhxHrxpVZS12129cBfgvPyxt9ceJpywSfmLWqlKA==", "integrity": "sha512-9GXeyUqNJUdg5JiQUZeGPiKnRzMRi9YEUn1l9zq6X/imYdMhxHrxpVZS12129cBfgvPyxt9ceJpywSfmLWqlKA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/merge-styles": { "node_modules/@fluentui/merge-styles": {
"version": "8.6.14", "version": "8.6.14",
"resolved": "https://registry.npmjs.org/@fluentui/merge-styles/-/merge-styles-8.6.14.tgz", "resolved": "https://registry.npmjs.org/@fluentui/merge-styles/-/merge-styles-8.6.14.tgz",
"integrity": "sha512-vghuHFAfQgS9WLIIs4kgDOCh/DHd5vGIddP4/bzposhlAVLZR6wUBqldm9AuCdY88r5LyCRMavVJLV+Up3xdvA==", "integrity": "sha512-vghuHFAfQgS9WLIIs4kgDOCh/DHd5vGIddP4/bzposhlAVLZR6wUBqldm9AuCdY88r5LyCRMavVJLV+Up3xdvA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/react": { "node_modules/@fluentui/react": {
"version": "8.125.6", "version": "8.125.7",
"resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.125.6.tgz", "resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.125.7.tgz",
"integrity": "sha512-uvq0PdAL+Tznikek54zbS31JefTqcPaCkwjHjJz0t8NAC2ZFHozKnkApaQo2+sf0390K3k1ErGWr/+3Tvc6+JQ==", "integrity": "sha512-MsputVjgAZEcSzfr6nXBghfZnqu+GKT4NCBwLeSL8yyQEugUxyZJNp4TVZblGdMognyRDbobNn+/zIhEK4sxNQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/date-time-utilities": "^8.6.11", "@fluentui/date-time-utilities": "^8.6.11",
"@fluentui/font-icons-mdl2": "^8.5.73", "@fluentui/font-icons-mdl2": "^8.5.74",
"@fluentui/foundation-legacy": "^8.6.6", "@fluentui/foundation-legacy": "^8.6.7",
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/react-focus": "^8.10.6", "@fluentui/react-focus": "^8.10.7",
"@fluentui/react-hooks": "^8.10.2", "@fluentui/react-hooks": "^8.10.2",
"@fluentui/react-portal-compat-context": "^9.0.15", "@fluentui/react-portal-compat-context": "^9.0.15",
"@fluentui/react-window-provider": "^2.3.2", "@fluentui/react-window-provider": "^2.3.2",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/style-utilities": "^8.15.1", "@fluentui/style-utilities": "^8.15.2",
"@fluentui/theme": "^2.7.2", "@fluentui/theme": "^2.7.2",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"@microsoft/load-themed-styles": "^1.10.26", "@microsoft/load-themed-styles": "^1.10.26",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"@types/react-dom": ">=16.8.0 <20.0.0", "@types/react-dom": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0", "react": ">=16.8.0 <20.0.0",
"react-dom": ">=16.8.0 <20.0.0" "react-dom": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/react-focus": { "node_modules/@fluentui/react-focus": {
"version": "8.10.6", "version": "8.10.7",
"resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.10.6.tgz", "resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.10.7.tgz",
"integrity": "sha512-hMQw7AETttfex3XEAB/XQalJSL8/RgzOdJrL1RPKcrxdkBal0C1MRQ43Bbmw/4WtI0vK0wI4+jHvCIlM0lkodA==", "integrity": "sha512-Uf0wliddeVPEYylNvbBqYu2V2ofCQ/YhC5JHIFT4RwBkZil1Ta3X+9EFhJMO1LejyLXTKnMMimPxdPS1XzLTGQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/keyboard-key": "^0.4.23", "@fluentui/keyboard-key": "^0.4.23",
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/style-utilities": "^8.15.1", "@fluentui/style-utilities": "^8.15.2",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/react-hooks": { "node_modules/@fluentui/react-hooks": {
"version": "8.10.2", "version": "8.10.2",
"resolved": "https://registry.npmjs.org/@fluentui/react-hooks/-/react-hooks-8.10.2.tgz", "resolved": "https://registry.npmjs.org/@fluentui/react-hooks/-/react-hooks-8.10.2.tgz",
"integrity": "sha512-HAd5cX50yKW/LljWlwt+FpSpdS/pNJutk9kMb7FyzxfoGBulL7sj6vX2HvxhSKyJMRKuTstXTdfJmsh22+3W3w==", "integrity": "sha512-HAd5cX50yKW/LljWlwt+FpSpdS/pNJutk9kMb7FyzxfoGBulL7sj6vX2HvxhSKyJMRKuTstXTdfJmsh22+3W3w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/react-window-provider": "^2.3.2", "@fluentui/react-window-provider": "^2.3.2",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/react-portal-compat-context": { "node_modules/@fluentui/react-portal-compat-context": {
"version": "9.0.15", "version": "9.0.15",
"resolved": "https://registry.npmjs.org/@fluentui/react-portal-compat-context/-/react-portal-compat-context-9.0.15.tgz", "resolved": "https://registry.npmjs.org/@fluentui/react-portal-compat-context/-/react-portal-compat-context-9.0.15.tgz",
"integrity": "sha512-DpV+qtFvM3dmH1j8ZD+YcM5vaTvmQPHUAx6tQnnmIoYJWs2R0wU/L5p2EajXy7zSg74jrDbDRxzaziamoOaJdg==", "integrity": "sha512-DpV+qtFvM3dmH1j8ZD+YcM5vaTvmQPHUAx6tQnnmIoYJWs2R0wU/L5p2EajXy7zSg74jrDbDRxzaziamoOaJdg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@swc/helpers": "^0.5.1" "@swc/helpers": "^0.5.1"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.14.0 <20.0.0", "@types/react": ">=16.14.0 <20.0.0",
"react": ">=16.14.0 <20.0.0" "react": ">=16.14.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/react-window-provider": { "node_modules/@fluentui/react-window-provider": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.3.2.tgz", "resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.3.2.tgz",
"integrity": "sha512-T15zFPIWr9De8hNkapne7YyvcxclyTK2bMXXHZwbWLkVeH/lGHRG0CIy/calNGKa86wuzMJhq8iqFW2W6+EwVQ==", "integrity": "sha512-T15zFPIWr9De8hNkapne7YyvcxclyTK2bMXXHZwbWLkVeH/lGHRG0CIy/calNGKa86wuzMJhq8iqFW2W6+EwVQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/set-version": { "node_modules/@fluentui/set-version": {
"version": "8.2.24", "version": "8.2.24",
"resolved": "https://registry.npmjs.org/@fluentui/set-version/-/set-version-8.2.24.tgz", "resolved": "https://registry.npmjs.org/@fluentui/set-version/-/set-version-8.2.24.tgz",
"integrity": "sha512-8uNi2ThvNgF+6d3q2luFVVdk/wZV0AbRfJ85kkvf2+oSRY+f6QVK0w13vMorNhA5puumKcZniZoAfUF02w7NSg==", "integrity": "sha512-8uNi2ThvNgF+6d3q2luFVVdk/wZV0AbRfJ85kkvf2+oSRY+f6QVK0w13vMorNhA5puumKcZniZoAfUF02w7NSg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/style-utilities": { "node_modules/@fluentui/style-utilities": {
"version": "8.15.1", "version": "8.15.2",
"resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.15.1.tgz", "resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.15.2.tgz",
"integrity": "sha512-EwjJE7P7XWViNIN+Klm4rFCaADujsfwHB4nzkYeD0zjMokrznsiAvqERxaGZMCRH7tO+DLKITt7kaoQstNLCVQ==", "integrity": "sha512-rss7pkgiyNQuo1OpS7R2X6IJXIwDzQ0fxQxIeBB7Xp7lM+AwcKn5V7fzgIgCyE7BI6TWSy2TeQJ9Jtr/4fYEaw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/theme": "^2.7.2", "@fluentui/theme": "^2.7.2",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"@microsoft/load-themed-styles": "^1.10.26", "@microsoft/load-themed-styles": "^1.10.26",
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@fluentui/theme": { "node_modules/@fluentui/theme": {
"version": "2.7.2", "version": "2.7.2",
"resolved": "https://registry.npmjs.org/@fluentui/theme/-/theme-2.7.2.tgz", "resolved": "https://registry.npmjs.org/@fluentui/theme/-/theme-2.7.2.tgz",
"integrity": "sha512-UXGNfGa/1bLmYrOpmHXdvyc7CzlNSKUQAADweTncbNoMF1DvscWEjPj5kxFgCmOU8wVtvvn4GraNNUSWtNxeeA==", "integrity": "sha512-UXGNfGa/1bLmYrOpmHXdvyc7CzlNSKUQAADweTncbNoMF1DvscWEjPj5kxFgCmOU8wVtvvn4GraNNUSWtNxeeA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"@fluentui/utilities": "^8.17.2", "@fluentui/utilities": "^8.17.2",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@fluentui/utilities": { "node_modules/@fluentui/utilities": {
"version": "8.17.2", "version": "8.17.2",
"resolved": "https://registry.npmjs.org/@fluentui/utilities/-/utilities-8.17.2.tgz", "resolved": "https://registry.npmjs.org/@fluentui/utilities/-/utilities-8.17.2.tgz",
"integrity": "sha512-TmeWVtGN+Lk0mch7tuRcbkeMdrBwltI68fvQbPwcNLo4igFtTInMmjEnVJGa7pBQN5lQAmHYqB9IJI6RZU/t6w==", "integrity": "sha512-TmeWVtGN+Lk0mch7tuRcbkeMdrBwltI68fvQbPwcNLo4igFtTInMmjEnVJGa7pBQN5lQAmHYqB9IJI6RZU/t6w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluentui/dom-utilities": "^2.3.10", "@fluentui/dom-utilities": "^2.3.10",
"@fluentui/merge-styles": "^8.6.14", "@fluentui/merge-styles": "^8.6.14",
"@fluentui/react-window-provider": "^2.3.2", "@fluentui/react-window-provider": "^2.3.2",
"@fluentui/set-version": "^8.2.24", "@fluentui/set-version": "^8.2.24",
"tslib": "^2.1.0" "tslib": "^2.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": ">=16.8.0 <20.0.0", "@types/react": ">=16.8.0 <20.0.0",
"react": ">=16.8.0 <20.0.0" "react": ">=16.8.0 <20.0.0"
} }
}, },
"node_modules/@microsoft/load-themed-styles": { "node_modules/@microsoft/load-themed-styles": {
"version": "1.10.295", "version": "1.10.295",
"resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.295.tgz", "resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.295.tgz",
"integrity": "sha512-W+IzEBw8a6LOOfRJM02dTT7BDZijxm+Z7lhtOAz1+y9vQm1Kdz9jlAO+qCEKsfxtUOmKilW8DIRqFw2aUgKeGg==", "integrity": "sha512-W+IzEBw8a6LOOfRJM02dTT7BDZijxm+Z7lhtOAz1+y9vQm1Kdz9jlAO+qCEKsfxtUOmKilW8DIRqFw2aUgKeGg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.5.23", "version": "0.5.23",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
"integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"tslib": "^2.8.0" "tslib": "^2.8.0"
} }
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.2.17", "version": "19.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
"integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
}, },
"node_modules/@types/react-dom": { "node_modules/@types/react-dom": {
"version": "19.2.3", "version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"peerDependencies": { "peerDependencies": {
"@types/react": "^19.2.0" "@types/react": "^19.2.0"
} }
}, },
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.2.3", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"license": "MIT" "license": "MIT",
}, "peer": true
"node_modules/react": { },
"version": "19.2.7", "node_modules/react": {
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", "version": "19.2.7",
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
"license": "MIT", "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"peer": true, "license": "MIT",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "19.2.7", "version": "19.2.7",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"license": "MIT", "license": "MIT",
"peer": true, "dependencies": {
"dependencies": { "scheduler": "^0.27.0"
"scheduler": "^0.27.0" },
}, "peerDependencies": {
"peerDependencies": { "react": "^19.2.7"
"react": "^19.2.7" }
} },
}, "node_modules/scheduler": {
"node_modules/scheduler": { "version": "0.27.0",
"version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT"
"license": "MIT" },
}, "node_modules/tslib": {
"node_modules/tslib": { "version": "2.8.1",
"version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD"
"license": "0BSD" }
} }
} }
}
+7 -7
View File
@@ -1,7 +1,7 @@
{ {
"dependencies": { "dependencies": {
"@fluentui/react": "^8.125.6", "@fluentui/react": "^8.125.6",
"react": "^19.2.7", "react": "^19.2.7",
"react-dom": "^19.2.5" "react-dom": "^19.2.5"
} }
} }
@@ -0,0 +1,21 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{js,jsx}'],
extends: [
js.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
globals: globals.browser,
parserOptions: { ecmaFeatures: { jsx: true } },
},
},
])
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="it">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>recupero-proposta-cct-da-contratti</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,27 @@
{
"name": "@elixforms/recupero-proposta-cct-da-contratti",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"vite-plugin-css-injected-by-js": "^5.0.1"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
"eslint": "^10.2.1",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.5.0",
"sass-embedded": "^1.99.0",
"vite": "^8.0.10"
}
}
@@ -0,0 +1,102 @@
/* ===== Autocomplete Component Styles ===== */
.autocomplete-wrapper {
position: relative;
width: 100%;
}
.autocomplete-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 1000;
background: #ffffff;
border: 1px solid #a19f9d;
border-top: none;
border-radius: 0 0 2px 2px;
max-height: 250px;
overflow-y: auto;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.autocomplete-dropdown-item {
padding: 8px 12px;
cursor: pointer;
font-size: 14px;
line-height: 1.4;
border-bottom: 1px solid #f3f2f1;
transition: background-color 0.1s ease;
}
.autocomplete-dropdown-item:last-child {
border-bottom: none;
}
.autocomplete-dropdown-item:hover,
.autocomplete-dropdown-item.highlighted {
background-color: #edebe9;
}
.autocomplete-dropdown-item .contract-id {
font-weight: 600;
color: #323130;
}
.autocomplete-dropdown-item .contract-title {
color: #605e5c;
}
.autocomplete-loading {
padding: 12px;
text-align: center;
color: #605e5c;
font-size: 14px;
font-style: italic;
}
.autocomplete-no-results {
padding: 12px;
text-align: center;
color: #a19f9d;
font-size: 14px;
}
.autocomplete-error {
padding: 12px;
text-align: center;
color: #a4262c;
font-size: 14px;
}
/* ===== Selected Contract Summary ===== */
.selected-contract-summary {
margin-top: 8px;
padding: 10px 12px;
background-color: #f3f2f1;
border: 1px solid #e1dfdd;
border-radius: 2px;
font-size: 13px;
color: #323130;
}
.selected-contract-summary .summary-row {
display: flex;
gap: 8px;
margin-bottom: 4px;
}
.selected-contract-summary .summary-row:last-child {
margin-bottom: 0;
}
.selected-contract-summary .summary-label {
font-weight: 600;
min-width: 120px;
color: #605e5c;
}
.selected-contract-summary .summary-value {
color: #323130;
}
@@ -0,0 +1,20 @@
import './App.css'
import RecuperoPropostaCctDaContrattiComponent from './RecuperoPropostaCctDaContrattiComponent';
function App() {
return (
<RecuperoPropostaCctDaContrattiComponent
description=""
isDarkTheme={false}
environmentMessage=""
hasTeamsContext={false}
userDisplayName=""
headerTitle="Modulo - Placeholder Titolo Modulo"
pageTitle="Recupero Proposta CCT da Contratti"
pageDescription=""
submitDescription='CONFERMA E PROSEGUI'
/>
);
}
export default App
@@ -0,0 +1,361 @@
import React, { type JSX } from 'react';
import * as FluentUI from '@fluentui/react';
import ElixFormsComponentAbstract from '@common/src/ElixFormsComponentAbstract';
import type { IElixFormsComponentCustomFormFieldFactory } from '@common/src/IElixFormsComponentCustomFormFieldFactory';
import { ElixFormsElement } from '@common/src/ElixFormsElement';
import { QueryParamHelper } from '@common/src/QueryParamHelper';
import config from './config.json';
/** Singolo risultato restituito dall'API esterna */
interface ContrattoResult {
idContratto: string;
titoloContratto: string;
idDomanda: string;
idRicevuta: string;
}
/** State aggiuntivo per gestire l'autocomplete */
interface RecuperoPropostaState {
searchText: string;
searchResults: ContrattoResult[];
isLoading: boolean;
isDropdownOpen: boolean;
selectedContract: ContrattoResult | null;
highlightedIndex: number;
errorMessage: string;
}
export default class RecuperoPropostaCctDaContrattiComponent extends ElixFormsComponentAbstract {
/** Stato locale per l'autocomplete (separato dal formData gestito dall'abstract) */
private autocompleteState: RecuperoPropostaState = {
searchText: '',
searchResults: [],
isLoading: false,
isDropdownOpen: false,
selectedContract: null,
highlightedIndex: -1,
errorMessage: '',
};
/** Timer per il debounce della ricerca */
private debounceTimer: ReturnType<typeof setTimeout> | null = null;
/** Ref al container per gestire il click-outside */
private autocompleteRef: React.RefObject<HTMLDivElement | null> = React.createRef();
private static readonly formFieldKeys = {
idContratto: 'COL0010',
titoloContratto: 'COL0020',
idDomanda: 'COL0030',
idRicevuta: 'COL0040',
} as const;
/** Codice fiscale letto dalla query string (COL0009), usato solo per la chiamata API */
private codiceFiscale: string;
constructor(props: any) {
super(props);
this.codiceFiscale = QueryParamHelper.getDecodedTextFromQuery('COL0009') ?? '';
}
override componentDidMount(): void {
// Listener per chiudere il dropdown al click fuori dall'autocomplete
document.addEventListener('mousedown', this.handleClickOutside);
}
override componentWillUnmount(): void {
document.removeEventListener('mousedown', this.handleClickOutside);
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
}
private handleClickOutside = (event: MouseEvent): void => {
if (
this.autocompleteRef.current &&
!this.autocompleteRef.current.contains(event.target as Node)
) {
this.autocompleteState.isDropdownOpen = false;
this.forceUpdate();
}
};
/**
* Chiama l'API esterna per ottenere i contratti corrispondenti al testo di ricerca.
* Autenticazione: Basic Auth (username:password) + header X-Api-Key.
*/
private async fetchContratti(searchTerm: string): Promise<void> {
this.autocompleteState.isLoading = true;
this.autocompleteState.errorMessage = '';
this.forceUpdate();
try {
const url = new URL(config.apiUrl);
url.searchParams.set('cod_fis', this.codiceFiscale);
url.searchParams.set('term', searchTerm);
const credentials = btoa(`${config.apiUsername}:${config.apiPassword}`);
const response = await fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': `Basic ${credentials}`,
'X-Api-Key': config.apiKey,
'Accept': 'application/json',
},
});
if (!response.ok) {
throw new Error(`Errore API: ${response.status} ${response.statusText}`);
}
const data: ContrattoResult[] = await response.json();
this.autocompleteState.searchResults = data;
this.autocompleteState.isDropdownOpen = data.length > 0;
this.autocompleteState.highlightedIndex = -1;
this.autocompleteState.isLoading = false;
this.forceUpdate();
} catch (error) {
console.error('Errore durante la ricerca contratti:', error);
this.autocompleteState.searchResults = [];
this.autocompleteState.isDropdownOpen = false;
this.autocompleteState.isLoading = false;
this.autocompleteState.errorMessage =
error instanceof Error ? error.message : 'Errore durante la ricerca';
this.forceUpdate();
}
}
/**
* Gestisce il cambio testo nell'input di ricerca.
* Applica debounce e chiama l'API al raggiungimento del minimo di caratteri.
*/
private handleSearchChange = (_event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string): void => {
const text = newValue ?? '';
this.autocompleteState.searchText = text;
// Se l'utente cancella il testo, resetta anche la selezione
if (text.length === 0) {
this.autocompleteState.searchResults = [];
this.autocompleteState.isDropdownOpen = false;
this.autocompleteState.highlightedIndex = -1;
this.autocompleteState.errorMessage = '';
this.clearSelection();
this.forceUpdate();
return;
}
// Debounce della ricerca
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
if (text.length >= config.minCharsForSearch) {
this.debounceTimer = setTimeout(() => {
this.fetchContratti(text);
}, 300);
} else {
this.autocompleteState.searchResults = [];
this.autocompleteState.isDropdownOpen = false;
this.autocompleteState.highlightedIndex = -1;
this.forceUpdate();
}
};
/**
* Gestisce la navigazione da tastiera nel dropdown (frecce, Invio, Escape).
*/
private handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
const { searchResults, isDropdownOpen, highlightedIndex } = this.autocompleteState;
if (!isDropdownOpen || searchResults.length === 0) return;
switch (event.key) {
case 'ArrowDown':
event.preventDefault();
this.autocompleteState.highlightedIndex = Math.min(
highlightedIndex + 1,
searchResults.length - 1
);
this.forceUpdate();
break;
case 'ArrowUp':
event.preventDefault();
this.autocompleteState.highlightedIndex = Math.max(highlightedIndex - 1, 0);
this.forceUpdate();
break;
case 'Enter':
event.preventDefault();
if (highlightedIndex >= 0 && highlightedIndex < searchResults.length) {
this.selectContract(searchResults[highlightedIndex]);
}
break;
case 'Escape':
event.preventDefault();
this.autocompleteState.isDropdownOpen = false;
this.forceUpdate();
break;
}
};
/**
* Seleziona un contratto dal dropdown e popola i campi hidden del form.
*/
private selectContract(contract: ContrattoResult): void {
this.autocompleteState.selectedContract = contract;
this.autocompleteState.searchText = `[${contract.idContratto}] ${contract.titoloContratto}`;
this.autocompleteState.isDropdownOpen = false;
this.autocompleteState.searchResults = [];
this.autocompleteState.highlightedIndex = -1;
// Aggiorna il formData con i valori selezionati
this.setState({
formData: {
...this.state.formData,
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idContratto]: contract.idContratto,
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.titoloContratto]: contract.titoloContratto,
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idDomanda]: contract.idDomanda,
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idRicevuta]: contract.idRicevuta,
},
}, () => {
console.log('Contratto selezionato:', contract);
console.log('Form data aggiornato:', this.state.formData);
});
}
/**
* Resetta la selezione e svuota i campi hidden.
*/
private clearSelection(): void {
this.autocompleteState.selectedContract = null;
this.setState({
formData: {
...this.state.formData,
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idContratto]: '',
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.titoloContratto]: '',
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idDomanda]: '',
[RecuperoPropostaCctDaContrattiComponent.formFieldKeys.idRicevuta]: '',
},
});
}
/**
* Renderizza il componente autocomplete completo (label + input + dropdown).
*/
private renderAutocomplete(): JSX.Element {
const { searchResults, isLoading, isDropdownOpen, highlightedIndex, errorMessage, searchText } = this.autocompleteState;
const autocompleteInput = (
<>
<div className="autocomplete-wrapper" ref={this.autocompleteRef}>
<FluentUI.TextField
id="autocomplete-search"
name="autocomplete-search"
placeholder="Digita almeno 3 caratteri per cercare..."
value={searchText}
onChange={this.handleSearchChange}
onKeyDown={this.handleKeyDown}
className="isiportalPartialAdminFormFieldSingleLineText"
autoComplete="off"
/>
{isLoading && (
<div className="autocomplete-dropdown">
<div className="autocomplete-loading">
<FluentUI.Spinner size={FluentUI.SpinnerSize.small} label="Ricerca in corso..." />
</div>
</div>
)}
{!isLoading && isDropdownOpen && searchResults.length > 0 && (
<div className="autocomplete-dropdown">
{searchResults.map((contract, index) => (
<div
key={`${contract.idContratto}_${index}`}
className={`autocomplete-dropdown-item${index === highlightedIndex ? ' highlighted' : ''}`}
onMouseDown={(e) => {
e.preventDefault(); // Previene blur del TextField
this.selectContract(contract);
}}
onMouseEnter={() => {
this.autocompleteState.highlightedIndex = index;
this.forceUpdate();
}}
>
<span className="contract-id">[{contract.idContratto}]</span>{' '}
<span className="contract-title">{contract.titoloContratto}</span>
</div>
))}
</div>
)}
{!isLoading && isDropdownOpen && searchResults.length === 0 && (
<div className="autocomplete-dropdown">
<div className="autocomplete-no-results">Nessun risultato trovato</div>
</div>
)}
{errorMessage && (
<div className="autocomplete-error">{errorMessage}</div>
)}
</div>
{this.autocompleteState.selectedContract && (
<div className="selected-contract-summary">
<div className="summary-row">
<span className="summary-label">ID Contratto:</span>
<span className="summary-value">{this.autocompleteState.selectedContract.idContratto}</span>
</div>
<div className="summary-row">
<span className="summary-label">Titolo:</span>
<span className="summary-value">{this.autocompleteState.selectedContract.titoloContratto}</span>
</div>
<div className="summary-row">
<span className="summary-label">ID Domanda:</span>
<span className="summary-value">{this.autocompleteState.selectedContract.idDomanda}</span>
</div>
<div className="summary-row">
<span className="summary-label">ID Ricevuta:</span>
<span className="summary-value">{this.autocompleteState.selectedContract.idRicevuta}</span>
</div>
</div>
)}
</>
);
return new ElixFormsElement(
<FluentUI.Label htmlFor="autocomplete-search">Cerca Contratto</FluentUI.Label>,
autocompleteInput
).render();
}
/**
* Override del metodo factory per definire i campi custom del form.
* - Autocomplete per la ricerca contratti
* - 4 campi hidden (COL0010, COL0020, COL0030, COL0040) per i dati da rimandare a elixForms
*/
protected override createCustomFormFields(formFieldFactory: IElixFormsComponentCustomFormFieldFactory): JSX.Element {
const fieldKeys = RecuperoPropostaCctDaContrattiComponent.formFieldKeys;
const idContratto = this.state.formData[fieldKeys.idContratto] ?? '';
const titoloContratto = this.state.formData[fieldKeys.titoloContratto] ?? '';
const idDomanda = this.state.formData[fieldKeys.idDomanda] ?? '';
const idRicevuta = this.state.formData[fieldKeys.idRicevuta] ?? '';
return (
<>
{this.renderAutocomplete()}
{/* Campi hidden per i dati del contratto selezionato — verranno inviati nel POST a elixForms */}
<input type="hidden" id="idContratto_hidden" name={fieldKeys.idContratto} value={idContratto} />
<input type="hidden" id="titoloContratto_hidden" name={fieldKeys.titoloContratto} value={titoloContratto} />
<input type="hidden" id="idDomanda_hidden" name={fieldKeys.idDomanda} value={idDomanda} />
<input type="hidden" id="idRicevuta_hidden" name={fieldKeys.idRicevuta} value={idRicevuta} />
</>
);
}
}
@@ -0,0 +1,7 @@
{
"apiUrl": "http://localhost:8000/contratti/cerca",
"apiUsername": "your-username",
"apiPassword": "your-password",
"apiKey": "your-api-key",
"minCharsForSearch": 3
}
@@ -0,0 +1,3 @@
declare module "*.css";
declare module "*.svg";
declare module "*.png";
@@ -0,0 +1 @@
/* Global styles - currently empty */
@@ -0,0 +1,13 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Root element not found')
createRoot(rootElement).render(
<StrictMode>
<App />
</StrictMode>,
)
@@ -0,0 +1,18 @@
{
"extends": "../tsconfig.base.json",
"references": [
{
"path": "../common"
}
],
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"allowJs": true,
"checkJs": true,
//"resolveJsonModule": true
},
"include": [
"src/**/*"
]
}
@@ -0,0 +1,38 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
import path from "path";
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
cssInjectedByJsPlugin() // forza l'iniezione del CSS nel JS
],
build: {
outDir: 'dist',
cssCodeSplit: false, // evita file CSS separati
rollupOptions: {
input: 'src/main.jsx',
output: {
codeSplitting: false, // forza tutto in un singolo bundle
manualChunks: undefined, // disabilita la creazione di chunk multipli
entryFileNames: 'recupero-proposta-cct-da-contratti.js',
assetFileNames: '[name].[ext]'
},
},
sourcemap: true,
},
resolve: {
alias: {
"@common": path.resolve(__dirname, "../common"),
}
},
server: {
fs: {
allow: [
".." // permette import fuori dalla cartella del progetto
]
}
}
})
+363 -382
View File
File diff suppressed because it is too large Load Diff
+3 -8
View File
@@ -1,26 +1,21 @@
import { useState } from 'react'
// import reactLogo from './assets/react.svg'
// import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png' import heroImg from './assets/hero.png'
import './App.css' import './App.css'
import SceltaCarrieraComponent from './SceltaCarrieraComponent'; import SceltaCarrieraComponent from './SceltaCarrieraComponent';
function App() { function App() {
const [count, setCount] = useState(0)
return ( return (
<SceltaCarrieraComponent <SceltaCarrieraComponent
description="" description=""
isDarkTheme={false} isDarkTheme={false}
environmentMessage="" environmentMessage=""
hasTeamsContext={false} hasTeamsContext={false}
userDisplayName="John Doe" userDisplayName="John Doe"
moduleTitle="Modulo A/13 - Richiesta di Certificato" headerTitle="Modulo A/13 - Richiesta di Certificato"
pageTitle="Scelta Carriera" pageTitle="Scelta Carriera"
pageDescription="Benvenuto nella piattaforma di scelta carriera! Esplora le tue opzioni e trova la strada giusta per te." pageDescription="Benvenuto nella piattaforma di scelta carriera! Esplora le tue opzioni e trova la strada giusta per te."
heroImageSrc={heroImg} heroImageSrc={heroImg}
/> />
); )
} }
export default App export default App
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"files": [], //"files": [],
"references": [ "references": [
{ {
"path": "./common" "path": "./common"