diff --git a/.postcssrc.json b/.postcssrc.json
new file mode 100644
index 0000000..72f908d
--- /dev/null
+++ b/.postcssrc.json
@@ -0,0 +1,5 @@
+{
+ "plugins": {
+ "@tailwindcss/postcss": {}
+ }
+}
\ No newline at end of file
diff --git a/openapi-generator.yaml b/openapi-generator.yaml
new file mode 100644
index 0000000..0738df7
--- /dev/null
+++ b/openapi-generator.yaml
@@ -0,0 +1,3 @@
+additionalProperties:
+ fileNaming: kebab-case
+ modelPropertyNaming: camelCase
\ No newline at end of file
diff --git a/openapitools.json b/openapitools.json
new file mode 100644
index 0000000..f052220
--- /dev/null
+++ b/openapitools.json
@@ -0,0 +1,7 @@
+{
+ "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
+ "spaces": 2,
+ "generator-cli": {
+ "version": "7.17.0"
+ }
+}
diff --git a/package-lock.json b/package-lock.json
index ca8a2b0..5f7824f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,8 +14,14 @@
"@angular/forms": "^20.3.0",
"@angular/platform-browser": "^20.3.0",
"@angular/router": "^20.3.0",
+ "@openapitools/openapi-generator-cli": "^2.25.2",
+ "@tailwindcss/postcss": "^4.1.17",
"@tailwindcss/vite": "^4.1.17",
+ "browser-image-compression": "^2.0.2",
+ "jwt-decode": "^4.0.0",
"ng-zorro-antd": "^20.4.0",
+ "postcss": "^8.5.6",
+ "rimraf": "^6.1.3",
"rxjs": "~7.8.0",
"tailwindcss": "^4.1.17",
"tslib": "^2.3.0",
@@ -25,6 +31,7 @@
"@angular/build": "^20.3.9",
"@angular/cli": "^20.3.9",
"@angular/compiler-cli": "^20.3.0",
+ "baseline-browser-mapping": "^2.10.32",
"less": "^4.2.0",
"typescript": "~5.9.2"
}
@@ -238,6 +245,18 @@
"node": ">= 14.0.0"
}
},
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -971,6 +990,16 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@borewit/text-codec": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz",
+ "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
@@ -1531,7 +1560,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz",
"integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"chardet": "^2.1.1",
@@ -1751,7 +1779,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
@@ -1761,7 +1788,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
@@ -2014,6 +2040,15 @@
"win32"
]
},
+ "node_modules/@lukeed/csprng": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
+ "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@modelcontextprotocol/sdk": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.3.tgz",
@@ -2469,6 +2504,90 @@
"node": ">= 10"
}
},
+ "node_modules/@nestjs/axios": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz",
+ "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
+ "axios": "^1.3.1",
+ "rxjs": "^7.0.0"
+ }
+ },
+ "node_modules/@nestjs/common": {
+ "version": "11.1.9",
+ "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.9.tgz",
+ "integrity": "sha512-zDntUTReRbAThIfSp3dQZ9kKqI+LjgLp5YZN5c1bgNRDuoeLySAoZg46Bg1a+uV8TMgIRziHocglKGNzr6l+bQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "file-type": "21.1.0",
+ "iterare": "1.2.1",
+ "load-esm": "1.0.3",
+ "tslib": "2.8.1",
+ "uid": "2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "class-transformer": ">=0.4.1",
+ "class-validator": ">=0.13.2",
+ "reflect-metadata": "^0.1.12 || ^0.2.0",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "class-transformer": {
+ "optional": true
+ },
+ "class-validator": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/core": {
+ "version": "11.1.9",
+ "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.9.tgz",
+ "integrity": "sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nuxt/opencollective": "0.4.1",
+ "fast-safe-stringify": "2.1.1",
+ "iterare": "1.2.1",
+ "path-to-regexp": "8.3.0",
+ "tslib": "2.8.1",
+ "uid": "2.0.2"
+ },
+ "engines": {
+ "node": ">= 20"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^11.0.0",
+ "@nestjs/microservices": "^11.0.0",
+ "@nestjs/platform-express": "^11.0.0",
+ "@nestjs/websockets": "^11.0.0",
+ "reflect-metadata": "^0.1.12 || ^0.2.0",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@nestjs/microservices": {
+ "optional": true
+ },
+ "@nestjs/platform-express": {
+ "optional": true
+ },
+ "@nestjs/websockets": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@npmcli/agent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz",
@@ -2718,6 +2837,225 @@
"node": "^18.17.0 || >=20.5.0"
}
},
+ "node_modules/@nuxt/opencollective": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz",
+ "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "consola": "^3.2.3"
+ },
+ "bin": {
+ "opencollective": "bin/opencollective.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0",
+ "npm": ">=5.10.0"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz",
+ "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "consola": "^2.15.0",
+ "node-fetch": "^2.6.1"
+ },
+ "bin": {
+ "opencollective": "bin/opencollective.js"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective/node_modules/consola": {
+ "version": "2.15.3",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
+ "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==",
+ "license": "MIT"
+ },
+ "node_modules/@nuxtjs/opencollective/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli": {
+ "version": "2.25.2",
+ "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.25.2.tgz",
+ "integrity": "sha512-TXElbW1NXCy0EECXiO5AD2ZzT1dmaCs41Z8t3pBUGaJf8zgF/Lm0P6GRhVEpw29iHBNjZcy8nrgQ1acUfuCdng==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@nestjs/axios": "4.0.1",
+ "@nestjs/common": "11.1.9",
+ "@nestjs/core": "11.1.9",
+ "@nuxtjs/opencollective": "0.3.2",
+ "axios": "1.13.2",
+ "chalk": "4.1.2",
+ "commander": "8.3.0",
+ "compare-versions": "6.1.1",
+ "concurrently": "9.2.1",
+ "console.table": "0.10.0",
+ "fs-extra": "11.3.2",
+ "glob": "13.0.0",
+ "inquirer": "8.2.7",
+ "proxy-agent": "6.5.0",
+ "reflect-metadata": "0.2.2",
+ "rxjs": "7.8.2",
+ "tslib": "2.8.1"
+ },
+ "bin": {
+ "openapi-generator-cli": "main.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/openapi_generator"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/glob": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
+ "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.2",
+ "path-scurry": "^2.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/lru-cache": {
+ "version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz",
+ "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==",
+ "license": "ISC",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/minimatch": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
+ "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/brace-expansion": "^5.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/path-scurry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
+ "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@openapitools/openapi-generator-cli/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@parcel/watcher": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
@@ -3680,6 +4018,19 @@
"node": ">= 10"
}
},
+ "node_modules/@tailwindcss/postcss": {
+ "version": "4.1.17",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.17.tgz",
+ "integrity": "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "@tailwindcss/node": "4.1.17",
+ "@tailwindcss/oxide": "4.1.17",
+ "postcss": "^8.4.41",
+ "tailwindcss": "4.1.17"
+ }
+ },
"node_modules/@tailwindcss/vite": {
"version": "4.1.17",
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.17.tgz",
@@ -3694,6 +4045,36 @@
"vite": "^5.2.0 || ^6 || ^7"
}
},
+ "node_modules/@tokenizer/inflate": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.3.1.tgz",
+ "integrity": "sha512-4oeoZEBQdLdt5WmP/hx1KZ6D3/Oid/0cUb2nk4F0pTDAWy+KCH3/EnAkZF/bvckWo8I33EqBm01lIPgmgc8rCA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.1",
+ "fflate": "^0.8.2",
+ "token-types": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/@tokenizer/token": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
+ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+ "license": "MIT"
+ },
+ "node_modules/@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+ "license": "MIT"
+ },
"node_modules/@tufjs/canonical-json": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz",
@@ -3772,7 +4153,6 @@
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 14"
@@ -3881,6 +4261,36 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/ast-types": {
+ "version": "0.13.4",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
+ "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3888,14 +4298,46 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/baseline-browser-mapping": {
- "version": "2.8.27",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.27.tgz",
- "integrity": "sha512-2CXFpkjVnY2FT+B6GrSYxzYf65BJWEqz5tIRHCvNsZZ2F3CmsCB37h8SpYgKG7y9C4YAeTipIPWG7EmFmhAeXA==",
+ "version": "2.10.32",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz",
+ "integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
- "baseline-browser-mapping": "dist/cli.js"
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/basic-ftp": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
}
},
"node_modules/beasties": {
@@ -3918,6 +4360,17 @@
"node": ">=14.0.0"
}
},
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
"node_modules/body-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
@@ -3982,6 +4435,15 @@
"node": ">=8"
}
},
+ "node_modules/browser-image-compression": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/browser-image-compression/-/browser-image-compression-2.0.2.tgz",
+ "integrity": "sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw==",
+ "license": "MIT",
+ "dependencies": {
+ "uzip": "0.20201231.0"
+ }
+ },
"node_modules/browserslist": {
"version": "4.28.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
@@ -4017,6 +4479,30 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -4106,7 +4592,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -4171,7 +4656,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
"integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/chokidar": {
@@ -4220,7 +4704,6 @@
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
"integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4289,11 +4772,19 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -4306,7 +4797,6 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
"license": "MIT"
},
"node_modules/colorette": {
@@ -4316,6 +4806,229 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/compare-versions": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
+ "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==",
+ "license": "MIT"
+ },
+ "node_modules/concurrently": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz",
+ "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "4.1.2",
+ "rxjs": "7.8.2",
+ "shell-quote": "1.8.3",
+ "supports-color": "8.1.1",
+ "tree-kill": "1.2.2",
+ "yargs": "17.7.2"
+ },
+ "bin": {
+ "conc": "dist/bin/concurrently.js",
+ "concurrently": "dist/bin/concurrently.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concurrently/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concurrently/node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/concurrently/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/concurrently/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concurrently/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concurrently/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concurrently/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/concurrently/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
+ "node_modules/console.table": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz",
+ "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==",
+ "license": "MIT",
+ "dependencies": {
+ "easy-table": "1.1.0"
+ },
+ "engines": {
+ "node": "> 0.10"
+ }
+ },
"node_modules/content-disposition": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
@@ -4438,6 +5151,15 @@
"url": "https://github.com/sponsors/fb55"
}
},
+ "node_modules/data-uri-to-buffer": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@@ -4458,7 +5180,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -4472,6 +5193,41 @@
}
}
},
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/degenerator": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ast-types": "^0.13.4",
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -4554,7 +5310,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -4572,6 +5327,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/easy-table": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz",
+ "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==",
+ "license": "MIT",
+ "optionalDependencies": {
+ "wcwidth": ">=1.0.1"
+ }
+ },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -4603,31 +5367,6 @@
"node": ">= 0.8"
}
},
- "node_modules/encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "iconv-lite": "^0.6.2"
- }
- },
- "node_modules/encoding/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/enhanced-resolve": {
"version": "5.18.3",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
@@ -4702,7 +5441,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4712,7 +5450,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4722,7 +5459,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -4731,6 +5467,21 @@
"node": ">= 0.4"
}
},
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/esbuild": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
@@ -4776,7 +5527,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4789,6 +5539,77 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/escodegen/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -4910,6 +5731,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "license": "MIT"
+ },
"node_modules/fast-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
@@ -4944,6 +5771,45 @@
}
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/file-type": {
+ "version": "21.1.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.1.0.tgz",
+ "integrity": "sha512-boU4EHmP3JXkwDo4uhyBhTt5pPstxB6eEXKJBu2yu2l7aAMMm7QQYQEzssJmKReZYrFdFOJS8koVo6bXIBGDqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tokenizer/inflate": "^0.3.1",
+ "strtok3": "^10.3.1",
+ "token-types": "^6.0.0",
+ "uint8array-extras": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+ }
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4975,6 +5841,26 @@
"node": ">= 0.8"
}
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/foreground-child": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
@@ -4992,6 +5878,43 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/form-data/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/form-data/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -5012,6 +5935,20 @@
"node": ">= 0.8"
}
},
+ "node_modules/fs-extra": {
+ "version": "11.3.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
+ "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
"node_modules/fs-minipass": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
@@ -5043,7 +5980,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -5063,7 +5999,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
@@ -5086,7 +6021,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -5111,7 +6045,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -5121,6 +6054,20 @@
"node": ">= 0.4"
}
},
+ "node_modules/get-uri": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz",
+ "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==",
+ "license": "MIT",
+ "dependencies": {
+ "basic-ftp": "^5.0.2",
+ "data-uri-to-buffer": "^6.0.2",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
@@ -5153,7 +6100,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -5168,11 +6114,19 @@
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -5181,11 +6135,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -5288,7 +6256,6 @@
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "dev": true,
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.0",
@@ -5302,7 +6269,6 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
@@ -5316,7 +6282,6 @@
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -5329,6 +6294,26 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/ignore-walk": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz",
@@ -5393,7 +6378,6 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true,
"license": "ISC"
},
"node_modules/ini": {
@@ -5406,11 +6390,265 @@
"node": "^18.17.0 || >=20.5.0"
}
},
+ "node_modules/inquirer": {
+ "version": "8.2.7",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz",
+ "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/external-editor": "^1.0.0",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.1",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.21",
+ "mute-stream": "0.0.8",
+ "ora": "^5.4.1",
+ "run-async": "^2.4.0",
+ "rxjs": "^7.5.5",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6",
+ "wrap-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inquirer/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/inquirer/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/inquirer/node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/inquirer/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/inquirer/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inquirer/node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inquirer/node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "license": "ISC"
+ },
+ "node_modules/inquirer/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inquirer/node_modules/ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inquirer/node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC"
+ },
+ "node_modules/inquirer/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inquirer/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/ip-address": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
"integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 12"
@@ -5562,6 +6800,15 @@
"node": ">=10"
}
},
+ "node_modules/iterare": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz",
+ "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -5644,6 +6891,18 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"node_modules/jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
@@ -5654,6 +6913,15 @@
],
"license": "MIT"
},
+ "node_modules/jwt-decode": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+ "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/less": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/less/-/less-4.4.2.tgz",
@@ -6007,6 +7275,31 @@
"@lmdb/lmdb-win32-x64": "3.4.2"
}
},
+ "node_modules/load-esm": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz",
+ "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ },
+ {
+ "type": "buymeacoffee",
+ "url": "https://buymeacoffee.com/borewit"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=13.2.0"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
"node_modules/log-symbols": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
@@ -6181,7 +7474,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -6274,6 +7566,15 @@
"node": ">= 0.6"
}
},
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/mimic-function": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
@@ -6304,11 +7605,10 @@
}
},
"node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
- "license": "ISC",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
}
@@ -6483,7 +7783,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/msgpackr": {
@@ -6590,6 +7889,15 @@
"node": ">= 0.6"
}
},
+ "node_modules/netmask": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
"node_modules/ng-zorro-antd": {
"version": "20.4.0",
"resolved": "https://registry.npmjs.org/ng-zorro-antd/-/ng-zorro-antd-20.4.0.tgz",
@@ -6619,6 +7927,26 @@
"license": "MIT",
"optional": true
},
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-gyp": {
"version": "11.5.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz",
@@ -7050,11 +8378,42 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/pac-proxy-agent": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz",
+ "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "get-uri": "^6.0.1",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.6",
+ "pac-resolver": "^7.0.1",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/pac-resolver": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
+ "license": "MIT",
+ "dependencies": {
+ "degenerator": "^5.0.0",
+ "netmask": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/pacote": {
@@ -7255,7 +8614,6 @@
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
- "dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -7387,6 +8745,40 @@
"node": ">= 0.10"
}
},
+ "node_modules/proxy-agent": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
+ "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "http-proxy-agent": "^7.0.1",
+ "https-proxy-agent": "^7.0.6",
+ "lru-cache": "^7.14.1",
+ "pac-proxy-agent": "^7.1.0",
+ "proxy-from-env": "^1.1.0",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/proxy-agent/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
"node_modules/prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -7447,6 +8839,20 @@
"node": ">= 0.10"
}
},
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@@ -7465,8 +8871,17 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
- "dev": true,
- "license": "Apache-2.0"
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/require-from-string": {
"version": "2.0.2",
@@ -7533,6 +8948,103 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/rimraf": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+ "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "glob": "^13.0.3",
+ "package-json-from-dist": "^1.0.1"
+ },
+ "bin": {
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/rimraf/node_modules/brace-expansion": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/lru-cache": {
+ "version": "11.5.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz",
+ "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/rimraf/node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/rollup": {
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz",
@@ -7591,6 +9103,15 @@
"node": ">= 18"
}
},
+ "node_modules/run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -7605,7 +9126,6 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -7626,7 +9146,6 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true,
"license": "MIT"
},
"node_modules/sass": {
@@ -7741,6 +9260,18 @@
"node": ">=8"
}
},
+ "node_modules/shell-quote": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+ "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -7869,7 +9400,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6.0.0",
@@ -7880,7 +9410,6 @@
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz",
"integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ip-address": "^10.0.1",
@@ -7895,7 +9424,6 @@
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
"integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
@@ -8018,6 +9546,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
@@ -8132,6 +9669,37 @@
"node": ">=8"
}
},
+ "node_modules/strtok3": {
+ "version": "10.3.4",
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz",
+ "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tokenizer/token": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -8252,6 +9820,12 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "license": "MIT"
+ },
"node_modules/tinyglobby": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
@@ -8292,6 +9866,39 @@
"node": ">=0.6"
}
},
+ "node_modules/token-types": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz",
+ "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@borewit/text-codec": "^0.1.0",
+ "@tokenizer/token": "^0.3.0",
+ "ieee754": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -8314,6 +9921,18 @@
"node": "^18.17.0 || >=20.5.0"
}
},
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/type-is": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
@@ -8344,6 +9963,30 @@
"node": ">=14.17"
}
},
+ "node_modules/uid": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz",
+ "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@lukeed/csprng": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/uint8array-extras": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
+ "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/unique-filename": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz",
@@ -8370,6 +10013,15 @@
"node": "^18.17.0 || >=20.5.0"
}
},
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -8421,6 +10073,18 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/uzip": {
+ "version": "0.20201231.0",
+ "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz",
+ "integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==",
+ "license": "MIT"
+ },
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -8557,6 +10221,15 @@
"node": ">=10.13.0"
}
},
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
"node_modules/weak-lru-cache": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz",
@@ -8565,6 +10238,22 @@
"license": "MIT",
"optional": true
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -8585,7 +10274,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -8690,7 +10378,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8700,7 +10387,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -8716,14 +10402,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8733,7 +10417,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -8748,7 +10431,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -8768,7 +10450,6 @@
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
diff --git a/package.json b/package.json
index 4ec4df3..4cc1a66 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,8 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
- "watch": "ng build --watch --configuration development"
+ "watch": "ng build --watch --configuration development",
+ "openapi": "rimraf src/app/services/api && openapi-generator-cli generate -i http://localhost:5298/swagger/v1/swagger.json -g typescript-angular -o src/app/services/api -c openapi-generator.yaml"
},
"prettier": {
"printWidth": 100,
@@ -27,8 +28,14 @@
"@angular/forms": "^20.3.0",
"@angular/platform-browser": "^20.3.0",
"@angular/router": "^20.3.0",
+ "@openapitools/openapi-generator-cli": "^2.25.2",
+ "@tailwindcss/postcss": "^4.1.17",
"@tailwindcss/vite": "^4.1.17",
+ "browser-image-compression": "^2.0.2",
+ "jwt-decode": "^4.0.0",
"ng-zorro-antd": "^20.4.0",
+ "postcss": "^8.5.6",
+ "rimraf": "^6.1.3",
"rxjs": "~7.8.0",
"tailwindcss": "^4.1.17",
"tslib": "^2.3.0",
@@ -38,6 +45,7 @@
"@angular/build": "^20.3.9",
"@angular/cli": "^20.3.9",
"@angular/compiler-cli": "^20.3.0",
+ "baseline-browser-mapping": "^2.10.32",
"less": "^4.2.0",
"typescript": "~5.9.2"
}
diff --git a/src/app/app.config.ts b/src/app/app.config.ts
index 010986a..23dc4c7 100644
--- a/src/app/app.config.ts
+++ b/src/app/app.config.ts
@@ -1,19 +1,21 @@
-import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
-import { provideRouter } from '@angular/router';
+import {ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection} from '@angular/core';
+import {provideRouter} from '@angular/router';
-import { routes } from './app.routes';
-import { fr_FR, provideNzI18n } from 'ng-zorro-antd/i18n';
-import { registerLocaleData } from '@angular/common';
+import {routes} from './app.routes';
+import {fr_FR, provideNzI18n} from 'ng-zorro-antd/i18n';
+import {registerLocaleData} from '@angular/common';
import fr from '@angular/common/locales/fr';
-import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
-import { provideHttpClient } from '@angular/common/http';
+import {provideAnimationsAsync} from '@angular/platform-browser/animations/async';
+import {provideHttpClient, withInterceptors} from '@angular/common/http';
+import {authInterceptor} from "./interceptors/auth-interceptor";
registerLocaleData(fr);
export const appConfig: ApplicationConfig = {
- providers: [
- provideBrowserGlobalErrorListeners(),
- provideZoneChangeDetection({ eventCoalescing: true }),
- provideRouter(routes), provideNzI18n(fr_FR), provideAnimationsAsync(), provideHttpClient()
- ]
+ providers: [
+ provideBrowserGlobalErrorListeners(),
+ provideZoneChangeDetection({eventCoalescing: true}),
+ provideRouter(routes), provideNzI18n(fr_FR), provideAnimationsAsync(), provideHttpClient(),
+ provideHttpClient(withInterceptors([authInterceptor]))
+ ]
};
diff --git a/src/app/app.css b/src/app/app.css
index 73a1c7e..e69de29 100644
--- a/src/app/app.css
+++ b/src/app/app.css
@@ -1,46 +0,0 @@
-:host {
- display: flex;
-}
-
-.app-layout {
- height: 100vh;
-}
-
-.top-nav {
- line-height: 64px;
-}
-
-.logo {
- float: left;
- height: 64px;
- padding-right: 24px;
- line-height: 64px;
- background: #001529;
-}
-
-.logo img {
- display: inline-block;
- height: 32px;
- width: 32px;
- vertical-align: middle;
-}
-
-.logo h1 {
- display: inline-block;
- margin: 0 0 0 15px;
- color: #fff;
- font-weight: 600;
- font-size: 20px;
- font-family: Avenir,Helvetica Neue,Arial,Helvetica,sans-serif;
- vertical-align: middle;
-}
-
-nz-content {
- padding: 24px 50px;
-}
-
-.inner-content {
- padding: 24px;
- background: #fff;
- height: 100%;
-}
diff --git a/src/app/app.html b/src/app/app.html
index 8f2b8dc..90c6b64 100644
--- a/src/app/app.html
+++ b/src/app/app.html
@@ -1,70 +1 @@
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 107dbfe..3d610b8 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -1,41 +1,70 @@
-import { Routes } from '@angular/router';
+import {Routes} from '@angular/router';
+import {authGuard} from "./guards/auth.guard";
export const routes: Routes = [
{
path: '',
pathMatch: 'full',
- redirectTo: '/welcome'
+ redirectTo: '/login'
},
{
- path: 'welcome',
- loadComponent: () => import('./pages/welcome/welcome').then(x => x.Welcome)
+ path: 'login',
+ loadComponent: () => import('./pages/login/login').then(x => x.Login)
},
{
- path: 'stock',
- loadComponent: () => import('./pages/stock/stock').then(x => x.Stock)
- },
- {
- path: 'supplier',
- loadComponent: () => import('./pages/supplier/supplier').then(x => x.Supplier)
- },
- {
- path: 'deliverer',
- loadComponent: () => import('./pages/deliverer/deliverer').then(x => x.Deliverer)
- },
- {
- path: 'quotation',
- loadComponent: () => import('./pages/quotation/quotation').then(x => x.Quotation)
- },
- {
- path: 'purchase-order',
- loadComponent: () => import('./pages/purchase-order/purchase-order').then(x => x.PurchaseOrder)
- },
- {
- path: 'delivery-note',
- loadComponent: () => import('./pages/delivery-note/delivery-note').then(x => x.DeliveryNote)
- },
- {
- path: 'user',
- loadComponent: () => import('./pages/user/user').then(x => x.User)
+ path: '',
+ loadComponent: () =>
+ import('./components/layout/layout').then(m => m.Layout),
+ children: [
+ {
+ path: '',
+ pathMatch: 'full',
+ redirectTo: '/dashboard'
+ },
+ {
+ path: 'dashboard',
+ loadComponent: () => import('./pages/dashboard/dashboard').then(m => m.Dashboard),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'stock',
+ loadComponent: () => import('./pages/stock/stock').then(m => m.Stock),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'supplier',
+ loadComponent: () => import('./pages/supplier/supplier').then(m => m.Supplier),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'deliverer',
+ loadComponent: () => import('./pages/deliverer/deliverer').then(m => m.Deliverer),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'quotation',
+ loadComponent: () => import('./pages/quotation/quotation').then(m => m.Quotation),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'purchase-order',
+ loadComponent: () => import('./pages/purchase-order/purchase-order').then(m => m.PurchaseOrder),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'delivery-note',
+ loadComponent: () => import('./pages/delivery-note/delivery-note').then(m => m.DeliveryNote),
+ canActivate: [authGuard]
+ },
+ {
+ path: 'user',
+ loadComponent: () => import('./pages/user/user').then(m => m.User),
+ canActivate: [authGuard],
+ },
+ {
+ path: '**',
+ redirectTo: 'dashboard'
+ }
+ ]
}
];
diff --git a/src/app/app.ts b/src/app/app.ts
index fa98bea..8d3207b 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -1,14 +1,13 @@
-import { Component } from '@angular/core';
-import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
-import { NzLayoutModule } from 'ng-zorro-antd/layout';
-import { NzMenuModule } from 'ng-zorro-antd/menu';
-import {NzFlexDirective} from "ng-zorro-antd/flex";
-import {NzIconDirective} from "ng-zorro-antd/icon";
+import {Component} from '@angular/core';
+import {RouterOutlet} from '@angular/router';
+import {NzLayoutModule} from 'ng-zorro-antd/layout';
+import {NzMenuModule} from 'ng-zorro-antd/menu';
@Component({
- selector: 'app-root',
- imports: [RouterOutlet, NzLayoutModule, NzMenuModule, NzFlexDirective, NzIconDirective, RouterLinkActive, RouterLink],
- templateUrl: './app.html',
- styleUrl: './app.css'
+ selector: 'app-root',
+ imports: [RouterOutlet, NzLayoutModule, NzMenuModule],
+ templateUrl: './app.html',
+ styleUrl: './app.css'
})
-export class App {}
+export class App {
+}
diff --git a/src/app/pages/welcome/welcome.css b/src/app/components/add-product-supplier-form/add-product-supplier-form.css
similarity index 100%
rename from src/app/pages/welcome/welcome.css
rename to src/app/components/add-product-supplier-form/add-product-supplier-form.css
diff --git a/src/app/components/add-product-supplier-form/add-product-supplier-form.html b/src/app/components/add-product-supplier-form/add-product-supplier-form.html
new file mode 100644
index 0000000..606dc88
--- /dev/null
+++ b/src/app/components/add-product-supplier-form/add-product-supplier-form.html
@@ -0,0 +1,40 @@
+
diff --git a/src/app/components/add-product-supplier-form/add-product-supplier-form.ts b/src/app/components/add-product-supplier-form/add-product-supplier-form.ts
new file mode 100644
index 0000000..d031fe1
--- /dev/null
+++ b/src/app/components/add-product-supplier-form/add-product-supplier-form.ts
@@ -0,0 +1,54 @@
+import {Component, input} from '@angular/core';
+import {FormArray, FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {GetProductDto, GetSupplierDto} from "../../services/api";
+import {NzColDirective, NzRowDirective} from "ng-zorro-antd/grid";
+import {NzFormControlComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {NzInputNumberComponent} from "ng-zorro-antd/input-number";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+
+@Component({
+ selector: 'app-add-product-supplier-form',
+ imports: [
+ NzRowDirective,
+ NzFormControlComponent,
+ NzFormLabelComponent,
+ ReactiveFormsModule,
+ NzFlexDirective,
+ NzColDirective,
+ NzTableComponent,
+ NzInputNumberComponent,
+ NzOptionComponent,
+ NzSelectComponent
+ ],
+ templateUrl: './add-product-supplier-form.html',
+ styleUrl: './add-product-supplier-form.css',
+})
+export class AddProductSupplierForm {
+ addProductForm: FormGroup = new FormGroup({
+ supplierId: new FormControl(null, Validators.required),
+ lines: new FormArray([], Validators.required),
+ });
+
+ suppliers = input.required();
+ products = input.required();
+
+ get lines(): FormArray {
+ return this.addProductForm.get('lines') as FormArray;
+ }
+
+ addProductToForm() {
+ this.lines.clear();
+
+ this.products().forEach(x => {
+ this.lines.push(
+ new FormGroup({
+ productId: new FormControl(x.id),
+ name: new FormControl(x.name),
+ price: new FormControl(0, [Validators.required, Validators.min(0)])
+ })
+ );
+ });
+ }
+}
diff --git a/src/app/components/create-purchaseorder-form/create-purchaseorder-form.css b/src/app/components/create-purchaseorder-form/create-purchaseorder-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/create-purchaseorder-form/create-purchaseorder-form.html b/src/app/components/create-purchaseorder-form/create-purchaseorder-form.html
new file mode 100644
index 0000000..304b160
--- /dev/null
+++ b/src/app/components/create-purchaseorder-form/create-purchaseorder-form.html
@@ -0,0 +1,53 @@
+
diff --git a/src/app/components/create-purchaseorder-form/create-purchaseorder-form.ts b/src/app/components/create-purchaseorder-form/create-purchaseorder-form.ts
new file mode 100644
index 0000000..58c1b0a
--- /dev/null
+++ b/src/app/components/create-purchaseorder-form/create-purchaseorder-form.ts
@@ -0,0 +1,93 @@
+import {Component, input, OnInit, signal} from '@angular/core';
+import {FormBuilder, FormGroup, FormArray, Validators, ReactiveFormsModule, FormControl} from '@angular/forms';
+import {GetProductDto, GetSupplierDto} from '../../services/api';
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {NzInputNumberComponent} from "ng-zorro-antd/input-number";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {min} from "rxjs";
+
+@Component({
+ selector: 'app-create-purchaseorder-form',
+ templateUrl: './create-purchaseorder-form.html',
+ styleUrl: './create-purchaseorder-form.css',
+ imports: [
+ ReactiveFormsModule,
+ NzTableComponent,
+ NzInputNumberComponent,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ NzOptionComponent,
+ NzSelectComponent,
+ ]
+})
+export class CreatePurchaseorderForm {
+ suppliers = input.required();
+ products = input.required();
+
+ getBestSupplier() {
+ let bestSupplier: GetSupplierDto = this.suppliers()[0];
+ let maxProducts = 0;
+
+ const selectedProducts = this.products().map(x => x.id);
+
+ this.suppliers().forEach(x => {
+ const supplierProductsCount = x.prices.filter(p => selectedProducts.includes(p.productId)).length ?? 0;
+
+ if (supplierProductsCount > maxProducts) {
+ maxProducts = supplierProductsCount;
+ bestSupplier = x;
+ }
+ })
+ return bestSupplier;
+ }
+
+ getProductsOfSupplier() {
+ const supplier = this.suppliers().find(x => x.id === this.createPurchaseOrderForm.value.supplierId);
+ if (!supplier) return [];
+
+ const supplierProductIds = supplier.prices.map(x => x.productId);
+
+ return this.products().filter(product => supplierProductIds.includes(product.id));
+ }
+
+ createPurchaseOrderForm: FormGroup = new FormGroup({
+ purchaseConditions: new FormControl(null, Validators.required),
+ lines: new FormArray([], Validators.required),
+ supplierId: new FormControl(null, Validators.required),
+ })
+
+ get lines(): FormArray {
+ return this.createPurchaseOrderForm.get('lines') as FormArray;
+ }
+
+ addProductToForm() {
+ const supplierId = this.createPurchaseOrderForm.value.supplierId ?? this.getBestSupplier().id;
+ this.createPurchaseOrderForm.patchValue({
+ supplierId
+ });
+
+ this.refresh();
+ }
+
+ refresh() {
+ this.lines.clear();
+
+ this.getProductsOfSupplier().forEach(x => {
+ this.lines.push(
+ new FormGroup({
+ productId: new FormControl(x.id),
+ name: new FormControl(x.name),
+ quantity: new FormControl(1, [Validators.required, Validators.min(1)])
+ })
+ );
+ });
+ }
+}
diff --git a/src/app/components/create-quotation-form/create-quotation-form.css b/src/app/components/create-quotation-form/create-quotation-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/create-quotation-form/create-quotation-form.html b/src/app/components/create-quotation-form/create-quotation-form.html
new file mode 100644
index 0000000..a70a780
--- /dev/null
+++ b/src/app/components/create-quotation-form/create-quotation-form.html
@@ -0,0 +1,62 @@
+
diff --git a/src/app/components/create-quotation-form/create-quotation-form.ts b/src/app/components/create-quotation-form/create-quotation-form.ts
new file mode 100644
index 0000000..0069596
--- /dev/null
+++ b/src/app/components/create-quotation-form/create-quotation-form.ts
@@ -0,0 +1,105 @@
+import {Component, inject, input, OnInit, signal} from '@angular/core';
+import {
+ FormArray,
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ FormsModule,
+ ReactiveFormsModule,
+ Validators
+} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {NzInputNumberComponent} from "ng-zorro-antd/input-number";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {CustomersService, GetCustomerDto, GetProductDto, GetSupplierDto} from "../../services/api";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {firstValueFrom} from "rxjs";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+
+@Component({
+ selector: 'app-create-quotation-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ NzInputNumberComponent,
+ NzTableComponent,
+ ReactiveFormsModule,
+ NzOptionComponent,
+ NzSelectComponent
+ ],
+ templateUrl: './create-quotation-form.html',
+ styleUrl: './create-quotation-form.css',
+})
+export class CreateQuotationForm implements OnInit {
+ private customersService = inject(CustomersService);
+ private notificationService = inject(NzNotificationService);
+
+ suppliers = input.required();
+ products = input.required();
+
+ customers = signal([]);
+
+ async ngOnInit() {
+ try {
+ const customers = await firstValueFrom(this.customersService.getAllCustomersEndpoint())
+ this.customers.set(customers);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur de communication avec l\'API')
+ }
+ }
+
+ createQuotationForm: FormGroup = new FormGroup({
+ message: new FormControl(null, Validators.required),
+ conditionsSale: new FormControl(null, Validators.required),
+ supplierId: new FormControl(null, Validators.required),
+ customerId: new FormControl(null, Validators.required),
+ lines: new FormArray([], Validators.required),
+ })
+
+ get lines(): FormArray {
+ return this.createQuotationForm.get('lines') as FormArray;
+ }
+
+ getDefaultSupplier() {
+ let defaultSupplier: GetSupplierDto = this.suppliers()[0];
+ let maxProducts = 0;
+
+ const selectedProducts = this.products().map(x => x.id);
+
+ this.suppliers().forEach(x => {
+ const supplierProductsCount = x.prices.filter(p => selectedProducts.includes(p.productId)).length ?? 0;
+
+ if (supplierProductsCount > maxProducts) {
+ maxProducts = supplierProductsCount;
+ defaultSupplier = x;
+ }
+ })
+
+ return defaultSupplier;
+ }
+
+ addProductToForm() {
+ this.lines.clear();
+ this.products().forEach(x => {
+ this.lines.push(
+ new FormGroup({
+ productId: new FormControl(x.id),
+ name: new FormControl(x.name),
+ quantity: new FormControl(1, [Validators.required, Validators.min(1)])
+ })
+ );
+ });
+
+ this.createQuotationForm.patchValue({
+ supplierId: this.getDefaultSupplier().id,
+ });
+ }
+}
diff --git a/src/app/components/deliverer-choice/deliverer-choice.css b/src/app/components/deliverer-choice/deliverer-choice.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/deliverer-choice/deliverer-choice.html b/src/app/components/deliverer-choice/deliverer-choice.html
new file mode 100644
index 0000000..296243f
--- /dev/null
+++ b/src/app/components/deliverer-choice/deliverer-choice.html
@@ -0,0 +1,15 @@
+
diff --git a/src/app/components/deliverer-choice/deliverer-choice.ts b/src/app/components/deliverer-choice/deliverer-choice.ts
new file mode 100644
index 0000000..aeffa1f
--- /dev/null
+++ b/src/app/components/deliverer-choice/deliverer-choice.ts
@@ -0,0 +1,45 @@
+import {Component, inject, OnInit, signal} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzColDirective, NzRowDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {DeliverersService, GetDelivererDto} from "../../services/api";
+import {firstValueFrom} from "rxjs";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+
+@Component({
+ selector: 'app-deliverer-choice',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormLabelComponent,
+ NzOptionComponent,
+ NzRowDirective,
+ NzSelectComponent,
+ ReactiveFormsModule
+ ],
+ templateUrl: './deliverer-choice.html',
+ styleUrl: './deliverer-choice.css',
+})
+export class DelivererChoice implements OnInit {
+ private deliverersService = inject(DeliverersService);
+ private notificationService = inject(NzNotificationService);
+
+ choiceDelivererForm: FormGroup = new FormGroup({
+ delivererId: new FormControl(null, Validators.required),
+ });
+
+ deliverers = signal([]);
+
+ async ngOnInit() {
+ try {
+ const deliverers = await firstValueFrom(this.deliverersService.getAllDelivererEndpoint());
+ this.deliverers.set(deliverers);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de l\'affichage des livreurs');
+ }
+ }
+}
diff --git a/src/app/components/deliverer-form/deliverer-form.css b/src/app/components/deliverer-form/deliverer-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/deliverer-form/deliverer-form.html b/src/app/components/deliverer-form/deliverer-form.html
new file mode 100644
index 0000000..51b292b
--- /dev/null
+++ b/src/app/components/deliverer-form/deliverer-form.html
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/src/app/components/deliverer-form/deliverer-form.ts b/src/app/components/deliverer-form/deliverer-form.ts
new file mode 100644
index 0000000..0244a7a
--- /dev/null
+++ b/src/app/components/deliverer-form/deliverer-form.ts
@@ -0,0 +1,40 @@
+import {Component, effect, input} from '@angular/core';
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {GetDelivererDto} from "../../services/api";
+
+@Component({
+ selector: 'app-deliverer-form',
+ imports: [
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './deliverer-form.html',
+ styleUrl: './deliverer-form.css',
+})
+export class DelivererForm {
+ delivererForm: FormGroup = new FormGroup({
+ transporter: new FormControl(null, [Validators.required])
+ })
+
+ deliverer = input();
+
+ constructor() {
+ effect(() => {
+ if (this.deliverer()) {
+ this.delivererForm.patchValue({
+ transporter: this.deliverer().transporter
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/deliverer-table/deliverer-table.css b/src/app/components/deliverer-table/deliverer-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/deliverer-table/deliverer-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/deliverer-table/deliverer-table.html b/src/app/components/deliverer-table/deliverer-table.html
new file mode 100644
index 0000000..1ff9409
--- /dev/null
+++ b/src/app/components/deliverer-table/deliverer-table.html
@@ -0,0 +1,63 @@
+
+
+
+ | Transporteur |
+ Bon de livraison |
+ Action |
+
+
+
+ @for (deliverer of deliverers(); track deliverer.id) {
+
+ | {{ deliverer.transporter }} |
+
+
+
+
+
+
+ | Numéro de livraison |
+ Date d'expédition |
+ Date de livraison estimée |
+ Date de livraison réelle |
+
+
+
+ @for (deliveryInfo of deliverer.deliveryNotes; track deliveryInfo.id) {
+
+ | {{ deliveryInfo.trackingNumber }} |
+ {{ deliveryInfo.expeditionDate | date: 'dd/MM/yyyy' }} |
+ {{ deliveryInfo.estimateDeliveryDate | date: 'dd/MM/yyyy' }} |
+ {{ deliveryInfo.realDeliveryDate | date: 'dd/MM/yyyy' }} |
+
+ }
+
+
+
+
+ |
+
+
+
+ @if (admin()){
+
+
+ }
+
+ |
+
+ }
+
+
+
+
diff --git a/src/app/components/deliverer-table/deliverer-table.ts b/src/app/components/deliverer-table/deliverer-table.ts
new file mode 100644
index 0000000..53bb557
--- /dev/null
+++ b/src/app/components/deliverer-table/deliverer-table.ts
@@ -0,0 +1,105 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {ModalButton} from "../modal-button/modal-button";
+import {DatePipe} from "@angular/common";
+import {DelivererForm} from "../deliverer-form/deliverer-form";
+import {DeliverersService, GetDelivererDto, GetSupplierDto} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-deliverer-table',
+ imports: [
+ ModalNav,
+ NzDividerComponent,
+ NzIconDirective,
+ NzTableComponent,
+ ModalButton,
+ DatePipe,
+ DelivererForm,
+ ],
+ templateUrl: './deliverer-table.html',
+ styleUrl: './deliverer-table.css',
+})
+
+export class DelivererTable implements OnInit {
+ private deliverersService = inject(DeliverersService);
+ private notificationService = inject(NzNotificationService)
+ private authService = inject(AuthService);
+
+ deliverers = signal([]);
+ deliverersLoading = signal(false);
+ admin = signal(false);
+
+ modal = viewChild.required('modalNav');
+
+ async ngOnInit() {
+ await this.fetchDeliverers();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchDeliverers() {
+ this.deliverersLoading.set(true)
+
+ try {
+ const deliverers = await firstValueFrom(this.deliverersService.getAllDelivererEndpoint())
+ this.deliverers.set(deliverers);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des transporteurs');
+ }
+ this.deliverersLoading.set(false)
+ }
+
+ async delete(deliverer: number) {
+ try {
+ await firstValueFrom(this.deliverersService.deleteDelivererEndpoint(deliverer))
+ this.notificationService.success('Success', 'Suppression effectuée');
+ } catch {
+ this.notificationService.error(
+ 'Erreur',
+ 'Impossible de supprimer la ligne'
+ )
+ }
+ await this.fetchDeliverers();
+ }
+
+ async edit(id: number, updateDelivererComponent: DelivererForm) {
+ if (updateDelivererComponent.delivererForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ try {
+ const deliverers = updateDelivererComponent.delivererForm.getRawValue();
+ await firstValueFrom(this.deliverersService.updateDelivererEndpoint(id, deliverers))
+
+ this.notificationService.success('Success', 'Transporteur modifié')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification')
+ }
+ }
+
+ selectedDeliverer: GetDelivererDto | null = null;
+
+ openEditModal(supplier: GetSupplierDto) {
+ this.selectedDeliverer = {...supplier};
+ this.modal().showModal();
+ }
+
+ async onModalOk(supplierId: number, updateDelivererComponent: DelivererForm, modal: ModalNav) {
+ if (!this.selectedDeliverer) return;
+
+ await this.edit(supplierId, updateDelivererComponent);
+ updateDelivererComponent.delivererForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchDeliverers();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+}
diff --git a/src/app/components/deliverery-note-form/deliverery-note-form.css b/src/app/components/deliverery-note-form/deliverery-note-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/deliverery-note-form/deliverery-note-form.html b/src/app/components/deliverery-note-form/deliverery-note-form.html
new file mode 100644
index 0000000..a5000b4
--- /dev/null
+++ b/src/app/components/deliverery-note-form/deliverery-note-form.html
@@ -0,0 +1,45 @@
+
\ No newline at end of file
diff --git a/src/app/components/deliverery-note-form/deliverery-note-form.ts b/src/app/components/deliverery-note-form/deliverery-note-form.ts
new file mode 100644
index 0000000..e0a063c
--- /dev/null
+++ b/src/app/components/deliverery-note-form/deliverery-note-form.ts
@@ -0,0 +1,72 @@
+import {Component, effect, inject, input, OnInit, signal} from '@angular/core';
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzDatePickerComponent} from "ng-zorro-antd/date-picker";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {DeliverersService, GetDelivererDto, GetDeliveryNoteDto} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+
+@Component({
+ selector: 'app-deliverery-note-form',
+ imports: [
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzFormControlComponent,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormDirective,
+ ReactiveFormsModule,
+ NzDatePickerComponent,
+ NzSelectComponent,
+ NzOptionComponent,
+ ],
+ templateUrl: './deliverery-note-form.html',
+ styleUrl: './deliverery-note-form.css',
+})
+export class DelivereryNoteForm implements OnInit {
+ deliveryNoteForm: FormGroup = new FormGroup({
+ trackingNumber: new FormControl(null),
+ delivererId: new FormControl(null, [Validators.required]),
+ expeditionDate: new FormControl(null, [Validators.required]),
+ estimatedDate: new FormControl(null, [Validators.required]),
+ realDeliveryDate: new FormControl(null)
+ })
+
+ private deliverersService = inject(DeliverersService);
+ private notificationService = inject(NzNotificationService);
+
+ deliverers = signal([]);
+
+ deliveryNote = input();
+
+ async fetchDeliverers() {
+ try {
+ const deliverers = await firstValueFrom(this.deliverersService.getAllDelivererEndpoint());
+ this.deliverers.set(deliverers);
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de récupérer les transporteurs');
+ }
+ }
+
+ async ngOnInit() {
+ await this.fetchDeliverers();
+ }
+
+ constructor() {
+ effect(() => {
+ if (this.deliveryNote()) {
+ this.deliveryNoteForm.patchValue({
+ trackingNumber: this.deliveryNote().trackingNumber,
+ expeditionDate: this.deliveryNote().expeditionDate,
+ realDeliveryDate: this.deliveryNote().realDeliveryDate,
+ estimatedDate: this.deliveryNote().estimateDeliveryDate,
+ delivererId: this.deliveryNote().delivererId
+ });
+ }
+ });
+ }
+
+}
diff --git a/src/app/components/deliverery-note-table/deliverery-note-table.css b/src/app/components/deliverery-note-table/deliverery-note-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/deliverery-note-table/deliverery-note-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/deliverery-note-table/deliverery-note-table.html b/src/app/components/deliverery-note-table/deliverery-note-table.html
new file mode 100644
index 0000000..c7b0c4f
--- /dev/null
+++ b/src/app/components/deliverery-note-table/deliverery-note-table.html
@@ -0,0 +1,61 @@
+
+
+
+ | Numéro de livraison |
+ Transporteur |
+ Date d'expédition |
+ Date de livraison estimée |
+ Date de livraison réelle |
+ Statut |
+ Action |
+
+
+
+ @for (deliveryNote of deliveryNotes(); track deliveryNote.id) {
+
+ | {{ deliveryNote.trackingNumber }} |
+ {{ deliveryNote.delivererTransporter }} |
+ {{ deliveryNote.expeditionDate | date: 'dd/MM/yyyy' }} |
+ {{ deliveryNote.estimateDeliveryDate | date: 'dd/MM/yyyy' }} |
+ {{ deliveryNote.realDeliveryDate | date: 'dd/MM/yyyy' }} |
+
+ @if (deliveryNote.estimateDeliveryDate >= date && deliveryNote.realDeliveryDate == null) {
+ En cours
+ } @else if (deliveryNote.realDeliveryDate == null) {
+ En retard
+ } @else {
+ Terminée
+ }
+ |
+
+
+
+
+
+
+ @if (admin()){
+
+
+ }
+
+
+ |
+
+ }
+
+
+
+
diff --git a/src/app/components/deliverery-note-table/deliverery-note-table.ts b/src/app/components/deliverery-note-table/deliverery-note-table.ts
new file mode 100644
index 0000000..1b31870
--- /dev/null
+++ b/src/app/components/deliverery-note-table/deliverery-note-table.ts
@@ -0,0 +1,147 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {DatePipe} from "@angular/common";
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {DelivereryNoteForm} from "../deliverery-note-form/deliverery-note-form";
+import {DeliverynotesService, GetDeliveryNoteDto, UpdateDeliveryNoteDto} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {format} from "date-fns";
+import {FileService} from "../../services/file.service";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-deliverery-note-table',
+ imports: [
+ ModalNav,
+ NzDividerComponent,
+ NzIconDirective,
+ NzTableComponent,
+ DelivereryNoteForm,
+ DatePipe,
+ ],
+ templateUrl: './deliverery-note-table.html',
+ styleUrl: './deliverery-note-table.css',
+})
+export class DelivereryNoteTable implements OnInit {
+ private deliveryNotesService = inject(DeliverynotesService);
+ private notificationService = inject(NzNotificationService);
+ private fileService = inject(FileService);
+ private authService = inject(AuthService);
+
+ deliveryNotes = signal([]);
+ deliveryNotesLoading = signal(false);
+ admin = signal(false);
+
+ modal = viewChild.required('modalNav');
+
+ date = new Date().toISOString().split('T')[0]; // yyyy-mm-dd
+
+ async ngOnInit() {
+ await this.fetchDeliveryNotes();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchDeliveryNotes() {
+ this.deliveryNotesLoading.set(true)
+ try {
+ const deliveryNotes = await firstValueFrom(this.deliveryNotesService.getAllDeliveryNoteEndpoint());
+ this.deliveryNotes.set(deliveryNotes);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des bons de livraison');
+ }
+ this.deliveryNotesLoading.set(false)
+ }
+
+ async delete(deliveryNote: number) {
+ this.deliveryNotesLoading.set(true)
+ try {
+ await firstValueFrom(this.deliveryNotesService.deleteDeliveryNoteEndpoint(deliveryNote));
+ this.notificationService.success('Success', 'Suppression effectuée');
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne');
+ }
+ this.deliveryNotesLoading.set(false)
+ await this.fetchDeliveryNotes();
+ }
+
+ async validate(deliveryNote: number) {
+ this.deliveryNotesLoading.set(true)
+ try {
+ const PatchRealDate = {
+ realDeliveryDate: format(new Date(), 'yyyy-MM-dd')
+ };
+
+ try {
+ await firstValueFrom(this.deliveryNotesService.patchRealDeliveryDateEndpoint(deliveryNote, PatchRealDate))
+ this.notificationService.success('Success', 'Date actualisée');
+ } catch {
+ this.notificationService.error('Erreur', 'La date à déjà été actualisée');
+ }
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur d\'actualisation de la date');
+ }
+ this.deliveryNotesLoading.set(false)
+ await this.fetchDeliveryNotes()
+ }
+
+ async export(deliveryNoteId: number) {
+ this.deliveryNotesLoading.set(true)
+ try {
+ const pdf = await firstValueFrom(this.deliveryNotesService.getDeliveryNotePdfEndpoint(deliveryNoteId, "response"));
+ this.fileService.downloadBlob(pdf)
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de générer un PDF');
+ }
+ this.deliveryNotesLoading.set(false)
+ }
+
+ async edit(id: number, updateDelivereryNoteComponent: DelivereryNoteForm) {
+ if (updateDelivereryNoteComponent.deliveryNoteForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ try {
+ const raw = updateDelivereryNoteComponent.deliveryNoteForm.getRawValue();
+
+ const toIso = (val: any) =>
+ val ? new Date(val).toISOString().substring(0, 10) : null;
+
+ const deliveryNoteDto: UpdateDeliveryNoteDto = {
+ trackingNumber: raw.trackingNumber,
+ delivererId: raw.delivererId,
+ expeditionDate: toIso(raw.expeditionDate),
+ estimateDeliveryDate: toIso(raw.estimatedDate),
+ realDeliveryDate: toIso(raw.realDeliveryDate)
+ };
+
+ await firstValueFrom(this.deliveryNotesService.updateDeliveryNoteEndpoint(id, deliveryNoteDto));
+ this.notificationService.success('Success', 'Bon de livraison modifié');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification');
+ }
+ }
+
+ selectedDeliveryNote: GetDeliveryNoteDto | null = null;
+
+ openEditModal(deliveryNote: GetDeliveryNoteDto) {
+ this.selectedDeliveryNote = {...deliveryNote};
+ this.modal().showModal();
+ }
+
+ async onModalOk(id: number, updateDelivereryNoteComponent: DelivereryNoteForm, modal: ModalNav) {
+ if (!this.selectedDeliveryNote) return;
+
+ await this.edit(id, updateDelivereryNoteComponent);
+ updateDelivereryNoteComponent.deliveryNoteForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchDeliveryNotes();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+}
diff --git a/src/app/components/delivery-validator/delivery-validator.css b/src/app/components/delivery-validator/delivery-validator.css
new file mode 100644
index 0000000..919cf1c
--- /dev/null
+++ b/src/app/components/delivery-validator/delivery-validator.css
@@ -0,0 +1,85 @@
+/* Conteneur principal centré */
+.livraisons-container {
+ max-width: 650px;
+ margin: 40px 0 0 80px;
+ padding: 25px;
+ background: #f9fafb;
+ border-radius: 16px;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.06),
+ 0 8px 20px rgba(0, 0, 0, 0.08),
+ 0 16px 40px rgba(0, 0, 0, 0.06);
+}
+
+
+/* Barre de recherche */
+.search-input {
+ width: 100%;
+ padding: 14px 18px;
+ border-radius: 12px;
+ border: 1px solid #ddd;
+ margin-bottom: 20px;
+ font-size: 16px;
+ transition: all 0.3s ease;
+}
+
+.search-input:focus {
+ border-color: #3b82f6;
+ box-shadow: 0 0 8px rgba(59, 130, 246, 0.2);
+ outline: none;
+}
+
+.livraisons-list {
+ width: 100%;
+ max-height: 500px;
+ overflow-y: auto;
+ padding-right: 10px;
+}
+
+.livraisons-list::-webkit-scrollbar {
+ width: 8px;
+}
+
+.livraisons-list::-webkit-scrollbar-thumb {
+ background: #9ca3af;
+ border-radius: 4px;
+}
+
+.livraisons-list::-webkit-scrollbar-track {
+ background: #f3f4f6;
+}
+
+.livraison-card {
+ background: #ffffff;
+ padding: 20px 22px;
+ border-radius: 14px;
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.05);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ margin-bottom: 18px;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.livraison-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 10px 22px rgba(0, 0, 0, 0.08);
+}
+
+.livraison-info h3 {
+ font-size: 17px;
+ margin: 0 0 4px;
+ color: #111827;
+}
+
+.livraison-info p {
+ margin: 0;
+ font-size: 14px;
+ color: #6b7280;
+}
diff --git a/src/app/components/delivery-validator/delivery-validator.html b/src/app/components/delivery-validator/delivery-validator.html
new file mode 100644
index 0000000..fe7be05
--- /dev/null
+++ b/src/app/components/delivery-validator/delivery-validator.html
@@ -0,0 +1,58 @@
+
+
+
+
+ @for (deliveryItem of filteredDeliveries(); track deliveryItem.id) {
+
+
+
{{ deliveryItem.delivererTransporter }}
+
Date d'expédition: {{ deliveryItem.expeditionDate }}
+
Quantité livrée : {{ deliveryItem.products.length }}
+
+
+
+
+
+
+
+ @for (wareHouse of wareHouses(); track wareHouse.id) {
+
+ }
+
+
+
+
+
+
+
+
+ | Réference |
+ Nom |
+ Quantité |
+
+
+
+ @for (product of deliveryItem.products; track product.productId) {
+
+ | {{ product.productReference }} |
+ {{ product.productName }} |
+ {{ product.quantity }} |
+
+ }
+
+
+
+
+
+ }
+
+
diff --git a/src/app/components/delivery-validator/delivery-validator.ts b/src/app/components/delivery-validator/delivery-validator.ts
new file mode 100644
index 0000000..c5c6f9d
--- /dev/null
+++ b/src/app/components/delivery-validator/delivery-validator.ts
@@ -0,0 +1,105 @@
+import {Component, computed, inject, OnInit, signal} from '@angular/core';
+import {
+ DeliverynotesService,
+ GetDeliveryNoteDto, GetWareHouseDto,
+ WarehouseproductsService,
+ WarehousesService
+} from "../../services/api";
+import {firstValueFrom} from "rxjs";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {format} from "date-fns";
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {FormsModule} from "@angular/forms";
+
+@Component({
+ selector: 'app-delivery-validator',
+ imports: [
+ NzTableComponent,
+ ModalNav,
+ NzSelectComponent,
+ NzOptionComponent,
+ FormsModule
+ ],
+ templateUrl: './delivery-validator.html',
+ styleUrl: './delivery-validator.css',
+})
+export class DeliveryValidator implements OnInit {
+ private deliveryNotesService = inject(DeliverynotesService);
+ private notificationService = inject(NzNotificationService);
+ private warehousesService = inject(WarehousesService);
+ private warehouseProductsService = inject(WarehouseproductsService);
+
+ search = signal('');
+ deliveryNotes = signal([]);
+ wareHouses = signal([]);
+
+ selectedWarehouseId: number | null = null;
+
+ async ngOnInit() {
+ await this.fetchDeliveryNotes();
+ try {
+ const wareHouses = await firstValueFrom(this.warehousesService.getAllWarehouseEndpoint());
+ this.wareHouses.set(wareHouses);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des quantitées')
+ }
+ }
+
+ async fetchDeliveryNotes() {
+ try {
+ const deliveries = await firstValueFrom(this.deliveryNotesService.getAllDeliveryNotesNotArrivedEndpoint());
+ this.deliveryNotes.set(deliveries);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des bon de livraison')
+ }
+ }
+
+ filteredDeliveries = computed(() => {
+ const query = this.search().toLowerCase();
+ return this.deliveryNotes().filter(l =>
+ l.delivererTransporter.toLowerCase().includes(query) ||
+ l.expeditionDate.includes(query)
+ );
+ });
+
+ async check(id: number) {
+ try {
+ const PatchRealDate = {
+ realDeliveryDate: format(new Date(), 'yyyy-MM-dd')
+ };
+ await firstValueFrom(this.deliveryNotesService.patchRealDeliveryDateEndpoint(id, PatchRealDate));
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible d\'actualiser la date')
+ }
+ }
+
+ async validate(id: number, warehouseId: number, modal: ModalNav) {
+ try {
+ const deliveryNote = this.deliveryNotes().find(x => x.id === id);
+
+ for (const product of deliveryNote.products) {
+ await firstValueFrom(this.warehouseProductsService.patchWareHouseProductQuantityEndpoint(
+ product.productId,
+ warehouseId,
+ {
+ quantity: product.quantity
+ }
+ ));
+ }
+
+ this.notificationService.success('Succès', 'Les produits sont bien ajoutés au stock')
+
+ modal.isVisible = false;
+ await this.fetchDeliveryNotes();
+ } catch {
+ this.notificationService.error('Erreur', 'Vous devez choisir un entrepôt')
+ }
+ }
+
+ async reject(modal: ModalNav) {
+ modal.isVisible = false;
+ await this.fetchDeliveryNotes();
+ }
+}
diff --git a/src/app/components/info-card/info-card.css b/src/app/components/info-card/info-card.css
new file mode 100644
index 0000000..278411c
--- /dev/null
+++ b/src/app/components/info-card/info-card.css
@@ -0,0 +1,42 @@
+.card-content {
+ background: #ffffff;
+ padding: 32px 36px;
+ border-radius: 20px;
+ box-shadow: 0 10px 22px rgba(0, 0, 0, 0.12);
+ width: 350px;
+ min-height: 180px;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.card-content:hover {
+ transform: translateY(-6px);
+ box-shadow: 0 14px 26px rgba(0, 0, 0, 0.16);
+}
+
+/* Ligne du haut : icône ET nombre */
+.card-top {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+}
+
+/* Icône à gauche (plus grande) */
+.card-top nz-icon {
+ font-size: 50px;
+}
+
+/* Nombre à droite de l'icône (plus grand) */
+.card-number {
+ font-size: 48px;
+ font-weight: 700;
+ margin: 0;
+ color: #111827;
+}
+
+/* Texte en dessous (plus lisible) */
+.card-text {
+ margin-top: 18px;
+ font-size: 18px;
+ line-height: 1.4;
+ color: #4b5563;
+}
diff --git a/src/app/components/info-card/info-card.html b/src/app/components/info-card/info-card.html
new file mode 100644
index 0000000..33895c3
--- /dev/null
+++ b/src/app/components/info-card/info-card.html
@@ -0,0 +1,7 @@
+
+
+
{{ description() }}
+
\ No newline at end of file
diff --git a/src/app/components/info-card/info-card.ts b/src/app/components/info-card/info-card.ts
new file mode 100644
index 0000000..15b1c20
--- /dev/null
+++ b/src/app/components/info-card/info-card.ts
@@ -0,0 +1,19 @@
+import {Component, input} from '@angular/core';
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NgStyle} from "@angular/common";
+
+@Component({
+ selector: 'app-info-card',
+ imports: [
+ NzIconDirective,
+ NgStyle
+ ],
+ templateUrl: './info-card.html',
+ styleUrl: './info-card.css',
+})
+export class InfoCard {
+ icon = input.required()
+ value = input.required()
+ description = input.required()
+ color = input.required()
+}
diff --git a/src/app/components/layout/layout.css b/src/app/components/layout/layout.css
new file mode 100644
index 0000000..51e4597
--- /dev/null
+++ b/src/app/components/layout/layout.css
@@ -0,0 +1,122 @@
+:host {
+ display: flex;
+}
+
+.app-layout {
+ height: 100vh;
+}
+
+nz-header {
+ display: flex;
+ align-items: center;
+ background: #001529;
+ padding: 0 24px;
+}
+
+.header-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+}
+
+/* --- LOGO + TITRE --- */
+.logo {
+ display: flex;
+ align-items: center;
+}
+
+.logo a {
+ display: flex;
+ align-items: center;
+ text-decoration: none;
+}
+
+.logo img {
+ height: 40px;
+ width: auto;
+}
+
+.logo h1 {
+ margin: 0 0 0 10px;
+ color: #fff;
+ font-weight: 600;
+ font-size: 20px;
+ font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
+}
+
+/* --- MENU PRINCIPAL --- */
+.top-nav {
+ flex: 1;
+ margin: 0 40px;
+ line-height: 64px;
+ background: #001529;
+ border: none;
+}
+
+/* Couleur grise par défaut + effet blanc et zoom au survol */
+.top-nav li {
+ transition: transform 0.2s ease, color 0.2s ease;
+}
+
+.top-nav li a {
+ color: #bfbfbf !important; /* gris clair par défaut */
+ transition: transform 0.2s ease, color 0.2s ease;
+}
+
+/* Au survol → zoom + blanc pur */
+.top-nav li:hover {
+ transform: scale(1.08);
+ background: transparent !important;
+ color: #fff !important;
+}
+
+.top-nav li:hover a {
+ color: #ffffff !important;
+}
+
+/* Supprime toute coloration bleue ou fond par défaut NG-ZORRO */
+.top-nav li.ant-menu-item-active,
+.top-nav li.ant-menu-item-selected {
+ background: transparent !important;
+ color: #fff !important;
+}
+
+/* --- ICONES DROITES --- */
+.right-icons {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ color: #fff;
+ font-size: 18px;
+ cursor: pointer;
+}
+
+.right-icons app-modal-nav {
+ transition: transform 0.2s ease, color 0.2s ease;
+}
+
+.disconnect {
+ transition: transform 0.2s ease, color 0.2s ease;
+}
+
+.disconnect:hover {
+ color: #40a9ff;
+ transform: scale(1.2);
+}
+
+.right-icons app-modal-nav:hover {
+ color: #40a9ff;
+ transform: scale(1.2);
+}
+
+/* --- CONTENU --- */
+nz-content {
+ padding: 24px 50px;
+}
+
+.inner-content {
+ padding: 24px;
+ background: #fff;
+ height: 100%;
+}
diff --git a/src/app/components/layout/layout.html b/src/app/components/layout/layout.html
new file mode 100644
index 0000000..269cc2c
--- /dev/null
+++ b/src/app/components/layout/layout.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/components/layout/layout.ts b/src/app/components/layout/layout.ts
new file mode 100644
index 0000000..1a4286e
--- /dev/null
+++ b/src/app/components/layout/layout.ts
@@ -0,0 +1,45 @@
+import {Component, inject, OnInit, signal} from '@angular/core';
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzContentComponent, NzHeaderComponent, NzLayoutComponent} from "ng-zorro-antd/layout";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzMenuDirective, NzMenuItemComponent, NzSubMenuComponent} from "ng-zorro-antd/menu";
+import {Profil} from "../profil/profil";
+import {Router, RouterLink, RouterLinkActive, RouterOutlet} from "@angular/router";
+import {SettingForm} from "../setting-form/setting-form";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-layout',
+ imports: [
+ ModalNav,
+ NzContentComponent,
+ NzHeaderComponent,
+ NzIconDirective,
+ NzLayoutComponent,
+ NzMenuDirective,
+ NzMenuItemComponent,
+ NzSubMenuComponent,
+ Profil,
+ RouterLink,
+ RouterLinkActive,
+ RouterOutlet,
+ SettingForm
+ ],
+ templateUrl: './layout.html',
+ styleUrl: './layout.css',
+})
+export class Layout implements OnInit {
+ private authService = inject(AuthService);
+ private router = inject(Router);
+
+ admin = signal(false);
+
+ ngOnInit() {
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async disconnect() {
+ this.authService.logout();
+ await this.router.navigate(['/login']);
+ }
+}
diff --git a/src/app/components/modal-button/modal-button.css b/src/app/components/modal-button/modal-button.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/modal-button/modal-button.html b/src/app/components/modal-button/modal-button.html
new file mode 100644
index 0000000..e282f64
--- /dev/null
+++ b/src/app/components/modal-button/modal-button.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/app/components/modal-button/modal-button.ts b/src/app/components/modal-button/modal-button.ts
new file mode 100644
index 0000000..55d17d5
--- /dev/null
+++ b/src/app/components/modal-button/modal-button.ts
@@ -0,0 +1,43 @@
+import {Component, input, output} from '@angular/core';
+import {NzModalComponent} from "ng-zorro-antd/modal";
+import {NzButtonComponent} from "ng-zorro-antd/button";
+
+@Component({
+ selector: 'app-modal-button',
+ imports: [
+ NzModalComponent,
+ NzButtonComponent,
+ ],
+ templateUrl: './modal-button.html',
+ styleUrl: './modal-button.css',
+})
+
+export class ModalButton {
+ size = input();
+ name = input.required()
+ type = input<"primary" | "default" | "dashed" | "link" | "text">()
+
+ ok = output();
+ cancel = output();
+
+ isVisible = false;
+ isOkLoading = false;
+
+ showModal(): void {
+ this.isVisible = true;
+ }
+
+ handleOk(): void {
+ this.isOkLoading = true;
+ setTimeout(() => {
+ this.ok.emit();
+ this.isVisible = false;
+ this.isOkLoading = false;
+ }, 1000);
+ }
+
+ handleCancel(): void {
+ this.cancel.emit();
+ this.isVisible = false;
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/modal-nav/modal-nav.css b/src/app/components/modal-nav/modal-nav.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/modal-nav/modal-nav.html b/src/app/components/modal-nav/modal-nav.html
new file mode 100644
index 0000000..1401a39
--- /dev/null
+++ b/src/app/components/modal-nav/modal-nav.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/components/modal-nav/modal-nav.ts b/src/app/components/modal-nav/modal-nav.ts
new file mode 100644
index 0000000..f103ca3
--- /dev/null
+++ b/src/app/components/modal-nav/modal-nav.ts
@@ -0,0 +1,37 @@
+import {Component, input, output} from '@angular/core';
+import {NzButtonModule} from 'ng-zorro-antd/button';
+import {NzModalModule} from 'ng-zorro-antd/modal';
+import {NzIconDirective} from "ng-zorro-antd/icon";
+
+@Component({
+ selector: 'app-modal-nav',
+ imports: [NzButtonModule, NzModalModule, NzIconDirective],
+ templateUrl: 'modal-nav.html',
+ styleUrls: ['./modal-nav.css'],
+})
+export class ModalNav {
+ nameIcon = input.required()
+ name = input.required()
+ ok = output();
+ cancel = output();
+ isVisible = false;
+ isOkLoading = false;
+
+ showModal(): void {
+ this.isVisible = true;
+ }
+
+ handleOk(): void {
+ this.isOkLoading = true;
+ setTimeout(() => {
+ this.ok.emit();
+ this.isOkLoading = false;
+ }, 1000);
+ }
+
+ handleCancel(): void {
+ this.isVisible = false;
+ this.cancel.emit();
+
+ }
+}
diff --git a/src/app/components/price-form/price-form.css b/src/app/components/price-form/price-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/price-form/price-form.html b/src/app/components/price-form/price-form.html
new file mode 100644
index 0000000..fb025a8
--- /dev/null
+++ b/src/app/components/price-form/price-form.html
@@ -0,0 +1,13 @@
+
+
+
diff --git a/src/app/components/price-form/price-form.ts b/src/app/components/price-form/price-form.ts
new file mode 100644
index 0000000..6594d44
--- /dev/null
+++ b/src/app/components/price-form/price-form.ts
@@ -0,0 +1,41 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {GetPriceDto} from "../../services/api";
+
+@Component({
+ selector: 'app-price-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './price-form.html',
+ styleUrl: './price-form.css',
+})
+export class PriceForm {
+ priceForm: FormGroup = new FormGroup({
+ price: new FormControl(null, [Validators.required]),
+ })
+
+ price = input();
+
+ constructor() {
+ effect(() => {
+ if (this.price()) {
+ this.priceForm.patchValue({
+ price: this.price().sellingPrice
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/profil-form/profil-form.css b/src/app/components/profil-form/profil-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/profil-form/profil-form.html b/src/app/components/profil-form/profil-form.html
new file mode 100644
index 0000000..cb4ae5f
--- /dev/null
+++ b/src/app/components/profil-form/profil-form.html
@@ -0,0 +1,43 @@
+
\ No newline at end of file
diff --git a/src/app/components/profil-form/profil-form.ts b/src/app/components/profil-form/profil-form.ts
new file mode 100644
index 0000000..231d875
--- /dev/null
+++ b/src/app/components/profil-form/profil-form.ts
@@ -0,0 +1,50 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {NzOptionComponent, NzSelectComponent} from "ng-zorro-antd/select";
+import {GetUserDto} from "../../services/api";
+
+@Component({
+ selector: 'app-profil-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule,
+ NzSelectComponent,
+ NzOptionComponent
+ ],
+ templateUrl: './profil-form.html',
+ styleUrl: './profil-form.css',
+})
+export class ProfilForm {
+ profilForm: FormGroup = new FormGroup({
+ name: new FormControl(null, [Validators.required]),
+ email: new FormControl(null, [Validators.required]),
+ fonction: new FormControl(null, [Validators.required]),
+ password: new FormControl(null, [Validators.required])
+ })
+
+ user = input();
+
+ constructor() {
+ effect(() => {
+ if (this.user()) {
+ this.profilForm.patchValue({
+ name: this.user().name,
+ email: this.user().email,
+ fonction: this.user().fonction,
+ password: this.user().password
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/profil/profil.css b/src/app/components/profil/profil.css
new file mode 100644
index 0000000..72b4354
--- /dev/null
+++ b/src/app/components/profil/profil.css
@@ -0,0 +1,12 @@
+.fontProfil {
+ font-family: "Arial", cursive;
+ text-shadow: 2px 2px #8C731A, -2px -2px #8C731A;
+ font-weight: bold;
+}
+
+.festive2 {
+ font-family: "Comic Sans MS", cursive;
+ color: #001529;
+ font-weight: bold;
+}
+
diff --git a/src/app/components/profil/profil.html b/src/app/components/profil/profil.html
new file mode 100644
index 0000000..a504813
--- /dev/null
+++ b/src/app/components/profil/profil.html
@@ -0,0 +1,9 @@
+
+ {{ getInitial(user().name) }}
+
+
+
+
{{ user().name }}
+
{{ user().email }}
+
{{ user().fonction }}
+
diff --git a/src/app/components/profil/profil.ts b/src/app/components/profil/profil.ts
new file mode 100644
index 0000000..f4d420d
--- /dev/null
+++ b/src/app/components/profil/profil.ts
@@ -0,0 +1,31 @@
+import {Component, inject, OnInit, signal} from '@angular/core';
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {GetUserDto, UserService} from "../../services/api";
+import {firstValueFrom} from "rxjs";
+
+@Component({
+ selector: 'app-profil',
+ imports: [],
+ templateUrl: './profil.html',
+ styleUrl: './profil.css',
+})
+export class Profil implements OnInit {
+ private notificationService = inject(NzNotificationService);
+ private userService = inject(UserService);
+
+ user = signal({});
+
+ async ngOnInit() {
+ try {
+ const user = await firstValueFrom(this.userService.getUserEndpoint());
+ this.user.set(user);
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de charger l\'utilisateur');
+ }
+ }
+
+ getInitial(name: string): string {
+ if (!name || name.trim() === '') return '?';
+ return name[0].toUpperCase();
+ }
+}
diff --git a/src/app/components/purchase-order-form/purchase-order-form.css b/src/app/components/purchase-order-form/purchase-order-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/purchase-order-form/purchase-order-form.html b/src/app/components/purchase-order-form/purchase-order-form.html
new file mode 100644
index 0000000..6804075
--- /dev/null
+++ b/src/app/components/purchase-order-form/purchase-order-form.html
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/src/app/components/purchase-order-form/purchase-order-form.ts b/src/app/components/purchase-order-form/purchase-order-form.ts
new file mode 100644
index 0000000..57e5725
--- /dev/null
+++ b/src/app/components/purchase-order-form/purchase-order-form.ts
@@ -0,0 +1,41 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {GetPurchaseOrderDto} from "../../services/api";
+
+@Component({
+ selector: 'app-purchase-order-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './purchase-order-form.html',
+ styleUrl: './purchase-order-form.css',
+})
+export class PurchaseOrderForm {
+ purchaseOrderForm: FormGroup = new FormGroup({
+ purchaseConditions: new FormControl(null, [Validators.required])
+ })
+
+ purchaseOrder = input();
+
+ constructor() {
+ effect(() => {
+ if (this.purchaseOrder()) {
+ this.purchaseOrderForm.patchValue({
+ purchaseConditions: this.purchaseOrder().purchaseConditions,
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/purchase-order-table/purchase-order-table.css b/src/app/components/purchase-order-table/purchase-order-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/purchase-order-table/purchase-order-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/purchase-order-table/purchase-order-table.html b/src/app/components/purchase-order-table/purchase-order-table.html
new file mode 100644
index 0000000..5cb9e04
--- /dev/null
+++ b/src/app/components/purchase-order-table/purchase-order-table.html
@@ -0,0 +1,102 @@
+
+
+
+ | Numéro |
+ Conditions de vente |
+ Fournisseur |
+ Produits |
+ Action |
+
+
+
+ @for (purchaseOrder of purchaseOrders(); track purchaseOrder.id) {
+
+ | {{ purchaseOrder.id }} |
+ {{ purchaseOrder.purchaseConditions }} |
+ {{ purchaseOrder.supplierName }} |
+
+
+
+
+
+
+ | Nom |
+ Reférence |
+ Prix |
+ Quantité |
+ Action |
+
+
+
+ @for (product of purchaseOrder.products; track product.productId) {
+
+ | {{ product.productName }} |
+ {{ product.productReference }} |
+ {{ product.productPrice }} € |
+ {{ product.quantity }} |
+
+
+
+
+
+
+ |
+
+ }
+
+
+
+
+ |
+
+
+
+
+ @if (admin()) {
+
+
+ }
+
+
+
+
+ |
+
+ }
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/purchase-order-table/purchase-order-table.ts b/src/app/components/purchase-order-table/purchase-order-table.ts
new file mode 100644
index 0000000..ef74075
--- /dev/null
+++ b/src/app/components/purchase-order-table/purchase-order-table.ts
@@ -0,0 +1,215 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {PurchaseOrderForm} from "../purchase-order-form/purchase-order-form";
+import {ModalButton} from "../modal-button/modal-button";
+import {
+ CreateDeliveryNoteDto,
+ DeliverynotesService,
+ GetPurchaseOrderDto,
+ GetPurchaseProductDto,
+ PurchaseordersService,
+} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {FileService} from "../../services/file.service";
+import {QuantityForm} from "../quantity-form/quantity-form";
+import {DelivererChoice} from "../deliverer-choice/deliverer-choice";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-purchase-order-table',
+ imports: [
+ ModalNav,
+ NzDividerComponent,
+ NzIconDirective,
+ NzTableComponent,
+ PurchaseOrderForm,
+ ModalButton,
+ QuantityForm,
+ DelivererChoice,
+ ],
+ templateUrl: './purchase-order-table.html',
+ styleUrl: './purchase-order-table.css',
+})
+export class PurchaseOrderTable implements OnInit {
+ private purchaseOrdersService = inject(PurchaseordersService);
+ private notificationService = inject(NzNotificationService);
+ private fileService = inject(FileService);
+ private deliveryNoteService = inject(DeliverynotesService);
+ private authService = inject(AuthService);
+
+ purchaseOrders = signal([]);
+ purchaseOrdersLoading = signal(false);
+ admin = signal(false);
+
+ modal = viewChild.required('modalNav');
+ modalQuantity = viewChild.required('modalQuantity');
+ modalDeliverer = viewChild.required('modalDeliverer');
+
+ async ngOnInit() {
+ await this.fetchPurchaseOrder();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchPurchaseOrder() {
+ this.purchaseOrdersLoading.set(true)
+
+ try {
+ const purchaseOrders = await firstValueFrom(this.purchaseOrdersService.getAllPurchaseOrderEndpoint())
+ this.purchaseOrders.set(purchaseOrders);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des bons de commande')
+ }
+ this.purchaseOrdersLoading.set(false)
+ }
+
+ async delete(purchaseOrderId: number) {
+ this.purchaseOrdersLoading.set(true)
+ try {
+ await firstValueFrom(this.purchaseOrdersService.deletePurchaseOrderEndpoint(purchaseOrderId))
+ this.notificationService.success('Success', 'Suppression effectuée')
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne')
+ }
+ this.purchaseOrdersLoading.set(false)
+ await this.fetchPurchaseOrder();
+ }
+
+ async export(purchaseOrderId: number) {
+ this.purchaseOrdersLoading.set(true)
+ try {
+ const pdf = await firstValueFrom(
+ this.purchaseOrdersService.getPurchaseOrderPdfEndpoint(purchaseOrderId, "response")
+ );
+ this.fileService.downloadBlob(pdf)
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de générer un PDF');
+ }
+ this.purchaseOrdersLoading.set(false)
+ }
+
+ async transfer(purchaseOrder: GetPurchaseOrderDto, delivererForm: DelivererChoice) {
+ this.purchaseOrdersLoading.set(true);
+ try {
+ const deliverer = delivererForm.choiceDelivererForm.getRawValue();
+
+ const date = new Date().toISOString().split('T')[0]; // yyyy-mm-dd
+
+ let trackingValue = 'TRK-';
+ const idStr = purchaseOrder.id?.toString() ?? '';
+ if (idStr.length < 2) trackingValue += '00' + idStr + '-' + date;
+ else if (idStr.length < 3) trackingValue += '0' + idStr + '-' + date;
+ else trackingValue += idStr.substring(0, 3) + date.replace(/-/g, '');
+
+ const productQuantities: Record = {};
+ purchaseOrder.products?.forEach(p => {
+ if (p.productId != null && p.quantity != null) {
+ productQuantities[p.productId] = p.quantity;
+ }
+ });
+
+ const deliveryNoteDto: CreateDeliveryNoteDto = {
+ trackingNumber: trackingValue,
+ delivererId: deliverer.delivererId,
+ productQuantities: productQuantities,
+ supplierId: purchaseOrder.supplierId
+ };
+
+ await firstValueFrom(this.deliveryNoteService.createDeliveryNoteEndpoint(deliveryNoteDto));
+ this.notificationService.success('Succès', 'Bon de livraison créé avec succès');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du transfert');
+ }
+ this.onModalCancel(this.modalDeliverer());
+ this.purchaseOrdersLoading.set(false);
+ }
+
+
+ async edit(id: number, updatePurchaseOrderComponent: PurchaseOrderForm) {
+ if (updatePurchaseOrderComponent.purchaseOrderForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ return;
+ }
+
+ try {
+ const purchaseOrders = updatePurchaseOrderComponent.purchaseOrderForm.getRawValue();
+ await firstValueFrom(this.purchaseOrdersService.patchPurchaseOrderPurchaseConditionsEndpoint(id, purchaseOrders))
+
+ this.notificationService.success('Success', 'Bon de commande modifié')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification')
+ }
+ }
+
+ async deleteProduct(productId: number, purchaseOrderId: number) {
+ this.purchaseOrdersLoading.set(true)
+ try {
+ await firstValueFrom(this.purchaseOrdersService.deleteProductFromPurchaseOrderEndpoint(productId, purchaseOrderId))
+ this.notificationService.success('Success', 'Suppression effectuée')
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne')
+ }
+ this.purchaseOrdersLoading.set(false)
+ await this.fetchPurchaseOrder();
+ }
+
+ async editQuantity(productId: number, purchaseOrderId: number, updateQuantityComponent: QuantityForm) {
+ if (updateQuantityComponent.quantityForm.invalid) {
+ this.notificationService.error('Erreur', 'Erreur d\'écriture dans le formulaire')
+ return;
+ }
+
+ try {
+ const quantity = updateQuantityComponent.quantityForm.getRawValue();
+ await firstValueFrom(this.purchaseOrdersService.patchPurchaseProductQuantityEndpoint(productId, purchaseOrderId, quantity))
+
+ this.notificationService.success('Success', 'Quantité modifiée');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification');
+ }
+ }
+
+ selectedPurchaseOrder: GetPurchaseOrderDto | null = null;
+
+ openEditModal(purchaseOrder: GetPurchaseOrderDto) {
+ this.selectedPurchaseOrder = {...purchaseOrder};
+ this.modal().showModal();
+ }
+
+ openDelivererModal(purchaseOrder: GetPurchaseOrderDto) {
+ this.selectedPurchaseOrder = {...purchaseOrder};
+ this.modalDeliverer().showModal();
+ }
+
+ async onModalOk(id: number, updatePurchaseOrderComponent: PurchaseOrderForm, modal: ModalNav) {
+ if (!this.selectedPurchaseOrder) return;
+
+ await this.edit(id, updatePurchaseOrderComponent);
+ updatePurchaseOrderComponent.purchaseOrderForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchPurchaseOrder();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+
+ selectedQuantity: GetPurchaseProductDto | null = null;
+
+ openEditQuantityModal(quantity: GetPurchaseProductDto) {
+ this.selectedQuantity = {...quantity};
+ this.modalQuantity().showModal();
+ }
+
+ async onModalQuantityOk(productId: number, purchaseOrderId: number, updateQuantityComponent: QuantityForm, modal: ModalNav) {
+ if (!this.selectedQuantity) return;
+
+ await this.editQuantity(productId, purchaseOrderId, updateQuantityComponent);
+ updateQuantityComponent.quantityForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchPurchaseOrder();
+ }
+}
diff --git a/src/app/components/quantity-form/quantity-form.css b/src/app/components/quantity-form/quantity-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/quantity-form/quantity-form.html b/src/app/components/quantity-form/quantity-form.html
new file mode 100644
index 0000000..0d987c5
--- /dev/null
+++ b/src/app/components/quantity-form/quantity-form.html
@@ -0,0 +1,11 @@
+
diff --git a/src/app/components/quantity-form/quantity-form.ts b/src/app/components/quantity-form/quantity-form.ts
new file mode 100644
index 0000000..8db14dd
--- /dev/null
+++ b/src/app/components/quantity-form/quantity-form.ts
@@ -0,0 +1,41 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {GetPurchaseProductDto} from "../../services/api";
+
+@Component({
+ selector: 'app-quantity-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './quantity-form.html',
+ styleUrl: './quantity-form.css',
+})
+export class QuantityForm {
+ quantityForm: FormGroup = new FormGroup({
+ quantity: new FormControl(null, [Validators.required])
+ })
+
+ quantity = input();
+
+ constructor() {
+ effect(() => {
+ if (this.quantity()) {
+ this.quantityForm.patchValue({
+ quantity: this.quantity().quantity
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/quotation-form/quotation-form.css b/src/app/components/quotation-form/quotation-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/quotation-form/quotation-form.html b/src/app/components/quotation-form/quotation-form.html
new file mode 100644
index 0000000..b0b4420
--- /dev/null
+++ b/src/app/components/quotation-form/quotation-form.html
@@ -0,0 +1,22 @@
+
+
diff --git a/src/app/components/quotation-form/quotation-form.ts b/src/app/components/quotation-form/quotation-form.ts
new file mode 100644
index 0000000..cefdab9
--- /dev/null
+++ b/src/app/components/quotation-form/quotation-form.ts
@@ -0,0 +1,42 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {GetQuotationDto} from "../../services/api";
+
+@Component({
+ selector: 'app-quotation-form',
+ imports: [
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzFormControlComponent,
+ NzInputDirective,
+ NzColDirective,
+ NzFlexDirective,
+ NzFormDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './quotation-form.html',
+ styleUrl: './quotation-form.css',
+})
+export class QuotationForm {
+ quotationForm: FormGroup = new FormGroup({
+ message: new FormControl(null, [Validators.required]),
+ conditionsSale: new FormControl(null, [Validators.required]),
+ })
+
+ quotation = input();
+
+ constructor() {
+ effect(() => {
+ if (this.quotation()) {
+ this.quotationForm.patchValue({
+ message: this.quotation().message,
+ conditionsSale: this.quotation().conditionsSale,
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/quotation-table/quotation-table.css b/src/app/components/quotation-table/quotation-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/quotation-table/quotation-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/quotation-table/quotation-table.html b/src/app/components/quotation-table/quotation-table.html
new file mode 100644
index 0000000..9dc2cc7
--- /dev/null
+++ b/src/app/components/quotation-table/quotation-table.html
@@ -0,0 +1,90 @@
+
+
+
+ | Numéro de Devis |
+ Message |
+ Conditions de vente |
+ Produit |
+ Action |
+
+
+
+ @for (quotation of quotations(); track quotation.id) {
+
+ | {{ quotation.id }} |
+ {{ quotation.message }} |
+ {{ quotation.conditionsSale }} |
+
+
+
+
+
+
+ | Réference |
+ Nom |
+ Prix |
+ Quantité |
+ Action |
+
+
+
+ @for (product of quotation.products; track product.productId) {
+
+ | {{ product.productReference }} |
+ {{ product.productName }} |
+ {{ product.productPrice }} € |
+ {{ product.quantity }} |
+
+
+
+
+
+
+ |
+
+ }
+
+
+
+
+ |
+
+
+
+
+ @if (admin()) {
+
+
+ }
+
+
+ |
+
+ }
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/quotation-table/quotation-table.ts b/src/app/components/quotation-table/quotation-table.ts
new file mode 100644
index 0000000..4a3e000
--- /dev/null
+++ b/src/app/components/quotation-table/quotation-table.ts
@@ -0,0 +1,168 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {ModalButton} from "../modal-button/modal-button";
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {QuotationForm} from "../quotation-form/quotation-form";
+import {
+ GetQuotationDto,
+ GetQuotationProductDto,
+ QuotationsService
+} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {FileService} from "../../services/file.service";
+import {QuantityForm} from "../quantity-form/quantity-form";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-quotation-table',
+ imports: [
+ ModalButton,
+ ModalNav,
+ NzDividerComponent,
+ NzIconDirective,
+ NzTableComponent,
+ QuotationForm,
+ QuantityForm,
+ ],
+ templateUrl: './quotation-table.html',
+ styleUrl: './quotation-table.css',
+})
+
+export class QuotationTable implements OnInit {
+ private quotationsService = inject(QuotationsService);
+ private notificationService = inject(NzNotificationService);
+ private fileService = inject(FileService);
+ private authService = inject(AuthService);
+
+ quotations = signal([]);
+ quotationsLoading = signal(false);
+ admin = signal(false);
+
+ modal = viewChild.required('modalNav');
+ modalQuantity = viewChild.required('modalQuantity');
+
+ async ngOnInit() {
+ await this.fetchQuotations();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchQuotations() {
+ this.quotationsLoading.set(true)
+
+ try {
+ const quotations = await firstValueFrom(this.quotationsService.getAllQuotationEndpoint())
+ this.quotations.set(quotations);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors du chargement des devis')
+ }
+ this.quotationsLoading.set(false)
+ }
+
+ async delete(quotation: number) {
+ this.quotationsLoading.set(true)
+ try {
+ await firstValueFrom(this.quotationsService.deleteQuotationEndpoint(quotation))
+ this.notificationService.success('Success', 'Suppression effectuée')
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne')
+ }
+ this.quotationsLoading.set(false)
+ await this.fetchQuotations();
+ }
+
+ async export(quotationId: number) {
+ this.quotationsLoading.set(true)
+ try {
+ const pdf = await firstValueFrom(
+ this.quotationsService.getQuotationPdfEndpoint(quotationId, "response")
+ );
+ this.fileService.downloadBlob(pdf)
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de générer un PDF');
+ }
+ this.quotationsLoading.set(false)
+ }
+
+ async edit(id: number, updateQuotationComponent: QuotationForm) {
+ if (updateQuotationComponent.quotationForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ try {
+ const quotations = updateQuotationComponent.quotationForm.getRawValue();
+ await firstValueFrom(this.quotationsService.updateQuotationEndpoint(id, quotations));
+ this.notificationService.success('Success', 'Devis modifié')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification')
+ }
+ }
+
+ async deleteProduct(productId: number, quotationId: number) {
+ this.quotationsLoading.set(true)
+ try {
+ await firstValueFrom(this.quotationsService.deleteProductFromQuotationEndpoint(productId, quotationId))
+ this.notificationService.success('Success', 'Suppression effectuée')
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne')
+ }
+ this.quotationsLoading.set(false)
+ await this.fetchQuotations();
+ }
+
+ async editQuantity(productId: number, quotationId: number, updateQuantityComponent: QuantityForm) {
+ if (updateQuantityComponent.quantityForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ return;
+ }
+
+ try {
+ const quantity = updateQuantityComponent.quantityForm.getRawValue();
+ await firstValueFrom(this.quotationsService.patchQuotationProductQuantityEndpoint(productId, quotationId, quantity))
+
+ this.notificationService.success('Success', 'Quantité modifiée')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification')
+ }
+ }
+
+ selectedQuotation: GetQuotationDto | null = null;
+
+ openEditModal(quotation: GetQuotationDto) {
+ this.selectedQuotation = {...quotation};
+ this.modal().showModal();
+ }
+
+ async onModalOk(id: number, updateQuotationComponent: QuotationForm, modal: ModalNav) {
+ if (!this.selectedQuotation) return;
+
+ await this.edit(id, updateQuotationComponent);
+ updateQuotationComponent.quotationForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchQuotations();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+
+ selectedQuantity: GetQuotationProductDto | null = null;
+
+ openEditQuantityModal(quantity: GetQuotationProductDto) {
+ this.selectedQuantity = {...quantity};
+ this.modalQuantity().showModal();
+ }
+
+ async onModalQuantityOk(productId: number, quotationId: number, updateQuantityComponent: QuantityForm, modal: ModalNav) {
+ if (!this.selectedQuantity) return;
+
+ await this.editQuantity(productId, quotationId, updateQuantityComponent);
+ updateQuantityComponent.quantityForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchQuotations();
+ }
+}
+
diff --git a/src/app/components/setting-form/setting-form.css b/src/app/components/setting-form/setting-form.css
new file mode 100644
index 0000000..4b77112
--- /dev/null
+++ b/src/app/components/setting-form/setting-form.css
@@ -0,0 +1,36 @@
+/* Container de chaque ligne */
+.row {
+ display: flex;
+ align-items: center; /* centre verticalement les images et champs */
+ gap: 24px; /* espace entre preview et champ */
+ margin-bottom: 20px;
+}
+
+/* Colonne gauche : preview */
+.row-left {
+ width: 180px; /* fixe la largeur pour aligner toutes les images */
+ display: flex;
+ justify-content: center;
+}
+
+/* Image de preview */
+.row-left img {
+ max-width: 100%;
+ max-height: 80px;
+ object-fit: contain;
+ border: 1px solid #e6e6e6;
+ border-radius: 6px;
+ background-color: #fafafa;
+ padding: 4px;
+}
+
+/* Colonne droite : input */
+.row-right {
+ flex: 1; /* prend le reste de l'espace */
+}
+
+/* Retire la largeur forcée du nz-form-label et nz-form-control */
+.row-right nz-form-item nz-form-label,
+.row-right nz-form-item nz-form-control {
+ width: auto !important;
+}
diff --git a/src/app/components/setting-form/setting-form.html b/src/app/components/setting-form/setting-form.html
new file mode 100644
index 0000000..49fe210
--- /dev/null
+++ b/src/app/components/setting-form/setting-form.html
@@ -0,0 +1,60 @@
+
diff --git a/src/app/components/setting-form/setting-form.ts b/src/app/components/setting-form/setting-form.ts
new file mode 100644
index 0000000..cf93c09
--- /dev/null
+++ b/src/app/components/setting-form/setting-form.ts
@@ -0,0 +1,87 @@
+import {Component, inject, OnInit, signal} from '@angular/core';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from "@angular/forms";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {SettingInfo} from "../../interfaces/setting.interface";
+import {firstValueFrom} from "rxjs";
+import {GetSettingDto, SettingsService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import imageCompression from "browser-image-compression";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-setting-form',
+ imports: [
+ FormsModule,
+ NzColDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule,
+ ],
+ templateUrl: './setting-form.html',
+ styleUrl: './setting-form.css',
+})
+export class SettingForm implements OnInit {
+ private settingsService = inject(SettingsService);
+ private notificationService = inject(NzNotificationService);
+ private authService = inject(AuthService);
+
+ settings = signal({});
+ admin = signal(false);
+
+ setting: SettingInfo = {
+ logo: 'https://www.pyro-fetes.com/wp-content/themes/pcptheme/img/logo-pyro-fetes-OR-top.png',
+ electronicSignature: 'https://www.pyro-fetes.com/wp-content/themes/pcptheme/img/logo-pyro-fetes-OR-top.png'
+ }
+
+ settingForm: FormGroup = new FormGroup({
+ logo: new FormControl(null),
+ electronicSignature: new FormControl(null)
+ })
+
+ async ngOnInit() {
+ await this.fetchSettings();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchSettings() {
+ try {
+ const settingsPicture = await firstValueFrom(this.settingsService.getSettingEndpoint());
+ this.settings.set(settingsPicture);
+ } catch {
+ this.notificationService.error('Erreur', 'Aucun paramètre défini')
+ }
+ }
+
+ async onFileChange(control: string, files?: FileList | null) {
+ if (!files?.length) return;
+
+ const file = files[0];
+
+ const options = {
+ maxSizeMB: 1,
+ maxWidthOrHeight: 1080,
+ useWebWorker: true,
+ fileType: 'image/jpeg'
+ }
+
+ const compressed = await imageCompression(file, options);
+
+ try {
+ if (control === 'logo') {
+ await firstValueFrom(this.settingsService.patchSettingLogoEndpoint(compressed));
+ } else {
+ await firstValueFrom(this.settingsService.patchSettingElectronicSignatureEndpoint(compressed));
+ }
+ await this.fetchSettings();
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de changer les paramètres actuellement');
+ }
+
+ this.settingForm.reset();
+ }
+}
diff --git a/src/app/components/stock-form/stock-form.css b/src/app/components/stock-form/stock-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/stock-form/stock-form.html b/src/app/components/stock-form/stock-form.html
new file mode 100644
index 0000000..a691485
--- /dev/null
+++ b/src/app/components/stock-form/stock-form.html
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/src/app/components/stock-form/stock-form.ts b/src/app/components/stock-form/stock-form.ts
new file mode 100644
index 0000000..ad281f4
--- /dev/null
+++ b/src/app/components/stock-form/stock-form.ts
@@ -0,0 +1,42 @@
+import {Component, effect, input} from '@angular/core';
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {GetProductDto} from "../../services/api";
+
+@Component({
+ selector: 'app-stock-form',
+ imports: [
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzFormControlComponent,
+ NzInputDirective,
+ NzColDirective,
+ NzFormDirective,
+ ReactiveFormsModule,
+ NzFlexDirective
+ ],
+ templateUrl: './stock-form.html',
+ styleUrl: './stock-form.css',
+})
+export class StockForm {
+ stockForm = new FormGroup({
+ id: new FormControl(null),
+ minimalQuantity: new FormControl(null, [Validators.required])
+ })
+
+ product = input();
+
+ constructor() {
+ effect(() => {
+ if (this.product()) {
+ this.stockForm.patchValue({
+ id: this.product().id,
+ minimalQuantity: this.product().minimalQuantity,
+ });
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/stock-table/stock-table.css b/src/app/components/stock-table/stock-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/stock-table/stock-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/stock-table/stock-table.html b/src/app/components/stock-table/stock-table.html
new file mode 100644
index 0000000..ca04789
--- /dev/null
+++ b/src/app/components/stock-table/stock-table.html
@@ -0,0 +1,66 @@
+
+
+
+ |
+
+ |
+ Nom |
+ Référence |
+ Nec |
+ Calibre |
+ Poids |
+ Durée |
+ Quantité |
+ Limite |
+ Action |
+
+
+
+
+ @for (product of products(); track product.id) {
+
+ |
+
+ |
+ {{ product.name }} |
+ {{ product.references }} |
+ {{ product.nec }} |
+ {{ product.caliber }} |
+ {{ product.weight }} |
+ {{ product.duration }} |
+ {{ product.totalQuantity }} |
+ {{ product.minimalQuantity }} |
+
+
+
+ @if (admin()) {
+
+
+ }
+
+ |
+
+ }
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/stock-table/stock-table.ts b/src/app/components/stock-table/stock-table.ts
new file mode 100644
index 0000000..ca7ab83
--- /dev/null
+++ b/src/app/components/stock-table/stock-table.ts
@@ -0,0 +1,159 @@
+import {Component, inject, OnInit, output, signal, viewChild} from '@angular/core';
+import {NzTableComponent, NzThMeasureDirective} from "ng-zorro-antd/table";
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {StockForm} from "../stock-form/stock-form";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {FormsModule} from "@angular/forms";
+import {GetProductDto, ProductsService, WarehouseproductsService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {NzCheckboxComponent} from "ng-zorro-antd/checkbox";
+import {AuthService} from "../../services/auth.service";
+
+interface ProductWithQuantity extends GetProductDto {
+ totalQuantity?: number;
+}
+
+@Component({
+ selector: 'app-stock-table',
+ imports: [
+ NzTableComponent,
+ ModalNav,
+ NzIconDirective,
+ StockForm,
+ NzDividerComponent,
+ FormsModule,
+ NzThMeasureDirective,
+ NzCheckboxComponent,
+ ],
+ templateUrl: './stock-table.html',
+ styleUrl: './stock-table.css',
+})
+
+export class StockTable implements OnInit {
+ private productsService = inject(ProductsService);
+ private wareHousseProductsService = inject(WarehouseproductsService)
+ private notificationService = inject(NzNotificationService)
+ private authService = inject(AuthService);
+
+ products = signal([]);
+ productsLoading = signal(false);
+ admin = signal(false);
+
+ modal = viewChild.required('modalNav');
+
+ selectionChange = output();
+ productsTables = output();
+
+ selectedProduct: GetProductDto | null = null;
+ checked: boolean = false;
+ indeterminate: boolean = false;
+ selectedIds: number[] = [];
+
+ async ngOnInit() {
+ await this.fetchProducts();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchProducts() {
+ this.productsLoading.set(true);
+ try {
+ const products = await firstValueFrom(this.productsService.getAllProductsEndpoint());
+ this.productsTables.emit(products);
+
+ const productsWithQuantity = await Promise.all(
+ products.map(async (x) => {
+ try {
+ const quantity = await firstValueFrom(this.wareHousseProductsService.getTotalQuantityEndpoint(x.id));
+ return {
+ ...x,
+ totalQuantity: quantity.totalQuantity ?? 0
+ };
+ } catch {
+ return {
+ ...x,
+ totalQuantity: 0
+ };
+ }
+ })
+ );
+ this.products.set(productsWithQuantity);
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de charger le catalogue');
+ }
+ this.productsLoading.set(false);
+ }
+
+ async delete(productId: number) {
+ try {
+ await firstValueFrom(this.productsService.deleteProductEndpoint(productId))
+ this.notificationService.success('Success', 'Suppression effectuée');
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne');
+ }
+ await this.fetchProducts();
+ }
+
+ async edit(id: number, updateProductComponent: StockForm) {
+ if (updateProductComponent.stockForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ return;
+ }
+ try {
+ const products = updateProductComponent.stockForm.getRawValue();
+ await firstValueFrom(this.productsService.patchProductMinimalStockEndpoint(id, products));
+ await this.fetchProducts();
+ this.notificationService.success('Success', 'Limite de stock modifiée');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification');
+ }
+ }
+
+ openEditModal(product: GetProductDto) {
+ this.selectedProduct = {...product};
+ this.modal().showModal();
+ }
+
+ async onModalOk(productId: number, updateProductComponent: StockForm, modal: ModalNav) {
+ if (!this.selectedProduct) return;
+ await this.edit(productId, updateProductComponent);
+ updateProductComponent.stockForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchProducts();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+
+ updateCheck(id: number, checked: boolean) {
+ if (checked) {
+ if (!this.selectedIds.includes(id)) {
+ this.selectedIds.push(id);
+ }
+ } else this.selectedIds = this.selectedIds.filter(x => x !== id);
+ }
+
+ refreshCheckStatus() {
+ const total = this.products().length;
+ const checkedCount = this.selectedIds.length;
+
+ this.checked = checkedCount === total;
+ this.indeterminate = checkedCount > 0 && checkedCount < total;
+
+ this.selectionChange.emit(this.selectedIds);
+ }
+
+ allCheck(checked: boolean) {
+ this.products().forEach(x =>
+ this.updateCheck(x.id, checked)
+ );
+ this.refreshCheckStatus();
+ }
+
+ onItemChecked(id: number, checked: boolean): void {
+ this.updateCheck(id, checked);
+ this.refreshCheckStatus();
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/supplier-form/supplier-form.css b/src/app/components/supplier-form/supplier-form.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/supplier-form/supplier-form.html b/src/app/components/supplier-form/supplier-form.html
new file mode 100644
index 0000000..ed44a1a
--- /dev/null
+++ b/src/app/components/supplier-form/supplier-form.html
@@ -0,0 +1,66 @@
+
diff --git a/src/app/components/supplier-form/supplier-form.ts b/src/app/components/supplier-form/supplier-form.ts
new file mode 100644
index 0000000..d3581a8
--- /dev/null
+++ b/src/app/components/supplier-form/supplier-form.ts
@@ -0,0 +1,53 @@
+import {Component, effect, input} from '@angular/core';
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFlexDirective} from "ng-zorro-antd/flex";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {GetSupplierDto} from "../../services/api";
+
+@Component({
+ selector: 'app-supplier-form',
+ imports: [
+ NzColDirective,
+ NzFlexDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule
+ ],
+ templateUrl: './supplier-form.html',
+ styleUrl: './supplier-form.css',
+})
+export class SupplierForm {
+ supplier = input();
+
+ supplierForm: FormGroup = new FormGroup({
+ name: new FormControl(null, [Validators.required]),
+ email: new FormControl(null, [Validators.required]),
+ phone: new FormControl(null, [Validators.required]),
+ address: new FormControl(null, [Validators.required]),
+ zipCode: new FormControl(null, [Validators.required]),
+ city: new FormControl(null, [Validators.required]),
+ deliveryDelay: new FormControl(null, [Validators.required]),
+
+ })
+
+ constructor() {
+ effect(() => {
+ if (this.supplier()) {
+ this.supplierForm.patchValue({
+ name: this.supplier().name,
+ email: this.supplier().email,
+ phone: this.supplier().phone,
+ address: this.supplier().address,
+ zipCode: this.supplier().zipCode,
+ city: this.supplier().city,
+ deliveryDelay: this.supplier().deliveryDelay,
+ });
+ }
+ });
+ }
+}
diff --git a/src/app/components/supplier-table/supplier-table.css b/src/app/components/supplier-table/supplier-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/supplier-table/supplier-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/supplier-table/supplier-table.html b/src/app/components/supplier-table/supplier-table.html
new file mode 100644
index 0000000..576e468
--- /dev/null
+++ b/src/app/components/supplier-table/supplier-table.html
@@ -0,0 +1,93 @@
+
+
+
+ | Nom |
+ Téléphone |
+ Email |
+ Adresse |
+ Code Postal |
+ Ville |
+ Délai moyen |
+ Produits |
+ Action |
+
+
+
+ @for (supplier of suppliers(); track supplier.id) {
+
+ | {{ supplier.name }} |
+ {{ supplier.phone }} |
+ {{ supplier.email }} |
+ {{ supplier.address }} |
+ {{ supplier.zipCode }} |
+ {{ supplier.city }} |
+ {{ supplier.deliveryDelay }} jours |
+
+
+
+
+
+ | Produit |
+ Référence |
+ Prix |
+ Action |
+
+
+
+ @for (product of supplier.prices; track product.productId) {
+
+ | {{ product.productName }} |
+ {{ product.productReference }} |
+ {{ product.sellingPrice }}€ |
+
+
+
+ @if (admin()) {
+
+
+ }
+
+ |
+
+ }
+
+
+
+ |
+
+
+
+ @if (admin()) {
+
+
+ }
+
+ |
+
+ }
+
+
+
+
+
+
diff --git a/src/app/components/supplier-table/supplier-table.ts b/src/app/components/supplier-table/supplier-table.ts
new file mode 100644
index 0000000..3d0d181
--- /dev/null
+++ b/src/app/components/supplier-table/supplier-table.ts
@@ -0,0 +1,156 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {ModalButton} from "../modal-button/modal-button";
+import {SupplierForm} from "../supplier-form/supplier-form";
+import {GetPriceDto, GetSupplierDto, PricesService, SuppliersService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+import {PriceForm} from "../price-form/price-form";
+import {AuthService} from "../../services/auth.service";
+
+@Component({
+ selector: 'app-supplier-table',
+ imports: [
+ ModalNav,
+ NzDividerComponent,
+ NzIconDirective,
+ NzTableComponent,
+ ModalButton,
+ SupplierForm,
+ PriceForm,
+ ],
+ templateUrl: './supplier-table.html',
+ styleUrl: './supplier-table.css',
+})
+
+export class SupplierTable implements OnInit {
+ private suppliersService = inject(SuppliersService);
+ private pricesService = inject(PricesService);
+ private notificationService = inject(NzNotificationService);
+ private authService = inject(AuthService);
+
+ suppliers = signal([]);
+ suppliersLoading = signal(false);
+ admin = signal(false);
+
+ supplierModal = viewChild.required('supplierModal');
+ productModal = viewChild.required('productModal');
+
+ selectedSupplier: GetSupplierDto | null = null;
+ selectedProduct: GetPriceDto | null = null;
+ selectedProductSupplierId: number | null = null;
+
+ async ngOnInit() {
+ await this.fetchSuppliers();
+ this.admin.set(this.authService.isAdmin());
+ }
+
+ async fetchSuppliers() {
+ this.suppliersLoading.set(true);
+ try {
+ const suppliers = await firstValueFrom(this.suppliersService.getAllSuppliersEndpoint());
+ this.suppliers.set(suppliers);
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur de communication avec l\'API');
+ }
+ this.suppliersLoading.set(false);
+ }
+
+ async edit(id: number, updateSupplierComponent: SupplierForm) {
+ if (updateSupplierComponent.supplierForm.invalid) {
+ this.notificationService.error('Erreur', 'Erreur d\'écriture dans le formulaire');
+ return;
+ }
+ try {
+ const suppliers = updateSupplierComponent.supplierForm.getRawValue();
+ await firstValueFrom(this.suppliersService.updateSupplierEndpoint(id, suppliers));
+ this.notificationService.success('Success', 'Fournisseur modifié');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification');
+ }
+ }
+
+ async delete(supplier: number) {
+ try {
+ await firstValueFrom(this.suppliersService.deleteSupplierEndpoint(supplier));
+ this.notificationService.success('Succès', 'Suppression effectuée');
+ await this.fetchSuppliers();
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne');
+ }
+ }
+
+ openEditModal(supplier: GetSupplierDto) {
+ this.selectedSupplier = {...supplier};
+ this.supplierModal().showModal();
+ }
+
+ openEditProductModal(product: GetPriceDto, supplierId: number) {
+ this.selectedProduct = {...product};
+ this.selectedProductSupplierId = supplierId;
+ this.productModal().showModal();
+ }
+
+ async onModalOk(supplierId: number | undefined, updateSupplierComponent: SupplierForm, modal: ModalNav) {
+ if (!supplierId || !this.selectedSupplier) return;
+
+ await this.edit(supplierId, updateSupplierComponent);
+ updateSupplierComponent.supplierForm.reset();
+ modal.isVisible = false;
+ await this.fetchSuppliers();
+ }
+
+ async onModalProductOk(
+ productId: number | undefined,
+ supplierId: number | null | undefined,
+ updateProductComponent: PriceForm,
+ modal: ModalNav
+ ) {
+ if (productId == null || supplierId == null || !this.selectedProduct) {
+ this.notificationService.error('Erreur', 'Identifiants produit ou fournisseur manquants');
+ return;
+ }
+
+ await this.editPrice(productId, supplierId, updateProductComponent);
+ updateProductComponent.priceForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchSuppliers();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+
+ async editPrice(productId: number, supplierId: number, updateProductComponent: PriceForm) {
+ if (updateProductComponent.priceForm.invalid) {
+ this.notificationService.error('Erreur', 'Erreur d\'écriture dans le formulaire');
+ return;
+ }
+ try {
+ const formValue = updateProductComponent.priceForm.getRawValue();
+ const body = {
+ productId,
+ supplierId,
+ sellingPrice: Number(formValue.price),
+ };
+ await firstValueFrom(this.pricesService.patchPriceEndpoint(productId, supplierId, body));
+ this.notificationService.success('Success', 'Prix modifié');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification');
+ }
+ }
+
+
+ async deleteProduct(idProduct: number, idSupplier: number) {
+ try {
+ await firstValueFrom(this.suppliersService.deleteProductToSupplierEndpoint(idSupplier, idProduct));
+ this.notificationService.success('Succès', 'Produit supprimé');
+ await this.fetchSuppliers();
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer le produit');
+ }
+ }
+}
diff --git a/src/app/components/user-table/user-table.css b/src/app/components/user-table/user-table.css
new file mode 100644
index 0000000..c804da2
--- /dev/null
+++ b/src/app/components/user-table/user-table.css
@@ -0,0 +1,88 @@
+/* Table globale */
+nz-table {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0 8px; /* espace entre les lignes */
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+/* En-tête */
+nz-table thead tr {
+ background-color: #f5f5f5;
+ text-align: left;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 2px solid #e0e0e0;
+}
+
+nz-table thead th {
+ padding: 12px 16px;
+}
+
+/* Lignes du tableau */
+nz-table tbody tr {
+ background-color: #fff;
+ transition: background 0.2s ease;
+}
+
+nz-table tbody tr:nth-child(even) {
+ background-color: #f9f9f9;
+}
+
+nz-table tbody tr:hover {
+ background-color: #e6f7ff; /* survol */
+}
+
+/* Cellules */
+nz-table tbody td {
+ padding: 12px 16px;
+ vertical-align: middle;
+ color: #444;
+}
+
+/* Boutons */
+nz-table button[nz-button] {
+ margin-right: 8px;
+}
+
+/* Modals dans le tableau */
+nz-table app-modal {
+ margin-right: 8px;
+}
+
+/* Dates (pour alignement et style) */
+nz-table tbody td p {
+ margin: 0;
+ font-size: 14px;
+ color: #555;
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ nz-table thead {
+ display: none;
+ }
+
+ nz-table tbody tr {
+ display: block;
+ margin-bottom: 16px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ nz-table tbody td {
+ display: flex;
+ justify-content: space-between;
+ padding: 6px 12px;
+ }
+
+ nz-table tbody td::before {
+ content: attr(data-label);
+ font-weight: 600;
+ }
+}
diff --git a/src/app/components/user-table/user-table.html b/src/app/components/user-table/user-table.html
new file mode 100644
index 0000000..dfbccb2
--- /dev/null
+++ b/src/app/components/user-table/user-table.html
@@ -0,0 +1,40 @@
+
+
+
+ | Prénom |
+ Email |
+ Fonction |
+ Action |
+
+
+
+ @for (user of users(); track user.id) {
+
+ | {{ user.name }} |
+ {{ user.email }} |
+ {{ user.fonction }} |
+
+
+ |
+
+ }
+
+
+
+
diff --git a/src/app/components/user-table/user-table.ts b/src/app/components/user-table/user-table.ts
new file mode 100644
index 0000000..9cf4bb5
--- /dev/null
+++ b/src/app/components/user-table/user-table.ts
@@ -0,0 +1,93 @@
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {ModalNav} from "../modal-nav/modal-nav";
+import {NzIconDirective} from "ng-zorro-antd/icon";
+import {NzTableComponent} from "ng-zorro-antd/table";
+import {ProfilForm} from "../profil-form/profil-form";
+import {NzDividerComponent} from "ng-zorro-antd/divider";
+import {GetUserDto, UsersService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
+
+@Component({
+ selector: 'app-user-table',
+ imports: [
+ ModalNav,
+ NzIconDirective,
+ NzTableComponent,
+ ProfilForm,
+ NzDividerComponent
+ ],
+ templateUrl: './user-table.html',
+ styleUrl: './user-table.css',
+})
+export class UserTable implements OnInit {
+ private usersService = inject(UsersService);
+ private notificationService = inject(NzNotificationService)
+
+ users = signal([]);
+ usersLoading = signal(false);
+
+ modal = viewChild.required('modalNav');
+
+ async ngOnInit() {
+ await this.fetchUsers();
+ }
+
+ async fetchUsers() {
+ this.usersLoading.set(true)
+
+ try {
+ const users = await firstValueFrom(this.usersService.getAllUsersEndpoint())
+ this.users.set(users);
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de charger les utilisateurs')
+ }
+ this.usersLoading.set(false)
+ }
+
+ async delete(user: number) {
+ try {
+ await firstValueFrom(this.usersService.deleteUserEndpoint(user))
+ this.notificationService.success('Success', 'Suppression effectuée')
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de supprimer la ligne')
+ }
+ await this.fetchUsers();
+ }
+
+ async edit(id: number, updateUserComponent: ProfilForm) {
+ if (updateUserComponent.profilForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ return;
+ }
+
+ try {
+ const users = updateUserComponent.profilForm.getRawValue();
+ await firstValueFrom(this.usersService.updateUserEndpoint(id, users))
+
+ this.notificationService.success('Success', 'Utilisateur modifié')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la modification')
+ }
+ }
+
+ selectedUser: GetUserDto | null = null;
+
+ openEditModal(user: GetUserDto) {
+ this.selectedUser = {...user};
+ this.modal().showModal();
+ }
+
+ async onModalOk(userId: number, updateUserComponent: ProfilForm, modal: ModalNav) {
+ if (!this.selectedUser) return;
+
+ await this.edit(userId, updateUserComponent);
+ updateUserComponent.profilForm.reset();
+ this.onModalCancel(modal);
+ await this.fetchUsers();
+ }
+
+ onModalCancel(modal: ModalNav) {
+ modal.isVisible = false;
+ }
+}
diff --git a/src/app/guards/auth.guard.ts b/src/app/guards/auth.guard.ts
new file mode 100644
index 0000000..ab6317f
--- /dev/null
+++ b/src/app/guards/auth.guard.ts
@@ -0,0 +1,14 @@
+import { inject } from '@angular/core';
+import { Router } from '@angular/router';
+import { AuthService} from "../services/auth.service";
+
+export const authGuard = async () => {
+ const auth = inject(AuthService);
+ const router = inject(Router);
+
+ if(!auth.userAuthenticated()) {
+ await router.navigateByUrl('/login');
+ return false;
+ }
+ return true
+};
\ No newline at end of file
diff --git a/src/app/interceptors/auth-interceptor.ts b/src/app/interceptors/auth-interceptor.ts
new file mode 100644
index 0000000..77568a3
--- /dev/null
+++ b/src/app/interceptors/auth-interceptor.ts
@@ -0,0 +1,48 @@
+import {HttpInterceptorFn, HttpErrorResponse, HttpRequest, HttpHandlerFn} from '@angular/common/http';
+import {inject} from '@angular/core';
+import {AuthService} from '../services/auth.service';
+import {RefreshService} from '../services/api';
+import {NzNotificationService} from 'ng-zorro-antd/notification';
+import {catchError, switchMap, throwError} from 'rxjs';
+
+export const authInterceptor: HttpInterceptorFn = (req: HttpRequest, next: HttpHandlerFn) => {
+ const authService = inject(AuthService);
+ const refreshService = inject(RefreshService);
+ const notification = inject(NzNotificationService);
+ const token = authService.getToken();
+
+ let authReq = req;
+ if (token) {
+ authReq = req.clone({
+ setHeaders: {Authorization: `Bearer ${token}`}
+ });
+ }
+
+ return next(authReq).pipe(
+ catchError((error: HttpErrorResponse) => {
+ if (error.status === 401 && token) {
+ return refreshService.refreshTokenEndpoint({token})
+ .pipe(
+ switchMap((res: any) => {
+ authService.setToken(res.token);
+ const newReq = req.clone({
+ setHeaders: {Authorization: `Bearer ${res.token}`}
+ });
+ return next(newReq);
+ }),
+ catchError((refreshErr) => {
+ authService.logout();
+ notification.error('Session expirée', 'Veuillez vous reconnecter.');
+ return throwError(() => refreshErr);
+ })
+ );
+ }
+
+ if (error.status === 403) {
+ notification.error('Accès refusé', 'Vous n’avez pas les droits pour cette action.');
+ }
+
+ return throwError(() => error);
+ })
+ );
+};
\ No newline at end of file
diff --git a/src/app/interfaces/setting.interface.ts b/src/app/interfaces/setting.interface.ts
new file mode 100644
index 0000000..2171a7c
--- /dev/null
+++ b/src/app/interfaces/setting.interface.ts
@@ -0,0 +1,4 @@
+export interface SettingInfo {
+ logo: string;
+ electronicSignature: string;
+}
\ No newline at end of file
diff --git a/src/app/interfaces/user.interface.ts b/src/app/interfaces/user.interface.ts
new file mode 100644
index 0000000..b7feffe
--- /dev/null
+++ b/src/app/interfaces/user.interface.ts
@@ -0,0 +1,5 @@
+export interface UserInfo {
+ name: string;
+ email: string;
+ fonction: string;
+}
\ No newline at end of file
diff --git a/src/app/pages/dashboard/dashboard.css b/src/app/pages/dashboard/dashboard.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/pages/dashboard/dashboard.html b/src/app/pages/dashboard/dashboard.html
new file mode 100644
index 0000000..e289089
--- /dev/null
+++ b/src/app/pages/dashboard/dashboard.html
@@ -0,0 +1,27 @@
+
\ No newline at end of file
diff --git a/src/app/pages/dashboard/dashboard.ts b/src/app/pages/dashboard/dashboard.ts
new file mode 100644
index 0000000..a158cc1
--- /dev/null
+++ b/src/app/pages/dashboard/dashboard.ts
@@ -0,0 +1,65 @@
+import {Component, inject, signal} from '@angular/core';
+import {InfoCard} from "../../components/info-card/info-card";
+import {DeliveryValidator} from "../../components/delivery-validator/delivery-validator";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {DeliverersService, GetSupplierDto, ProductsService, SuppliersService} from "../../services/api";
+import {firstValueFrom} from "rxjs";
+import {StockAlert} from "../../services/stock.alert";
+
+@Component({
+ selector: 'app-dashboard',
+ imports: [
+ InfoCard,
+ DeliveryValidator,
+ ],
+ templateUrl: './dashboard.html',
+ styleUrl: './dashboard.css'
+})
+
+export class Dashboard {
+ private productsService = inject(ProductsService);
+ private deliverersService = inject(DeliverersService);
+ private suppliersService = inject(SuppliersService);
+ private notificationsService = inject(NzNotificationService);
+ private stockAlertService = inject(StockAlert);
+
+ deliversCount = signal(0);
+ suppliersCount = signal(0);
+ productsUnderLimitCount = signal(0);
+ suppliers = signal([]);
+
+ async getDeliverers() {
+ try {
+ const deliverers = await firstValueFrom(this.deliverersService.getAllDelivererEndpoint());
+ this.deliversCount.set(deliverers.length);
+ } catch {
+ this.notificationsService.error('Erreur', 'Impossible de charger les transporteurs');
+ }
+ }
+
+ async getSuppliers() {
+ try {
+ const suppliers = await firstValueFrom(this.suppliersService.getAllSuppliersEndpoint());
+ this.suppliers.set(suppliers);
+ this.suppliersCount.set(suppliers.length);
+ } catch {
+ this.notificationsService.error('Erreur', 'Impossible de charger les fournisseurs');
+ }
+ }
+
+ async getProductsUnderLimit() {
+ try {
+ const products = await firstValueFrom(this.productsService.getAllProductsUnderLimitEndpoint());
+ this.productsUnderLimitCount.set(products.length);
+ await this.stockAlertService.generatePurchaseOrder(products, this.suppliers());
+ } catch {
+ this.notificationsService.error('Error', 'Impossible de charger les produits.');
+ }
+ }
+
+ async ngOnInit() {
+ await this.getDeliverers();
+ await this.getSuppliers();
+ await this.getProductsUnderLimit();
+ }
+}
diff --git a/src/app/pages/deliverer/deliverer.html b/src/app/pages/deliverer/deliverer.html
index fd81883..e7f9268 100644
--- a/src/app/pages/deliverer/deliverer.html
+++ b/src/app/pages/deliverer/deliverer.html
@@ -1 +1,15 @@
-deliverer works!
+
+
+
diff --git a/src/app/pages/deliverer/deliverer.ts b/src/app/pages/deliverer/deliverer.ts
index 9e36ced..74b9386 100644
--- a/src/app/pages/deliverer/deliverer.ts
+++ b/src/app/pages/deliverer/deliverer.ts
@@ -1,11 +1,50 @@
-import { Component } from '@angular/core';
+import {Component, inject, viewChild} from '@angular/core';
+import {ModalButton} from "../../components/modal-button/modal-button";
+import {DelivererTable} from "../../components/deliverer-table/deliverer-table";
+import {DelivererForm} from "../../components/deliverer-form/deliverer-form";
+import {DeliverersService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
@Component({
- selector: 'app-deliverer',
- imports: [],
- templateUrl: './deliverer.html',
- styleUrl: './deliverer.css',
+ selector: 'app-deliverer',
+ imports: [
+ ModalButton,
+ DelivererTable,
+ DelivererForm,
+ ],
+ templateUrl: './deliverer.html',
+ styleUrl: './deliverer.css',
})
export class Deliverer {
+ modal = viewChild.required('modalButton');
+ createDeliverer = viewChild.required('delivererForm');
+ delivererTable = viewChild.required('delivererTable');
+ private deliverersService = inject(DeliverersService);
+ private notificationService = inject(NzNotificationService)
-}
+ async onModalOk() {
+ await this.addDeliverer()
+ this.createDeliverer().delivererForm.reset();
+ this.onModalCancel();
+ await this.delivererTable().fetchDeliverers()
+ }
+
+ onModalCancel() {
+ this.modal().isVisible = false;
+ }
+
+ async addDeliverer() {
+ if (this.createDeliverer().delivererForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ }
+ try {
+ const deliverers = this.createDeliverer().delivererForm.getRawValue();
+ await firstValueFrom(this.deliverersService.createDelivererEndpoint(deliverers))
+
+ this.notificationService.success('Success', 'Transporteur enregistré')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur d\'enregistrement')
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/pages/delivery-note/delivery-note.html b/src/app/pages/delivery-note/delivery-note.html
index 736e266..2b50d1f 100644
--- a/src/app/pages/delivery-note/delivery-note.html
+++ b/src/app/pages/delivery-note/delivery-note.html
@@ -1 +1,3 @@
-delivery-note works!
+
diff --git a/src/app/pages/delivery-note/delivery-note.ts b/src/app/pages/delivery-note/delivery-note.ts
index cd3d99e..c35faa1 100644
--- a/src/app/pages/delivery-note/delivery-note.ts
+++ b/src/app/pages/delivery-note/delivery-note.ts
@@ -1,10 +1,13 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {DelivereryNoteTable} from "../../components/deliverery-note-table/deliverery-note-table";
@Component({
- selector: 'app-delivery-note',
- imports: [],
- templateUrl: './delivery-note.html',
- styleUrl: './delivery-note.css',
+ selector: 'app-delivery-note',
+ imports: [
+ DelivereryNoteTable,
+ ],
+ templateUrl: './delivery-note.html',
+ styleUrl: './delivery-note.css',
})
export class DeliveryNote {
diff --git a/src/app/pages/login/login.css b/src/app/pages/login/login.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/pages/login/login.html b/src/app/pages/login/login.html
new file mode 100644
index 0000000..90c7af9
--- /dev/null
+++ b/src/app/pages/login/login.html
@@ -0,0 +1,46 @@
+
+
+

+
+
+
+
+
+

+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/pages/login/login.ts b/src/app/pages/login/login.ts
new file mode 100644
index 0000000..2809b85
--- /dev/null
+++ b/src/app/pages/login/login.ts
@@ -0,0 +1,43 @@
+import {Component, inject, OnInit} from '@angular/core';
+import {NzColDirective} from "ng-zorro-antd/grid";
+import {NzFormControlComponent, NzFormDirective, NzFormItemComponent, NzFormLabelComponent} from "ng-zorro-antd/form";
+import {NzInputDirective} from "ng-zorro-antd/input";
+import {FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
+import {NzButtonComponent} from "ng-zorro-antd/button";
+import {AuthService} from "../../services/auth.service";
+import {Router} from "@angular/router";
+
+@Component({
+ selector: 'app-login',
+ imports: [
+ NzColDirective,
+ NzFormControlComponent,
+ NzFormDirective,
+ NzFormItemComponent,
+ NzFormLabelComponent,
+ NzInputDirective,
+ ReactiveFormsModule,
+ NzButtonComponent
+ ],
+ templateUrl: './login.html',
+ styleUrl: './login.css',
+})
+export class Login implements OnInit {
+ private authService = inject(AuthService);
+ private router = inject(Router);
+
+ ngOnInit() {
+ this.authService.logout();
+ }
+
+ loginForm: FormGroup = new FormGroup({
+ name: new FormControl(null, [Validators.required]),
+ password: new FormControl(null, [Validators.required])
+ })
+
+ async connectUser() {
+ if (this.loginForm.invalid) return;
+ const ok = await this.authService.connectUser(this.loginForm.value.name, this.loginForm.value.password);
+ if (ok) await this.router.navigate(['/dashboard']);
+ }
+}
diff --git a/src/app/pages/purchase-order/purchase-order.html b/src/app/pages/purchase-order/purchase-order.html
index f6376c5..b904151 100644
--- a/src/app/pages/purchase-order/purchase-order.html
+++ b/src/app/pages/purchase-order/purchase-order.html
@@ -1 +1,4 @@
-purchase-order works!
+
+
diff --git a/src/app/pages/purchase-order/purchase-order.ts b/src/app/pages/purchase-order/purchase-order.ts
index 574ce64..55da4aa 100644
--- a/src/app/pages/purchase-order/purchase-order.ts
+++ b/src/app/pages/purchase-order/purchase-order.ts
@@ -1,10 +1,13 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {PurchaseOrderTable} from "../../components/purchase-order-table/purchase-order-table";
@Component({
- selector: 'app-purchase-order',
- imports: [],
- templateUrl: './purchase-order.html',
- styleUrl: './purchase-order.css',
+ selector: 'app-purchase-order',
+ imports: [
+ PurchaseOrderTable,
+ ],
+ templateUrl: './purchase-order.html',
+ styleUrl: './purchase-order.css',
})
export class PurchaseOrder {
diff --git a/src/app/pages/quotation/quotation.html b/src/app/pages/quotation/quotation.html
index e7b7112..a03e0d8 100644
--- a/src/app/pages/quotation/quotation.html
+++ b/src/app/pages/quotation/quotation.html
@@ -1 +1,3 @@
-quotation works!
+
diff --git a/src/app/pages/quotation/quotation.ts b/src/app/pages/quotation/quotation.ts
index 2a2136d..b3380f2 100644
--- a/src/app/pages/quotation/quotation.ts
+++ b/src/app/pages/quotation/quotation.ts
@@ -1,10 +1,13 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {QuotationTable} from "../../components/quotation-table/quotation-table";
@Component({
- selector: 'app-quotation',
- imports: [],
- templateUrl: './quotation.html',
- styleUrl: './quotation.css',
+ selector: 'app-quotation',
+ imports: [
+ QuotationTable
+ ],
+ templateUrl: './quotation.html',
+ styleUrl: './quotation.css',
})
export class Quotation {
diff --git a/src/app/pages/stock/stock.html b/src/app/pages/stock/stock.html
index a46e7f2..02f11c0 100644
--- a/src/app/pages/stock/stock.html
+++ b/src/app/pages/stock/stock.html
@@ -1 +1,51 @@
-stock works!
+
+ @if (productIds().length) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+
+
\ No newline at end of file
diff --git a/src/app/pages/stock/stock.ts b/src/app/pages/stock/stock.ts
index 2ab1ba4..56b6ab7 100644
--- a/src/app/pages/stock/stock.ts
+++ b/src/app/pages/stock/stock.ts
@@ -1,11 +1,210 @@
-import { Component } from '@angular/core';
+import {Component, inject, OnInit, signal, viewChild} from '@angular/core';
+import {StockTable} from "../../components/stock-table/stock-table";
+import {ModalButton} from "../../components/modal-button/modal-button";
+import {CreatePurchaseorderForm} from "../../components/create-purchaseorder-form/create-purchaseorder-form";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {
+ CreatePurchaseOrderDto, CreateQuotationDto,
+ GetProductDto,
+ GetSupplierDto,
+ PurchaseordersService,
+ QuotationsService,
+ SuppliersService
+} from "../../services/api";
+import {firstValueFrom} from "rxjs";
+import {CreateQuotationForm} from "../../components/create-quotation-form/create-quotation-form";
+import {AddProductSupplierForm} from "../../components/add-product-supplier-form/add-product-supplier-form";
@Component({
- selector: 'app-stock',
- imports: [],
- templateUrl: './stock.html',
- styleUrl: './stock.css',
+ selector: 'app-stock',
+ imports: [
+ StockTable,
+ ModalButton,
+ CreatePurchaseorderForm,
+ CreateQuotationForm,
+ AddProductSupplierForm,
+ ],
+ templateUrl: './stock.html',
+ styleUrl: './stock.css',
})
-export class Stock {
+export class Stock implements OnInit {
+ createPurchaseOrder = viewChild.required('purchaseOrderForm');
+ createQuotation = viewChild.required('quotationForm');
+ addProduct = viewChild.required('supplierForm');
+ modalButtonPurchaseOrder = viewChild.required('modalButtonPurchaseOrder');
+ modalButtonQuotation = viewChild.required('modalButtonQuotation');
+ modalButtonSupplier = viewChild.required('modalButtonSupplier');
+
+ private purchaseOrdersService = inject(PurchaseordersService);
+ private quotationsService = inject(QuotationsService);
+ private suppliersService = inject(SuppliersService);
+ private notificationService = inject(NzNotificationService);
+
+ products = signal([]);
+ suppliers = signal([]);
+ selectedProducts = signal([]);
+
+ productIds = signal([]);
+
+ async ngOnInit() {
+ try {
+ const suppliers = await firstValueFrom(this.suppliersService.getAllSuppliersEndpoint());
+ this.suppliers.set(suppliers);
+ } catch {
+ this.notificationService.error('Erreur', 'Impossible de charger les fournisseurs');
+ }
+ }
+
+ onSelectionChange(ids: number[]) {
+ this.productIds.set(ids);
+ this.selectedProducts.set(this.products().filter(x => ids.includes(x.id)));
+ }
+
+ openPurchaseOrderForm() {
+ this.createPurchaseOrder().addProductToForm();
+ }
+
+ openQuotationForm() {
+ this.createQuotation().addProductToForm();
+ }
+
+ openSupplierForm() {
+ this.addProduct().addProductToForm();
+ }
+
+ async addPurchaseOrder() {
+ const form = this.createPurchaseOrder().createPurchaseOrderForm;
+
+ if (form.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ const orderLines = this.createPurchaseOrder().lines.value.map((line: { productId: any; quantity: any; }) => ({
+ productId: line.productId,
+ quantity: line.quantity
+ }));
+
+ if (!orderLines.length) {
+ this.notificationService.error('Erreur', 'Aucun produit sélectionné');
+ return;
+ }
+
+ const purchaseOrder: CreatePurchaseOrderDto = {
+ purchaseConditions: form.value.purchaseConditions,
+ products: orderLines,
+ supplierId: form.value.supplierId
+ };
+
+ try {
+ await firstValueFrom(this.purchaseOrdersService.createPurchaseOrder(purchaseOrder));
+ this.notificationService.success('Succès', 'Bon de commande créé');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la création du bon de commande.');
+ }
+ }
+
+ async addQuotation() {
+ const form = this.createQuotation().createQuotationForm;
+
+ if (form.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ const orderLines = this.createQuotation().lines.value.map((line: { productId: any; quantity: any; }) => ({
+ productId: line.productId,
+ quantity: line.quantity
+ }));
+
+ if (!orderLines.length) {
+ this.notificationService.error('Erreur', 'Aucun produit sélectionné');
+ return;
+ }
+
+ const quotation: CreateQuotationDto = {
+ message: this.createQuotation().createQuotationForm.value.message,
+ conditionsSale: this.createQuotation().createQuotationForm.value.conditionsSale,
+ customerId: this.createQuotation().createQuotationForm.value.customerId,
+ supplierId: this.createQuotation().createQuotationForm.value.supplierId,
+ products: orderLines
+ };
+
+ try {
+ await firstValueFrom(this.quotationsService.createQuotationEndpoint(quotation));
+ this.notificationService.success('Succès', 'Devis créé');
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur lors de la création du devis.');
+ }
+ }
+
+ async addProductFromSupplier() {
+ const form = this.addProduct().addProductForm;
+ let success = 0;
+
+ if (form.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide');
+ return;
+ }
+
+ const supplierId = form.value.supplierId;
+ const lines = this.addProduct().lines.value;
+
+ if (!lines.length) {
+ this.notificationService.error('Erreur', 'Aucun produit sélectionné');
+ return;
+ }
+
+ for (const line of lines) {
+ try {
+ await firstValueFrom(
+ this.suppliersService.addProductToSupplierEndpoint(
+ supplierId,
+ line.productId,
+ {
+ sellingPrice: line.price
+ }
+ )
+ );
+
+ success++;
+ } catch {
+ }
+ }
+ this.notificationService.success('Succès', `${success} produits ajoutés`);
+ }
+
+ async onModalPurchaseOrderOk() {
+ await this.addPurchaseOrder();
+ this.createPurchaseOrder().createPurchaseOrderForm.reset();
+ this.modalButtonPurchaseOrder().isVisible = false;
+ this.onModalPurchaseOrderCancel();
+ }
+
+ onModalPurchaseOrderCancel() {
+ this.modalButtonPurchaseOrder().isVisible = false;
+ }
+
+ async onModalQuotationOk() {
+ await this.addQuotation();
+ this.createQuotation().createQuotationForm.reset();
+ this.modalButtonQuotation().isVisible = false;
+ this.onModalQuotationCancel();
+ }
+
+ onModalQuotationCancel() {
+ this.modalButtonQuotation().isVisible = false;
+ }
+
+ async onModalSupplierOk() {
+ await this.addProductFromSupplier();
+ this.addProduct().addProductForm.reset();
+ this.modalButtonSupplier().isVisible = false;
+ this.onModalSupplierCancel();
+ }
+
+ onModalSupplierCancel() {
+ this.modalButtonSupplier().isVisible = false;
+ }
}
diff --git a/src/app/pages/supplier/supplier.html b/src/app/pages/supplier/supplier.html
index 572d871..6a6f549 100644
--- a/src/app/pages/supplier/supplier.html
+++ b/src/app/pages/supplier/supplier.html
@@ -1 +1,15 @@
-supplier works!
+
+
+
diff --git a/src/app/pages/supplier/supplier.ts b/src/app/pages/supplier/supplier.ts
index 744f113..e1767c1 100644
--- a/src/app/pages/supplier/supplier.ts
+++ b/src/app/pages/supplier/supplier.ts
@@ -1,11 +1,50 @@
-import { Component } from '@angular/core';
+import {Component, inject, viewChild} from '@angular/core';
+import {ModalButton} from "../../components/modal-button/modal-button";
+import {SupplierTable} from "../../components/supplier-table/supplier-table";
+import {SupplierForm} from "../../components/supplier-form/supplier-form";
+import {SuppliersService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
@Component({
- selector: 'app-supplier',
- imports: [],
- templateUrl: './supplier.html',
- styleUrl: './supplier.css',
+ selector: 'app-supplier',
+ imports: [
+ SupplierForm,
+ SupplierTable,
+ ModalButton
+ ],
+ templateUrl: './supplier.html',
+ styleUrl: './supplier.css',
})
export class Supplier {
+ modal = viewChild.required('modalButton');
+ createSupplier = viewChild.required('supplierForm');
+ supplierTable = viewChild.required('supplierTable');
+ private suppliersService = inject(SuppliersService);
+ private notificationService = inject(NzNotificationService)
+ async onModalOk() {
+ await this.addSupplier()
+ this.createSupplier().supplierForm.reset();
+ this.onModalCancel();
+ await this.supplierTable().fetchSuppliers()
+ }
+
+ onModalCancel() {
+ this.modal().isVisible = false;
+ }
+
+ async addSupplier() {
+ if (this.createSupplier().supplierForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ }
+ try {
+ const suppliers = this.createSupplier().supplierForm.getRawValue();
+ await firstValueFrom(this.suppliersService.createSupplierEndpoint(suppliers))
+
+ this.notificationService.success('Success', 'Fournisseur enregistré')
+ } catch {
+ this.notificationService.error('Erreur', 'Erreur d\'enregistrement')
+ }
+ }
}
diff --git a/src/app/pages/user/user.html b/src/app/pages/user/user.html
index d039bb7..5351683 100644
--- a/src/app/pages/user/user.html
+++ b/src/app/pages/user/user.html
@@ -1 +1,25 @@
-user works!
+
+
+
+
+
+
Consignes du mot de passe :
+
+ - 12 caractères
+ - Au moins une majuscule
+ - Au moins une minuscule
+ - Au moins un chiffre
+ - Au moins un caractère spécial
+
+
+
+
+
+
diff --git a/src/app/pages/user/user.ts b/src/app/pages/user/user.ts
index ad839b1..6f5d9bd 100644
--- a/src/app/pages/user/user.ts
+++ b/src/app/pages/user/user.ts
@@ -1,11 +1,52 @@
-import { Component } from '@angular/core';
+import {Component, inject, viewChild} from '@angular/core';
+import {UserTable} from "../../components/user-table/user-table";
+import {ModalButton} from "../../components/modal-button/modal-button";
+import {ProfilForm} from "../../components/profil-form/profil-form";
+import {UsersService} from "../../services/api";
+import {NzNotificationService} from "ng-zorro-antd/notification";
+import {firstValueFrom} from "rxjs";
@Component({
- selector: 'app-user',
- imports: [],
- templateUrl: './user.html',
- styleUrl: './user.css',
+ selector: 'app-user',
+ imports: [
+ UserTable,
+ ModalButton,
+ ProfilForm,
+ ],
+ templateUrl: './user.html',
+ styleUrl: './user.css',
})
export class User {
+ modal = viewChild.required('modalButton');
+ createUser = viewChild.required('profilForm');
+ usersTable = viewChild.required('userTable');
+ private usersService = inject(UsersService);
+ private notificationService = inject(NzNotificationService)
+
+ async onModalOk() {
+ await this.addUser()
+ this.createUser().profilForm.reset();
+ this.onModalCancel();
+ await this.usersTable().fetchUsers()
+ }
+
+ onModalCancel() {
+ this.modal().isVisible = false;
+ }
+
+ async addUser() {
+ if (this.createUser().profilForm.invalid) {
+ this.notificationService.error('Erreur', 'Formulaire invalide')
+ }
+ try {
+ const users = this.createUser().profilForm.getRawValue();
+ await firstValueFrom(this.usersService.createUserEndpoint(users))
+
+ this.notificationService.success('Success', 'Utilisateur crée')
+ } catch {
+ this.notificationService.error('Erreur', 'Email ou mot de passe invalide')
+ }
+ }
}
+
diff --git a/src/app/pages/welcome/welcome.html b/src/app/pages/welcome/welcome.html
deleted file mode 100644
index 608dfe6..0000000
--- a/src/app/pages/welcome/welcome.html
+++ /dev/null
@@ -1 +0,0 @@
-welcome works!
\ No newline at end of file
diff --git a/src/app/pages/welcome/welcome.routes.ts b/src/app/pages/welcome/welcome.routes.ts
deleted file mode 100644
index b1857b5..0000000
--- a/src/app/pages/welcome/welcome.routes.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Routes } from '@angular/router';
-import { Welcome } from './welcome';
-
-export const WELCOME_ROUTES: Routes = [
- { path: '', component: Welcome },
-];
diff --git a/src/app/pages/welcome/welcome.ts b/src/app/pages/welcome/welcome.ts
deleted file mode 100644
index 92e8bde..0000000
--- a/src/app/pages/welcome/welcome.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'app-welcome',
- imports: [],
- templateUrl: './welcome.html',
- styleUrl: './welcome.css'
-})
-export class Welcome {}
diff --git a/src/app/services/api/.gitignore b/src/app/services/api/.gitignore
new file mode 100644
index 0000000..149b576
--- /dev/null
+++ b/src/app/services/api/.gitignore
@@ -0,0 +1,4 @@
+wwwroot/*.js
+node_modules
+typings
+dist
diff --git a/src/app/services/api/.openapi-generator-ignore b/src/app/services/api/.openapi-generator-ignore
new file mode 100644
index 0000000..7484ee5
--- /dev/null
+++ b/src/app/services/api/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/src/app/services/api/.openapi-generator/FILES b/src/app/services/api/.openapi-generator/FILES
new file mode 100644
index 0000000..05530ea
--- /dev/null
+++ b/src/app/services/api/.openapi-generator/FILES
@@ -0,0 +1,76 @@
+.gitignore
+.openapi-generator-ignore
+README.md
+api.base.service.ts
+api.module.ts
+api/api.ts
+api/customers.service.ts
+api/deliverers.service.ts
+api/deliverynotes.service.ts
+api/prices.service.ts
+api/products.service.ts
+api/purchaseorders.service.ts
+api/quotations.service.ts
+api/refresh.service.ts
+api/settings.service.ts
+api/suppliers.service.ts
+api/user.service.ts
+api/users.service.ts
+api/warehouseproducts.service.ts
+api/warehouses.service.ts
+configuration.ts
+encoder.ts
+git_push.sh
+index.ts
+model/add-quotation-product-dto.ts
+model/connect-user-dto.ts
+model/create-deliverer-dto.ts
+model/create-delivery-note-dto.ts
+model/create-price-dto.ts
+model/create-product-quotation-dto.ts
+model/create-purchase-order-dto.ts
+model/create-purchase-order-product-dto.ts
+model/create-purchase-product-dto.ts
+model/create-quotation-dto.ts
+model/create-supplier-dto.ts
+model/create-user-dto.ts
+model/get-customer-dto.ts
+model/get-deliverer-dto.ts
+model/get-delivery-note-dto.ts
+model/get-price-dto.ts
+model/get-product-delivery-dto.ts
+model/get-product-dto.ts
+model/get-purchase-order-dto.ts
+model/get-purchase-product-dto.ts
+model/get-quotation-dto.ts
+model/get-quotation-product-dto.ts
+model/get-refresh-token-dto.ts
+model/get-setting-dto.ts
+model/get-supplier-dto.ts
+model/get-token-dto.ts
+model/get-total-quantity-dto.ts
+model/get-user-dto.ts
+model/get-ware-house-dto.ts
+model/get-ware-house-product-dto.ts
+model/models.ts
+model/patch-delivery-note-real-delivery-date-dto.ts
+model/patch-price-selling-price-dto.ts
+model/patch-product-minimal-stock-dto.ts
+model/patch-purchase-order-purchase-conditions-dto.ts
+model/patch-purchase-product-quantity-dto.ts
+model/patch-quotation-conditions-sale-dto.ts
+model/patch-quotation-message-dto.ts
+model/patch-quotation-product-quantity-dto.ts
+model/patch-supplier-delivery-delay-dto.ts
+model/patch-user-password-dto.ts
+model/patch-ware-house-product-quantity-dto.ts
+model/refresh-token-dto.ts
+model/update-deliverer-dto.ts
+model/update-delivery-note-dto.ts
+model/update-product-dto.ts
+model/update-quotation-dto.ts
+model/update-supplier-dto.ts
+model/update-user-dto.ts
+param.ts
+provide-api.ts
+variables.ts
diff --git a/src/app/services/api/.openapi-generator/VERSION b/src/app/services/api/.openapi-generator/VERSION
new file mode 100644
index 0000000..6328c54
--- /dev/null
+++ b/src/app/services/api/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.17.0
diff --git a/src/app/services/api/README.md b/src/app/services/api/README.md
new file mode 100644
index 0000000..c2ba935
--- /dev/null
+++ b/src/app/services/api/README.md
@@ -0,0 +1,185 @@
+# @
+
+No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+
+The version of the OpenAPI document: 1.0.0
+
+## Building
+
+To install the required dependencies and to build the typescript sources run:
+
+```console
+npm install
+npm run build
+```
+
+## Publishing
+
+First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!)
+
+## Consuming
+
+Navigate to the folder of your consuming project and run one of next commands.
+
+_published:_
+
+```console
+npm install @ --save
+```
+
+_without publishing (not recommended):_
+
+```console
+npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save
+```
+
+_It's important to take the tgz file, otherwise you'll get trouble with links on windows_
+
+_using `npm link`:_
+
+In PATH_TO_GENERATED_PACKAGE/dist:
+
+```console
+npm link
+```
+
+In your project:
+
+```console
+npm link
+```
+
+__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages.
+Please refer to this issue for a solution / workaround.
+Published packages are not effected by this issue.
+
+### General usage
+
+In your Angular project:
+
+```typescript
+
+import { ApplicationConfig } from '@angular/core';
+import { provideHttpClient } from '@angular/common/http';
+import { provideApi } from '';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ // ...
+ provideHttpClient(),
+ provideApi()
+ ],
+};
+```
+
+**NOTE**
+If you're still using `AppModule` and haven't [migrated](https://angular.dev/reference/migrations/standalone) yet, you can still import an Angular module:
+```typescript
+import { ApiModule } from '';
+```
+
+If different from the generated base path, during app bootstrap, you can provide the base path to your service.
+
+```typescript
+import { ApplicationConfig } from '@angular/core';
+import { provideHttpClient } from '@angular/common/http';
+import { provideApi } from '';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ // ...
+ provideHttpClient(),
+ provideApi('http://localhost:9999')
+ ],
+};
+```
+
+```typescript
+// with a custom configuration
+import { ApplicationConfig } from '@angular/core';
+import { provideHttpClient } from '@angular/common/http';
+import { provideApi } from '';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ // ...
+ provideHttpClient(),
+ provideApi({
+ withCredentials: true,
+ username: 'user',
+ password: 'password'
+ })
+ ],
+};
+```
+
+```typescript
+// with factory building a custom configuration
+import { ApplicationConfig } from '@angular/core';
+import { provideHttpClient } from '@angular/common/http';
+import { provideApi, Configuration } from '';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ // ...
+ provideHttpClient(),
+ {
+ provide: Configuration,
+ useFactory: (authService: AuthService) => new Configuration({
+ basePath: 'http://localhost:9999',
+ withCredentials: true,
+ username: authService.getUsername(),
+ password: authService.getPassword(),
+ }),
+ deps: [AuthService],
+ multi: false
+ }
+ ],
+};
+```
+
+### Using multiple OpenAPI files / APIs
+
+In order to use multiple APIs generated from different OpenAPI files,
+you can create an alias name when importing the modules
+in order to avoid naming conflicts:
+
+```typescript
+import { provideApi as provideUserApi } from 'my-user-api-path';
+import { provideApi as provideAdminApi } from 'my-admin-api-path';
+import { HttpClientModule } from '@angular/common/http';
+import { environment } from '../environments/environment';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ // ...
+ provideHttpClient(),
+ provideUserApi(environment.basePath),
+ provideAdminApi(environment.basePath),
+ ],
+};
+```
+
+### Customizing path parameter encoding
+
+Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple'
+and Dates for format 'date-time' are encoded correctly.
+
+Other styles (e.g. "matrix") are not that easy to encode
+and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]).
+
+To implement your own parameter encoding (or call another library),
+pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object
+(see [General Usage](#general-usage) above).
+
+Example value for use in your Configuration-Provider:
+
+```typescript
+new Configuration({
+ encodeParam: (param: Param) => myFancyParamEncoder(param),
+})
+```
+
+[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations
+[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values
+[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander
diff --git a/src/app/services/api/api.base.service.ts b/src/app/services/api/api.base.service.ts
new file mode 100644
index 0000000..1e0f210
--- /dev/null
+++ b/src/app/services/api/api.base.service.ts
@@ -0,0 +1,83 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http';
+import { CustomHttpParameterCodec } from './encoder';
+import { Configuration } from './configuration';
+
+export class BaseService {
+ protected basePath = 'http://localhost:5298';
+ public defaultHeaders = new HttpHeaders();
+ public configuration: Configuration;
+ public encoder: HttpParameterCodec;
+
+ constructor(basePath?: string|string[], configuration?: Configuration) {
+ this.configuration = configuration || new Configuration();
+ if (typeof this.configuration.basePath !== 'string') {
+ const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
+ if (firstBasePath != undefined) {
+ basePath = firstBasePath;
+ }
+
+ if (typeof basePath !== 'string') {
+ basePath = this.basePath;
+ }
+ this.configuration.basePath = basePath;
+ }
+ this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
+ }
+
+ protected canConsumeForm(consumes: string[]): boolean {
+ return consumes.indexOf('multipart/form-data') !== -1;
+ }
+
+ protected addToHttpParams(httpParams: HttpParams, value: any, key?: string, isDeep: boolean = false): HttpParams {
+ // If the value is an object (but not a Date), recursively add its keys.
+ if (typeof value === 'object' && !(value instanceof Date)) {
+ return this.addToHttpParamsRecursive(httpParams, value, isDeep ? key : undefined, isDeep);
+ }
+ return this.addToHttpParamsRecursive(httpParams, value, key);
+ }
+
+ protected addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string, isDeep: boolean = false): HttpParams {
+ if (value === null || value === undefined) {
+ return httpParams;
+ }
+ if (typeof value === 'object') {
+ // If JSON format is preferred, key must be provided.
+ if (key != null) {
+ return isDeep
+ ? Object.keys(value as Record).reduce(
+ (hp, k) => hp.append(`${key}[${k}]`, value[k]),
+ httpParams,
+ )
+ : httpParams.append(key, JSON.stringify(value));
+ }
+ // Otherwise, if it's an array, add each element.
+ if (Array.isArray(value)) {
+ value.forEach(elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+ } else if (value instanceof Date) {
+ if (key != null) {
+ httpParams = httpParams.append(key, value.toISOString());
+ } else {
+ throw Error("key may not be null if value is Date");
+ }
+ } else {
+ Object.keys(value).forEach(k => {
+ const paramKey = key ? `${key}.${k}` : k;
+ httpParams = this.addToHttpParamsRecursive(httpParams, value[k], paramKey);
+ });
+ }
+ return httpParams;
+ } else if (key != null) {
+ return httpParams.append(key, value);
+ }
+ throw Error("key may not be null if value is not object or array");
+ }
+}
diff --git a/src/app/services/api/api.module.ts b/src/app/services/api/api.module.ts
new file mode 100644
index 0000000..58d341f
--- /dev/null
+++ b/src/app/services/api/api.module.ts
@@ -0,0 +1,30 @@
+import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
+import { Configuration } from './configuration';
+import { HttpClient } from '@angular/common/http';
+
+
+@NgModule({
+ imports: [],
+ declarations: [],
+ exports: [],
+ providers: []
+})
+export class ApiModule {
+ public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders {
+ return {
+ ngModule: ApiModule,
+ providers: [ { provide: Configuration, useFactory: configurationFactory } ]
+ };
+ }
+
+ constructor( @Optional() @SkipSelf() parentModule: ApiModule,
+ @Optional() http: HttpClient) {
+ if (parentModule) {
+ throw new Error('ApiModule is already loaded. Import in your base AppModule only.');
+ }
+ if (!http) {
+ throw new Error('You need to import the HttpClientModule in your AppModule! \n' +
+ 'See also https://github.com/angular/angular/issues/20575');
+ }
+ }
+}
diff --git a/src/app/services/api/api/api.ts b/src/app/services/api/api/api.ts
new file mode 100644
index 0000000..060b5a1
--- /dev/null
+++ b/src/app/services/api/api/api.ts
@@ -0,0 +1,29 @@
+export * from './customers.service';
+import { CustomersService } from './customers.service';
+export * from './deliverers.service';
+import { DeliverersService } from './deliverers.service';
+export * from './deliverynotes.service';
+import { DeliverynotesService } from './deliverynotes.service';
+export * from './prices.service';
+import { PricesService } from './prices.service';
+export * from './products.service';
+import { ProductsService } from './products.service';
+export * from './purchaseorders.service';
+import { PurchaseordersService } from './purchaseorders.service';
+export * from './quotations.service';
+import { QuotationsService } from './quotations.service';
+export * from './refresh.service';
+import { RefreshService } from './refresh.service';
+export * from './settings.service';
+import { SettingsService } from './settings.service';
+export * from './suppliers.service';
+import { SuppliersService } from './suppliers.service';
+export * from './user.service';
+import { UserService } from './user.service';
+export * from './users.service';
+import { UsersService } from './users.service';
+export * from './warehouseproducts.service';
+import { WarehouseproductsService } from './warehouseproducts.service';
+export * from './warehouses.service';
+import { WarehousesService } from './warehouses.service';
+export const APIS = [CustomersService, DeliverersService, DeliverynotesService, PricesService, ProductsService, PurchaseordersService, QuotationsService, RefreshService, SettingsService, SuppliersService, UserService, UsersService, WarehouseproductsService, WarehousesService];
diff --git a/src/app/services/api/api/customers.service.ts b/src/app/services/api/api/customers.service.ts
new file mode 100644
index 0000000..53415ce
--- /dev/null
+++ b/src/app/services/api/api/customers.service.ts
@@ -0,0 +1,91 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { GetCustomerDto } from '../model/get-customer-dto';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+import { BaseService } from '../api.base.service';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CustomersService extends BaseService {
+
+ constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) {
+ super(basePath, configuration);
+ }
+
+ /**
+ * @endpoint get /API/customers
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllCustomersEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllCustomersEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllCustomersEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllCustomersEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/customers`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+}
diff --git a/src/app/services/api/api/deliverers.service.ts b/src/app/services/api/api/deliverers.service.ts
new file mode 100644
index 0000000..7810c10
--- /dev/null
+++ b/src/app/services/api/api/deliverers.service.ts
@@ -0,0 +1,346 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { CreateDelivererDto } from '../model/create-deliverer-dto';
+// @ts-ignore
+import { GetDelivererDto } from '../model/get-deliverer-dto';
+// @ts-ignore
+import { UpdateDelivererDto } from '../model/update-deliverer-dto';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+import { BaseService } from '../api.base.service';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class DeliverersService extends BaseService {
+
+ constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) {
+ super(basePath, configuration);
+ }
+
+ /**
+ * @endpoint post /API/deliverers
+ * @param createDelivererDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public createDelivererEndpoint(createDelivererDto: CreateDelivererDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public createDelivererEndpoint(createDelivererDto: CreateDelivererDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createDelivererEndpoint(createDelivererDto: CreateDelivererDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createDelivererEndpoint(createDelivererDto: CreateDelivererDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (createDelivererDto === null || createDelivererDto === undefined) {
+ throw new Error('Required parameter createDelivererDto was null or undefined when calling createDelivererEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliverers`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('post', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: createDelivererDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint delete /API/deliverers/{delivererId}
+ * @param delivererId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public deleteDelivererEndpoint(delivererId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public deleteDelivererEndpoint(delivererId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteDelivererEndpoint(delivererId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteDelivererEndpoint(delivererId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (delivererId === null || delivererId === undefined) {
+ throw new Error('Required parameter delivererId was null or undefined when calling deleteDelivererEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliverers/${this.configuration.encodeParam({name: "delivererId", value: delivererId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('delete', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliverers
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllDelivererEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllDelivererEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDelivererEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDelivererEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliverers`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliverers/{delivererId}
+ * @param delivererId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getDelivererEndpoint(delivererId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getDelivererEndpoint(delivererId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDelivererEndpoint(delivererId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDelivererEndpoint(delivererId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (delivererId === null || delivererId === undefined) {
+ throw new Error('Required parameter delivererId was null or undefined when calling getDelivererEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliverers/${this.configuration.encodeParam({name: "delivererId", value: delivererId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint put /API/deliverers/{id}
+ * @param id
+ * @param updateDelivererDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public updateDelivererEndpoint(id: number, updateDelivererDto: UpdateDelivererDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public updateDelivererEndpoint(id: number, updateDelivererDto: UpdateDelivererDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateDelivererEndpoint(id: number, updateDelivererDto: UpdateDelivererDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateDelivererEndpoint(id: number, updateDelivererDto: UpdateDelivererDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling updateDelivererEndpoint.');
+ }
+ if (updateDelivererDto === null || updateDelivererDto === undefined) {
+ throw new Error('Required parameter updateDelivererDto was null or undefined when calling updateDelivererEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliverers/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('put', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: updateDelivererDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+}
diff --git a/src/app/services/api/api/deliverynotes.service.ts b/src/app/services/api/api/deliverynotes.service.ts
new file mode 100644
index 0000000..811e64c
--- /dev/null
+++ b/src/app/services/api/api/deliverynotes.service.ts
@@ -0,0 +1,515 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { CreateDeliveryNoteDto } from '../model/create-delivery-note-dto';
+// @ts-ignore
+import { GetDeliveryNoteDto } from '../model/get-delivery-note-dto';
+// @ts-ignore
+import { PatchDeliveryNoteRealDeliveryDateDto } from '../model/patch-delivery-note-real-delivery-date-dto';
+// @ts-ignore
+import { UpdateDeliveryNoteDto } from '../model/update-delivery-note-dto';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+import { BaseService } from '../api.base.service';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class DeliverynotesService extends BaseService {
+
+ constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) {
+ super(basePath, configuration);
+ }
+
+ /**
+ * @endpoint post /API/deliveryNotes
+ * @param createDeliveryNoteDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public createDeliveryNoteEndpoint(createDeliveryNoteDto: CreateDeliveryNoteDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public createDeliveryNoteEndpoint(createDeliveryNoteDto: CreateDeliveryNoteDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createDeliveryNoteEndpoint(createDeliveryNoteDto: CreateDeliveryNoteDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createDeliveryNoteEndpoint(createDeliveryNoteDto: CreateDeliveryNoteDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (createDeliveryNoteDto === null || createDeliveryNoteDto === undefined) {
+ throw new Error('Required parameter createDeliveryNoteDto was null or undefined when calling createDeliveryNoteEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('post', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: createDeliveryNoteDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint delete /API/deliveryNotes/{id}
+ * @param id
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public deleteDeliveryNoteEndpoint(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public deleteDeliveryNoteEndpoint(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteDeliveryNoteEndpoint(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteDeliveryNoteEndpoint(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling deleteDeliveryNoteEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('delete', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliveryNotes
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllDeliveryNoteEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllDeliveryNoteEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDeliveryNoteEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDeliveryNoteEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliveryNotes/validation
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllDeliveryNotesNotArrivedEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllDeliveryNotesNotArrivedEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDeliveryNotesNotArrivedEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllDeliveryNotesNotArrivedEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes/validation`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliveryNotes/{deliveryNoteId}
+ * @param deliveryNoteId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getDeliveryNoteEndpoint(deliveryNoteId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getDeliveryNoteEndpoint(deliveryNoteId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDeliveryNoteEndpoint(deliveryNoteId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDeliveryNoteEndpoint(deliveryNoteId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (deliveryNoteId === null || deliveryNoteId === undefined) {
+ throw new Error('Required parameter deliveryNoteId was null or undefined when calling getDeliveryNoteEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes/${this.configuration.encodeParam({name: "deliveryNoteId", value: deliveryNoteId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/deliveryNotes/{id}/pdf
+ * @param id
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getDeliveryNotePdfEndpoint(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/pdf', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getDeliveryNotePdfEndpoint(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/pdf', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDeliveryNotePdfEndpoint(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/pdf', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getDeliveryNotePdfEndpoint(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/pdf', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling getDeliveryNotePdfEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/pdf'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let localVarPath = `/API/deliveryNotes/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}/pdf`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: "blob",
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint patch /API/deliveryNotes/{id}
+ * @param id
+ * @param patchDeliveryNoteRealDeliveryDateDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public patchRealDeliveryDateEndpoint(id: number, patchDeliveryNoteRealDeliveryDateDto: PatchDeliveryNoteRealDeliveryDateDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public patchRealDeliveryDateEndpoint(id: number, patchDeliveryNoteRealDeliveryDateDto: PatchDeliveryNoteRealDeliveryDateDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchRealDeliveryDateEndpoint(id: number, patchDeliveryNoteRealDeliveryDateDto: PatchDeliveryNoteRealDeliveryDateDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchRealDeliveryDateEndpoint(id: number, patchDeliveryNoteRealDeliveryDateDto: PatchDeliveryNoteRealDeliveryDateDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling patchRealDeliveryDateEndpoint.');
+ }
+ if (patchDeliveryNoteRealDeliveryDateDto === null || patchDeliveryNoteRealDeliveryDateDto === undefined) {
+ throw new Error('Required parameter patchDeliveryNoteRealDeliveryDateDto was null or undefined when calling patchRealDeliveryDateEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('patch', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: patchDeliveryNoteRealDeliveryDateDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint put /API/deliveryNotes/{id}
+ * @param id
+ * @param updateDeliveryNoteDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public updateDeliveryNoteEndpoint(id: number, updateDeliveryNoteDto: UpdateDeliveryNoteDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public updateDeliveryNoteEndpoint(id: number, updateDeliveryNoteDto: UpdateDeliveryNoteDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateDeliveryNoteEndpoint(id: number, updateDeliveryNoteDto: UpdateDeliveryNoteDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateDeliveryNoteEndpoint(id: number, updateDeliveryNoteDto: UpdateDeliveryNoteDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling updateDeliveryNoteEndpoint.');
+ }
+ if (updateDeliveryNoteDto === null || updateDeliveryNoteDto === undefined) {
+ throw new Error('Required parameter updateDeliveryNoteDto was null or undefined when calling updateDeliveryNoteEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/deliveryNotes/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('put', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: updateDeliveryNoteDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+}
diff --git a/src/app/services/api/api/prices.service.ts b/src/app/services/api/api/prices.service.ts
new file mode 100644
index 0000000..dd9463a
--- /dev/null
+++ b/src/app/services/api/api/prices.service.ts
@@ -0,0 +1,112 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { PatchPriceSellingPriceDto } from '../model/patch-price-selling-price-dto';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+import { BaseService } from '../api.base.service';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PricesService extends BaseService {
+
+ constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) {
+ super(basePath, configuration);
+ }
+
+ /**
+ * @endpoint patch /API/prices/{productId}/{supplierId}/SellingPrice
+ * @param productId
+ * @param supplierId
+ * @param patchPriceSellingPriceDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public patchPriceEndpoint(productId: number, supplierId: number, patchPriceSellingPriceDto: PatchPriceSellingPriceDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public patchPriceEndpoint(productId: number, supplierId: number, patchPriceSellingPriceDto: PatchPriceSellingPriceDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchPriceEndpoint(productId: number, supplierId: number, patchPriceSellingPriceDto: PatchPriceSellingPriceDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchPriceEndpoint(productId: number, supplierId: number, patchPriceSellingPriceDto: PatchPriceSellingPriceDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (productId === null || productId === undefined) {
+ throw new Error('Required parameter productId was null or undefined when calling patchPriceEndpoint.');
+ }
+ if (supplierId === null || supplierId === undefined) {
+ throw new Error('Required parameter supplierId was null or undefined when calling patchPriceEndpoint.');
+ }
+ if (patchPriceSellingPriceDto === null || patchPriceSellingPriceDto === undefined) {
+ throw new Error('Required parameter patchPriceSellingPriceDto was null or undefined when calling patchPriceEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/prices/${this.configuration.encodeParam({name: "productId", value: productId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}/${this.configuration.encodeParam({name: "supplierId", value: supplierId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}/SellingPrice`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('patch', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: patchPriceSellingPriceDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+}
diff --git a/src/app/services/api/api/products.service.ts b/src/app/services/api/api/products.service.ts
new file mode 100644
index 0000000..1d7e297
--- /dev/null
+++ b/src/app/services/api/api/products.service.ts
@@ -0,0 +1,401 @@
+/**
+ * PyroFetes
+ *
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { GetProductDto } from '../model/get-product-dto';
+// @ts-ignore
+import { PatchProductMinimalStockDto } from '../model/patch-product-minimal-stock-dto';
+// @ts-ignore
+import { UpdateProductDto } from '../model/update-product-dto';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+import { BaseService } from '../api.base.service';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ProductsService extends BaseService {
+
+ constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) {
+ super(basePath, configuration);
+ }
+
+ /**
+ * @endpoint delete /API/products/{productId}
+ * @param productId
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public deleteProductEndpoint(productId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public deleteProductEndpoint(productId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteProductEndpoint(productId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public deleteProductEndpoint(productId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (productId === null || productId === undefined) {
+ throw new Error('Required parameter productId was null or undefined when calling deleteProductEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products/${this.configuration.encodeParam({name: "productId", value: productId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('delete', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/products
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllProductsEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllProductsEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllProductsEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllProductsEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/products/underLimit
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getAllProductsUnderLimitEndpoint(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getAllProductsUnderLimitEndpoint(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllProductsUnderLimitEndpoint(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getAllProductsUnderLimitEndpoint(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products/underLimit`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request>('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint get /API/products/{id}
+ * @param id
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getProductEndpoint(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getProductEndpoint(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getProductEndpoint(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getProductEndpoint(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling getProductEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ 'application/json'
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('get', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint patch /API/products/{id}/MinimalStock
+ * @param id
+ * @param patchProductMinimalStockDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public patchProductMinimalStockEndpoint(id: number, patchProductMinimalStockDto: PatchProductMinimalStockDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public patchProductMinimalStockEndpoint(id: number, patchProductMinimalStockDto: PatchProductMinimalStockDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchProductMinimalStockEndpoint(id: number, patchProductMinimalStockDto: PatchProductMinimalStockDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public patchProductMinimalStockEndpoint(id: number, patchProductMinimalStockDto: PatchProductMinimalStockDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling patchProductMinimalStockEndpoint.');
+ }
+ if (patchProductMinimalStockDto === null || patchProductMinimalStockDto === undefined) {
+ throw new Error('Required parameter patchProductMinimalStockDto was null or undefined when calling patchProductMinimalStockEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}/MinimalStock`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('patch', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: patchProductMinimalStockDto,
+ responseType: responseType_,
+ ...(withCredentials ? { withCredentials } : {}),
+ headers: localVarHeaders,
+ observe: observe,
+ ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}),
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * @endpoint put /API/products/{id}
+ * @param id
+ * @param updateProductDto
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public updateProductEndpoint(id: number, updateProductDto: UpdateProductDto, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable;
+ public updateProductEndpoint(id: number, updateProductDto: UpdateProductDto, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateProductEndpoint(id: number, updateProductDto: UpdateProductDto, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateProductEndpoint(id: number, updateProductDto: UpdateProductDto, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable {
+ if (id === null || id === undefined) {
+ throw new Error('Required parameter id was null or undefined when calling updateProductEndpoint.');
+ }
+ if (updateProductDto === null || updateProductDto === undefined) {
+ throw new Error('Required parameter updateProductDto was null or undefined when calling updateProductEndpoint.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+
+ // authentication (JWTBearerAuth) required
+ localVarHeaders = this.configuration.addCredentialToHeaders('JWTBearerAuth', 'Authorization', localVarHeaders, 'Bearer ');
+
+ const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([
+ ]);
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ const localVarHttpContext: HttpContext = options?.context ?? new HttpContext();
+
+ const localVarTransferCache: boolean = options?.transferCache ?? true;
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/API/products/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`;
+ const { basePath, withCredentials } = this.configuration;
+ return this.httpClient.request('put', `${basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: updateProductDto,
+ responseType: