project et profile => clean archi et test vert
This commit is contained in:
4
.actrc
4
.actrc
@@ -1,3 +1,3 @@
|
|||||||
--container-architecture linux/arm64
|
--container-architecture linux/amd64
|
||||||
-W .gitea/workflows
|
-W .gitea/workflows
|
||||||
-P ubuntu-latest=node:20-bullseye
|
-P ubuntu-latest==ghcr.io/catthehacker/ubuntu:act-latest
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Docker Build Check
|
name: Build Check
|
||||||
|
|
||||||
# Déclencheur pour chaque pull request
|
# Déclencheur pour chaque pull request
|
||||||
on:
|
on:
|
||||||
|
|||||||
@@ -14,5 +14,4 @@ module.exports = {
|
|||||||
'^@app/(.*)$': '<rootDir>/src/app/$1',
|
'^@app/(.*)$': '<rootDir>/src/app/$1',
|
||||||
'^@env/(.*)$': '<rootDir>/src/environments/$1',
|
'^@env/(.*)$': '<rootDir>/src/environments/$1',
|
||||||
},
|
},
|
||||||
globalSetup: 'jest-preset-angular/global-setup',
|
|
||||||
};
|
};
|
||||||
|
|||||||
386
package-lock.json
generated
386
package-lock.json
generated
@@ -46,6 +46,7 @@
|
|||||||
"@types/node-fetch": "^2.6.13",
|
"@types/node-fetch": "^2.6.13",
|
||||||
"angular-eslint": "20.4.0",
|
"angular-eslint": "20.4.0",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
|
"canvas": "^2.11.2",
|
||||||
"eslint": "^9.37.0",
|
"eslint": "^9.37.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
@@ -5268,6 +5269,103 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.0",
|
||||||
|
"https-proxy-agent": "^5.0.0",
|
||||||
|
"make-dir": "^3.1.0",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
|
"nopt": "^5.0.0",
|
||||||
|
"npmlog": "^5.0.1",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"semver": "^7.3.5",
|
||||||
|
"tar": "^6.1.11"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-pre-gyp": "bin/node-pre-gyp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/abbrev": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "6",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": "1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nopt": "bin/nopt.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ngneat/until-destroy": {
|
"node_modules/@ngneat/until-destroy": {
|
||||||
"version": "10.0.0",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ngneat/until-destroy/-/until-destroy-10.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ngneat/until-destroy/-/until-destroy-10.0.0.tgz",
|
||||||
@@ -6225,9 +6323,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/express": {
|
"node_modules/@types/express": {
|
||||||
"version": "4.17.23",
|
"version": "4.17.24",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.24.tgz",
|
||||||
"integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
|
"integrity": "sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6268,9 +6366,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/http-proxy": {
|
"node_modules/@types/http-proxy": {
|
||||||
"version": "1.17.16",
|
"version": "1.17.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz",
|
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz",
|
||||||
"integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==",
|
"integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6394,9 +6492,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/send": {
|
"node_modules/@types/send": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
|
||||||
"integrity": "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==",
|
"integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6414,9 +6512,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/serve-static": {
|
"node_modules/@types/serve-static": {
|
||||||
"version": "1.15.9",
|
"version": "1.15.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz",
|
||||||
"integrity": "sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==",
|
"integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6426,9 +6524,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/serve-static/node_modules/@types/send": {
|
"node_modules/@types/serve-static/node_modules/@types/send": {
|
||||||
"version": "0.17.5",
|
"version": "0.17.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
|
||||||
"integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
|
"integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6471,9 +6569,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/yargs": {
|
"node_modules/@types/yargs": {
|
||||||
"version": "17.0.33",
|
"version": "17.0.34",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz",
|
||||||
"integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
|
"integrity": "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8045,6 +8143,28 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/aproba": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/are-we-there-yet": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"delegates": "^1.0.0",
|
||||||
|
"readable-stream": "^3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/arg": {
|
"node_modules/arg": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||||
@@ -8720,18 +8840,19 @@
|
|||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
"node_modules/canvas": {
|
"node_modules/canvas": {
|
||||||
"version": "3.2.0",
|
"version": "2.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz",
|
||||||
"integrity": "sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==",
|
"integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==",
|
||||||
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-addon-api": "^7.0.0",
|
"@mapbox/node-pre-gyp": "^1.0.0",
|
||||||
"prebuild-install": "^7.1.3"
|
"nan": "^2.17.0",
|
||||||
|
"simple-get": "^3.0.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.12.0 || >= 20.9.0"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
@@ -8975,6 +9096,16 @@
|
|||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/color-support": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"color-support": "bin.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/colorette": {
|
"node_modules/colorette": {
|
||||||
"version": "2.0.20",
|
"version": "2.0.20",
|
||||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||||
@@ -9088,6 +9219,13 @@
|
|||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/console-control-strings": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
@@ -9487,19 +9625,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/decompress-response": {
|
"node_modules/decompress-response": {
|
||||||
"version": "6.0.0",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mimic-response": "^3.1.0"
|
"mimic-response": "^2.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=8"
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dedent": {
|
"node_modules/dedent": {
|
||||||
@@ -9608,6 +9743,13 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delegates": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
@@ -9631,8 +9773,8 @@
|
|||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
|
"devOptional": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@@ -9807,9 +9949,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.239",
|
"version": "1.5.240",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.239.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz",
|
||||||
"integrity": "sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==",
|
"integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -11057,6 +11199,28 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gauge": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"aproba": "^1.0.3 || ^2.0.0",
|
||||||
|
"color-support": "^1.1.2",
|
||||||
|
"console-control-strings": "^1.0.0",
|
||||||
|
"has-unicode": "^2.0.1",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"signal-exit": "^3.0.0",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"wide-align": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gensync": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||||
@@ -11380,6 +11544,13 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-unicode": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/hasown": {
|
"node_modules/hasown": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
@@ -14771,13 +14942,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mimic-response": {
|
"node_modules/mimic-response": {
|
||||||
"version": "3.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=8"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
@@ -15114,6 +15285,13 @@
|
|||||||
"thenify-all": "^1.0.0"
|
"thenify-all": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.23.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
|
||||||
|
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.11",
|
"version": "3.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
@@ -15602,6 +15780,20 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/npmlog": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
|
||||||
|
"deprecated": "This package is no longer supported.",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"are-we-there-yet": "^2.0.0",
|
||||||
|
"console-control-strings": "^1.1.0",
|
||||||
|
"gauge": "^3.0.0",
|
||||||
|
"set-blocking": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nth-check": {
|
"node_modules/nth-check": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||||
@@ -16121,6 +16313,21 @@
|
|||||||
"path2d": "^0.2.1"
|
"path2d": "^0.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pdfjs-dist/node_modules/canvas": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"node-addon-api": "^7.0.0",
|
||||||
|
"prebuild-install": "^7.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.12.0 || >= 20.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@@ -16593,6 +16800,61 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prebuild-install/node_modules/decompress-response": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-response": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prebuild-install/node_modules/mimic-response": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prebuild-install/node_modules/simple-get": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
||||||
|
"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",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"decompress-response": "^6.0.0",
|
||||||
|
"once": "^1.3.1",
|
||||||
|
"simple-concat": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -17978,6 +18240,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||||
|
"devOptional": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -17992,31 +18255,16 @@
|
|||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/simple-get": {
|
"node_modules/simple-get": {
|
||||||
"version": "4.0.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
|
||||||
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
|
||||||
"funding": [
|
"dev": true,
|
||||||
{
|
|
||||||
"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",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decompress-response": "^6.0.0",
|
"decompress-response": "^4.2.0",
|
||||||
"once": "^1.3.1",
|
"once": "^1.3.1",
|
||||||
"simple-concat": "^1.0.0"
|
"simple-concat": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -20552,6 +20800,16 @@
|
|||||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/wide-align": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wildcard": {
|
"node_modules/wildcard": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
"@types/node-fetch": "^2.6.13",
|
"@types/node-fetch": "^2.6.13",
|
||||||
"angular-eslint": "20.4.0",
|
"angular-eslint": "20.4.0",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
|
"canvas": "^2.11.2",
|
||||||
"eslint": "^9.37.0",
|
"eslint": "^9.37.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Router } from '@angular/router';
|
|||||||
|
|
||||||
import { detailResolver } from './detail.resolver';
|
import { detailResolver } from './detail.resolver';
|
||||||
import { User } from '@app/shared/models/user';
|
import { User } from '@app/shared/models/user';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
describe('detailResolver', () => {
|
describe('detailResolver', () => {
|
||||||
let mockRoute: Partial<Router>;
|
let mockRoute: Partial<Router>;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ResolveFn, Router } from '@angular/router';
|
import { ResolveFn, Router } from '@angular/router';
|
||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { User } from '@app/shared/models/user';
|
import { User } from '@app/shared/models/user';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
export const detailResolver: ResolveFn<{ user: User; profile: Profile }> = (route, state) => {
|
export const detailResolver: ResolveFn<{ user: User; profile: Profile }> = (route, state) => {
|
||||||
const paramValue = route.params['name'];
|
const paramValue = route.params['name'];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ResolveFn } from '@angular/router';
|
import { ResolveFn } from '@angular/router';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
export const listResolver: ResolveFn<Profile[]> = (route, state) => {
|
export const listResolver: ResolveFn<Profile[]> = (route, state) => {
|
||||||
const queryValue = route.queryParams['search'];
|
const queryValue = route.queryParams['search'];
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ProfileService } from './profile.service';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
describe('ProfileService', () => {
|
|
||||||
let service: ProfileService;
|
|
||||||
|
|
||||||
const routerSpy = {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateByUrl: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
{ provide: Router, useValue: routerSpy }, // <<— spy: neutralise la navigation
|
|
||||||
],
|
|
||||||
imports: [],
|
|
||||||
});
|
|
||||||
service = TestBed.inject(ProfileService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import PocketBase from 'pocketbase';
|
|
||||||
import { environment } from '@env/environment';
|
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { from } from 'rxjs';
|
|
||||||
import { ProfileDto } from '@app/shared/models/profile-dto';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root',
|
|
||||||
})
|
|
||||||
export class ProfileService {
|
|
||||||
createProfile(profileDto: ProfileDto) {
|
|
||||||
const pb = new PocketBase(environment.baseUrl);
|
|
||||||
return from(pb.collection('profiles').create(profileDto));
|
|
||||||
}
|
|
||||||
|
|
||||||
get profiles() {
|
|
||||||
const pb = new PocketBase(environment.baseUrl);
|
|
||||||
return from(
|
|
||||||
pb.collection('profiles').getFullList<Profile>({
|
|
||||||
sort: 'profession',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getProfileByUserId(userId: string) {
|
|
||||||
const pb = new PocketBase(environment.baseUrl);
|
|
||||||
return from(pb.collection<Profile>('profiles').getFirstListItem(`utilisateur="${userId}"`));
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProfile(id: string, data: Profile | any) {
|
|
||||||
const pb = new PocketBase(environment.baseUrl);
|
|
||||||
return from(pb.collection('profiles').update<Profile>(id, data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
|
|||||||
|
|
||||||
export interface ProfileRepository {
|
export interface ProfileRepository {
|
||||||
list(params?: { search?: string; page?: number; pageSize?: number }): Observable<Profile[]>;
|
list(params?: { search?: string; page?: number; pageSize?: number }): Observable<Profile[]>;
|
||||||
getByUserId(userId: string): Observable<Profile | null>;
|
getByUserId(userId: string): Observable<Profile>;
|
||||||
create(profile: Profile): Observable<Profile>;
|
create(profile: Profile): Observable<Profile>;
|
||||||
update(id: string, profile: Partial<Profile>): Observable<Profile>;
|
update(profileId: string, profile: Partial<Profile>): Observable<Profile>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Project } from '@app/shared/models/project';
|
|
||||||
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
||||||
|
import { Project } from '@app/domain/projects/project.model';
|
||||||
|
|
||||||
export interface ProjectRepository {
|
export interface ProjectRepository {
|
||||||
create(projectDto: CreateProjectDto): Observable<Project>;
|
create(projectDto: CreateProjectDto): Observable<Project>;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class PbProfileRepository implements ProfileRepository {
|
|||||||
return from(this.pb.collection('profiles').getFullList<Profile>({ sort: 'profession' }));
|
return from(this.pb.collection('profiles').getFullList<Profile>({ sort: 'profession' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
getByUserId(userId: string): Observable<Profile | null> {
|
getByUserId(userId: string): Observable<Profile> {
|
||||||
return from(
|
return from(
|
||||||
this.pb.collection('profiles').getFirstListItem<Profile>(`utilisateur="${userId}"`)
|
this.pb.collection('profiles').getFirstListItem<Profile>(`utilisateur="${userId}"`)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { environment } from '@env/environment';
|
import { environment } from '@env/environment';
|
||||||
import { ProjectRepository } from '@app/domain/projects/project.repository';
|
import { ProjectRepository } from '@app/domain/projects/project.repository';
|
||||||
import { Project } from '@app/shared/models/project';
|
|
||||||
import { from, Observable } from 'rxjs';
|
import { from, Observable } from 'rxjs';
|
||||||
import PocketBase from 'pocketbase';
|
import PocketBase from 'pocketbase';
|
||||||
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
||||||
|
import { Project } from '@app/domain/projects/project.model';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { HomeComponent } from './home.component';
|
import { HomeComponent } from './home.component';
|
||||||
|
import { provideRouter } from '@angular/router';
|
||||||
|
|
||||||
describe('HomeComponent', () => {
|
describe('HomeComponent', () => {
|
||||||
let component: HomeComponent;
|
let component: HomeComponent;
|
||||||
@@ -9,6 +10,7 @@ describe('HomeComponent', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [HomeComponent],
|
imports: [HomeComponent],
|
||||||
|
providers: [provideRouter([])],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(HomeComponent);
|
fixture = TestBed.createComponent(HomeComponent);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@if (profile.estVerifier) {
|
@if (profile().estVerifier) {
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -100,8 +100,8 @@
|
|||||||
</h2>
|
</h2>
|
||||||
}
|
}
|
||||||
<div class="w-12 h-1 bg-indigo-500 rounded mt-2 mb-4"></div>
|
<div class="w-12 h-1 bg-indigo-500 rounded mt-2 mb-4"></div>
|
||||||
@if (profile.bio) {
|
@if (profile().bio) {
|
||||||
<p class="text-base dark:text-white w-full">{{ profile.bio }}</p>
|
<p class="text-base dark:text-white w-full">{{ profile().bio }}</p>
|
||||||
} @else {
|
} @else {
|
||||||
<p class="text-base dark:text-white w-full">
|
<p class="text-base dark:text-white w-full">
|
||||||
Je suis sur la plateforme Trouve Ton Profile pour partager mon expertise et mes
|
Je suis sur la plateforme Trouve Ton Profile pour partager mon expertise et mes
|
||||||
@@ -110,17 +110,17 @@
|
|||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (profile.secteur) {
|
@if (profile().secteur) {
|
||||||
<div class="space-y-2 flex flex-col my-4">
|
<div class="space-y-2 flex flex-col my-4">
|
||||||
<p class="text-base dark:text-white">Secteur</p>
|
<p class="text-base dark:text-white">Secteur</p>
|
||||||
<app-chips [sectorId]="profile.secteur" />
|
<app-chips [sectorId]="profile().secteur" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (profile.reseaux) {
|
@if (profile().reseaux) {
|
||||||
<div class="space-y-2 flex flex-col my-4">
|
<div class="space-y-2 flex flex-col my-4">
|
||||||
<p class="text-base dark:text-white">Réseaux</p>
|
<p class="text-base dark:text-white">Réseaux</p>
|
||||||
<app-reseaux [reseaux]="profile.reseaux" />
|
<app-reseaux [reseaux]="profile().reseaux" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -240,23 +240,23 @@
|
|||||||
<div id="homeContent" class="tab-content max-w-2xl block mt-8">
|
<div id="homeContent" class="tab-content max-w-2xl block mt-8">
|
||||||
@switch (menu().toLowerCase()) {
|
@switch (menu().toLowerCase()) {
|
||||||
@case ('home'.toLowerCase()) {
|
@case ('home'.toLowerCase()) {
|
||||||
<app-my-home-profile [profile]="profile" />
|
<app-my-home-profile [profile]="profile()" />
|
||||||
}
|
}
|
||||||
@case ('projects'.toLowerCase()) {
|
@case ('projects'.toLowerCase()) {
|
||||||
<app-my-profile-project-list
|
<app-my-profile-project-list
|
||||||
[projectIds]="profile.projets"
|
[projectIds]="profile().projets"
|
||||||
[userId]="user().id"
|
[userId]="user().id"
|
||||||
/>
|
/>
|
||||||
<router-outlet />
|
<router-outlet />
|
||||||
}
|
}
|
||||||
@case ('update'.toLowerCase()) {
|
@case ('update'.toLowerCase()) {
|
||||||
<app-my-profile-update-form [profile]="profile" />
|
<app-my-profile-update-form [profile]="profile()" />
|
||||||
}
|
}
|
||||||
@case ('cv'.toLowerCase()) {
|
@case ('cv'.toLowerCase()) {
|
||||||
<app-pdf-viewer [profile]="profile" />
|
<app-pdf-viewer [profile]="profile()" />
|
||||||
}
|
}
|
||||||
@default {
|
@default {
|
||||||
<app-my-home-profile [profile]="profile" />
|
<app-my-home-profile [profile]="profile()" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,15 +2,30 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
|
|
||||||
import { MyProfileComponent } from './my-profile.component';
|
import { MyProfileComponent } from './my-profile.component';
|
||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
describe('MyProfileComponent', () => {
|
describe('MyProfileComponent', () => {
|
||||||
let component: MyProfileComponent;
|
let component: MyProfileComponent;
|
||||||
let fixture: ComponentFixture<MyProfileComponent>;
|
let fixture: ComponentFixture<MyProfileComponent>;
|
||||||
|
|
||||||
|
let mockProfileRepo: ProfileRepository;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockProfileRepo = {
|
||||||
|
create: jest.fn(),
|
||||||
|
list: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
getByUserId: jest.fn().mockReturnValue(of({} as Profile)),
|
||||||
|
};
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [MyProfileComponent],
|
imports: [MyProfileComponent],
|
||||||
providers: [provideRouter([])],
|
providers: [
|
||||||
|
provideRouter([]),
|
||||||
|
{ provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
|
||||||
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(MyProfileComponent);
|
fixture = TestBed.createComponent(MyProfileComponent);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, computed, inject, OnInit, signal } from '@angular/core';
|
import { Component, computed, inject, OnInit, signal } from '@angular/core';
|
||||||
import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';
|
import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';
|
||||||
import { User } from '@app/shared/models/user';
|
import { User } from '@app/shared/models/user';
|
||||||
import { AsyncPipe, JsonPipe, Location, NgClass, UpperCasePipe } from '@angular/common';
|
import { Location, NgClass } from '@angular/common';
|
||||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||||
import { SafeUrl } from '@angular/platform-browser';
|
import { SafeUrl } from '@angular/platform-browser';
|
||||||
import { QRCodeModule } from 'angularx-qrcode';
|
import { QRCodeModule } from 'angularx-qrcode';
|
||||||
@@ -12,22 +12,18 @@ import { UpdateUserComponent } from '@app/shared/features/update-user/update-use
|
|||||||
import { MyProfileProjectListComponent } from '@app/shared/components/my-profile-project-list/my-profile-project-list.component';
|
import { MyProfileProjectListComponent } from '@app/shared/components/my-profile-project-list/my-profile-project-list.component';
|
||||||
import { MyHomeProfileComponent } from '@app/shared/components/my-home-profile/my-home-profile.component';
|
import { MyHomeProfileComponent } from '@app/shared/components/my-home-profile/my-home-profile.component';
|
||||||
import { MyProfileUpdateFormComponent } from '@app/shared/components/my-profile-update-form/my-profile-update-form.component';
|
import { MyProfileUpdateFormComponent } from '@app/shared/components/my-profile-update-form/my-profile-update-form.component';
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { PdfViewerComponent } from '@app/shared/features/pdf-viewer/pdf-viewer.component';
|
import { PdfViewerComponent } from '@app/shared/features/pdf-viewer/pdf-viewer.component';
|
||||||
|
import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-my-profile',
|
selector: 'app-my-profile',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
JsonPipe,
|
|
||||||
RouterLink,
|
RouterLink,
|
||||||
AsyncPipe,
|
|
||||||
QRCodeModule,
|
QRCodeModule,
|
||||||
ChipsComponent,
|
ChipsComponent,
|
||||||
ReseauxComponent,
|
ReseauxComponent,
|
||||||
UpdateUserComponent,
|
UpdateUserComponent,
|
||||||
UpperCasePipe,
|
|
||||||
MyProfileProjectListComponent,
|
MyProfileProjectListComponent,
|
||||||
RouterOutlet,
|
RouterOutlet,
|
||||||
MyHomeProfileComponent,
|
MyHomeProfileComponent,
|
||||||
@@ -40,8 +36,6 @@ import { PdfViewerComponent } from '@app/shared/features/pdf-viewer/pdf-viewer.c
|
|||||||
})
|
})
|
||||||
@UntilDestroy()
|
@UntilDestroy()
|
||||||
export class MyProfileComponent implements OnInit {
|
export class MyProfileComponent implements OnInit {
|
||||||
private profileService = inject(ProfileService);
|
|
||||||
|
|
||||||
protected readonly environment = environment;
|
protected readonly environment = environment;
|
||||||
protected menu = signal<string>('home');
|
protected menu = signal<string>('home');
|
||||||
|
|
||||||
@@ -58,8 +52,6 @@ export class MyProfileComponent implements OnInit {
|
|||||||
return {} as User;
|
return {} as User;
|
||||||
});
|
});
|
||||||
|
|
||||||
protected profile: Profile = {} as Profile;
|
|
||||||
|
|
||||||
protected isEditMode = signal<boolean>(false);
|
protected isEditMode = signal<boolean>(false);
|
||||||
|
|
||||||
onChangeURL(url: SafeUrl) {
|
onChangeURL(url: SafeUrl) {
|
||||||
@@ -70,13 +62,13 @@ export class MyProfileComponent implements OnInit {
|
|||||||
this.isEditMode.set(!$event);
|
this.isEditMode.set(!$event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly profileFacade = new ProfileFacade();
|
||||||
|
protected profile = this.profileFacade.profile;
|
||||||
|
protected readonly loading = this.profileFacade.loading;
|
||||||
|
protected readonly error = this.profileFacade.error;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.myProfileQrCode = `${this.myProfileQrCode}/profiles/${this.user().id}`;
|
this.myProfileQrCode = `${this.myProfileQrCode}/profiles/${this.user().id}`;
|
||||||
|
this.profileFacade.loadOne(this.user().id);
|
||||||
this.profileService.getProfileByUserId(this.user().id).subscribe({
|
|
||||||
next: (value: Profile) => {
|
|
||||||
this.profile = value;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { ActivatedRoute, RouterLink } from '@angular/router';
|
|||||||
import { QRCodeModule } from 'angularx-qrcode';
|
import { QRCodeModule } from 'angularx-qrcode';
|
||||||
import { UpperCasePipe } from '@angular/common';
|
import { UpperCasePipe } from '@angular/common';
|
||||||
import { User } from '@app/shared/models/user';
|
import { User } from '@app/shared/models/user';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { ChipsComponent } from '@app/shared/components/chips/chips.component';
|
import { ChipsComponent } from '@app/shared/components/chips/chips.component';
|
||||||
import { ReseauxComponent } from '@app/shared/components/reseaux/reseaux.component';
|
import { ReseauxComponent } from '@app/shared/components/reseaux/reseaux.component';
|
||||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||||
import { ProjectListComponent } from '@app/shared/components/project-list/project-list.component';
|
import { ProjectListComponent } from '@app/shared/components/project-list/project-list.component';
|
||||||
import { environment } from '@env/environment';
|
import { environment } from '@env/environment';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-profile-detail',
|
selector: 'app-profile-detail',
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { AsyncPipe, JsonPipe, UpperCasePipe } from '@angular/common';
|
import { UpperCasePipe } from '@angular/common';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||||
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-my-home-profile',
|
selector: 'app-my-home-profile',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [UpperCasePipe, AsyncPipe, JsonPipe],
|
imports: [UpperCasePipe],
|
||||||
templateUrl: './my-home-profile.component.html',
|
templateUrl: './my-home-profile.component.html',
|
||||||
styleUrl: './my-home-profile.component.scss',
|
styleUrl: './my-home-profile.component.scss',
|
||||||
})
|
})
|
||||||
@UntilDestroy()
|
@UntilDestroy()
|
||||||
export class MyHomeProfileComponent {
|
export class MyHomeProfileComponent {
|
||||||
@Input({ required: true }) profile: Profile | undefined = undefined;
|
@Input({ required: true }) profile: ProfileViewModel | undefined = undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,22 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
|
|
||||||
import { MyProfileUpdateCvFormComponent } from './my-profile-update-cv-form.component';
|
import { MyProfileUpdateCvFormComponent } from './my-profile-update-cv-form.component';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||||
import { signal } from '@angular/core';
|
import { signal } from '@angular/core';
|
||||||
import { Auth } from '@app/shared/models/auth';
|
import { Auth } from '@app/shared/models/auth';
|
||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
|
|
||||||
describe('MyProfileUpdateCvFormComponent', () => {
|
describe('MyProfileUpdateCvFormComponent', () => {
|
||||||
let component: MyProfileUpdateCvFormComponent;
|
let component: MyProfileUpdateCvFormComponent;
|
||||||
let fixture: ComponentFixture<MyProfileUpdateCvFormComponent>;
|
let fixture: ComponentFixture<MyProfileUpdateCvFormComponent>;
|
||||||
|
|
||||||
let mockToastrService: Partial<ToastrService>;
|
let mockToastrService: Partial<ToastrService>;
|
||||||
let mockProfileService: Partial<ProfileService>;
|
|
||||||
let mockAuthService: Partial<AuthService>;
|
let mockAuthService: Partial<AuthService>;
|
||||||
|
let mockProfileRepo: ProfileRepository;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockToastrService = {
|
mockToastrService = {
|
||||||
@@ -23,10 +26,11 @@ describe('MyProfileUpdateCvFormComponent', () => {
|
|||||||
warning: jest.fn(),
|
warning: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
mockProfileService = {
|
mockProfileRepo = {
|
||||||
updateProfile: jest.fn().mockReturnValue({
|
create: jest.fn(),
|
||||||
subscribe: jest.fn(),
|
list: jest.fn(),
|
||||||
}),
|
update: jest.fn().mockReturnValue(of({} as Profile)),
|
||||||
|
getByUserId: jest.fn().mockReturnValue(of({} as Profile)),
|
||||||
};
|
};
|
||||||
|
|
||||||
mockAuthService = {
|
mockAuthService = {
|
||||||
@@ -38,8 +42,8 @@ describe('MyProfileUpdateCvFormComponent', () => {
|
|||||||
imports: [MyProfileUpdateCvFormComponent],
|
imports: [MyProfileUpdateCvFormComponent],
|
||||||
providers: [
|
providers: [
|
||||||
provideRouter([]),
|
provideRouter([]),
|
||||||
|
{ provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
|
||||||
{ provide: ToastrService, useValue: mockToastrService },
|
{ provide: ToastrService, useValue: mockToastrService },
|
||||||
{ provide: ProfileService, useValue: mockProfileService },
|
|
||||||
{ provide: AuthService, useValue: mockAuthService },
|
{ provide: AuthService, useValue: mockAuthService },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -47,6 +51,8 @@ describe('MyProfileUpdateCvFormComponent', () => {
|
|||||||
fixture = TestBed.createComponent(MyProfileUpdateCvFormComponent);
|
fixture = TestBed.createComponent(MyProfileUpdateCvFormComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
await fixture.whenStable();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { Component, inject, Input, output } from '@angular/core';
|
import { Component, effect, inject, Input } from '@angular/core';
|
||||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { NgClass } from '@angular/common';
|
import { NgClass } from '@angular/common';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
|
import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
||||||
|
import { ActionType } from '@app/domain/action-type.util';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-my-profile-update-cv-form',
|
selector: 'app-my-profile-update-cv-form',
|
||||||
@@ -13,29 +15,40 @@ import { ToastrService } from 'ngx-toastr';
|
|||||||
styleUrl: './my-profile-update-cv-form.component.scss',
|
styleUrl: './my-profile-update-cv-form.component.scss',
|
||||||
})
|
})
|
||||||
export class MyProfileUpdateCvFormComponent {
|
export class MyProfileUpdateCvFormComponent {
|
||||||
@Input({ required: true }) profile: Profile | undefined = undefined;
|
@Input({ required: true }) profile: ProfileViewModel | undefined = undefined;
|
||||||
|
|
||||||
private readonly profileService = inject(ProfileService);
|
|
||||||
private readonly toastrService = inject(ToastrService);
|
private readonly toastrService = inject(ToastrService);
|
||||||
|
|
||||||
private readonly authService = inject(AuthService);
|
private readonly authService = inject(AuthService);
|
||||||
|
|
||||||
file: File | null = null; // Variable to store file
|
file: File | null = null; // Variable to store file
|
||||||
|
|
||||||
|
private readonly profileFacade = new ProfileFacade();
|
||||||
|
protected readonly loading = this.profileFacade.loading;
|
||||||
|
protected readonly error = this.profileFacade.error;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
effect(() => {
|
||||||
|
switch (this.loading().action) {
|
||||||
|
case ActionType.UPDATE:
|
||||||
|
if (!this.loading() && !this.error().hasError) {
|
||||||
|
this.authService.updateUser();
|
||||||
|
|
||||||
|
this.toastrService.success(` Votre CV a bien été modifier !`, `Mise à jour`, {
|
||||||
|
closeButton: true,
|
||||||
|
progressAnimation: 'decreasing',
|
||||||
|
progressBar: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
if (this.file != null) {
|
if (this.file != null) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('cv', this.file); // "avatar" est le nom du champ dans PocketBase
|
formData.append('cv', this.file); // "avatar" est le nom du champ dans PocketBase
|
||||||
|
this.profileFacade.update(this.profile?.id!, formData as Partial<Profile>);
|
||||||
this.profileService.updateProfile(this.profile?.id!, formData).subscribe((value) => {
|
|
||||||
this.authService.updateUser();
|
|
||||||
|
|
||||||
this.toastrService.success(` Votre CV a bien été modifier !`, `Mise à jour`, {
|
|
||||||
closeButton: true,
|
|
||||||
progressAnimation: 'decreasing',
|
|
||||||
progressBar: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,17 @@ import { MyProfileUpdateFormComponent } from './my-profile-update-form.component
|
|||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { FormBuilder } from '@angular/forms';
|
import { FormBuilder } from '@angular/forms';
|
||||||
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
describe('MyProfileUpdateFormComponent', () => {
|
describe('MyProfileUpdateFormComponent', () => {
|
||||||
let component: MyProfileUpdateFormComponent;
|
let component: MyProfileUpdateFormComponent;
|
||||||
let fixture: ComponentFixture<MyProfileUpdateFormComponent>;
|
let fixture: ComponentFixture<MyProfileUpdateFormComponent>;
|
||||||
|
|
||||||
let mockToastrService: Partial<ToastrService>;
|
let mockToastrService: Partial<ToastrService>;
|
||||||
|
let mockProfileRepo: ProfileRepository;
|
||||||
|
|
||||||
const mockProfileData = {
|
const mockProfileData = {
|
||||||
profession: '',
|
profession: '',
|
||||||
@@ -26,18 +31,28 @@ describe('MyProfileUpdateFormComponent', () => {
|
|||||||
error: jest.fn(),
|
error: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mockProfileRepo = {
|
||||||
|
create: jest.fn(),
|
||||||
|
list: jest.fn(),
|
||||||
|
update: jest.fn().mockReturnValue(of({} as Profile)),
|
||||||
|
getByUserId: jest.fn().mockReturnValue(of({} as Profile)),
|
||||||
|
};
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [MyProfileUpdateFormComponent],
|
imports: [MyProfileUpdateFormComponent],
|
||||||
providers: [
|
providers: [
|
||||||
FormBuilder,
|
FormBuilder,
|
||||||
provideRouter([]),
|
provideRouter([]),
|
||||||
{ provide: ToastrService, useValue: mockToastrService },
|
{ provide: ToastrService, useValue: mockToastrService },
|
||||||
|
{ provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(MyProfileUpdateFormComponent);
|
fixture = TestBed.createComponent(MyProfileUpdateFormComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
await fixture.whenStable();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, inject, Input, OnInit, signal } from '@angular/core';
|
import { Component, effect, inject, Input, OnInit, signal } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
FormBuilder,
|
FormBuilder,
|
||||||
FormControl,
|
FormControl,
|
||||||
@@ -7,14 +7,16 @@ import {
|
|||||||
Validators,
|
Validators,
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { NgClass } from '@angular/common';
|
import { NgClass } from '@angular/common';
|
||||||
import { SectorService } from '@app/core/services/sector/sector.service';
|
import { SectorService } from '@app/core/services/sector/sector.service';
|
||||||
import { Sector } from '@app/shared/models/sector';
|
import { Sector } from '@app/shared/models/sector';
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||||
import { MyProfileUpdateCvFormComponent } from '@app/shared/components/my-profile-update-cv-form/my-profile-update-cv-form.component';
|
import { MyProfileUpdateCvFormComponent } from '@app/shared/components/my-profile-update-cv-form/my-profile-update-cv-form.component';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
|
import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
||||||
|
import { ActionType } from '@app/domain/action-type.util';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-my-profile-update-form',
|
selector: 'app-my-profile-update-form',
|
||||||
@@ -27,14 +29,38 @@ import { ToastrService } from 'ngx-toastr';
|
|||||||
export class MyProfileUpdateFormComponent implements OnInit {
|
export class MyProfileUpdateFormComponent implements OnInit {
|
||||||
private readonly toastrService = inject(ToastrService);
|
private readonly toastrService = inject(ToastrService);
|
||||||
|
|
||||||
@Input({ required: true }) profile: Profile = {} as Profile;
|
@Input({ required: true }) profile: ProfileViewModel = {} as ProfileViewModel;
|
||||||
private readonly formBuilder = inject(FormBuilder);
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
protected readonly sectorService = inject(SectorService);
|
protected readonly sectorService = inject(SectorService);
|
||||||
protected readonly profileService = inject(ProfileService);
|
|
||||||
protected readonly authService = inject(AuthService);
|
protected readonly authService = inject(AuthService);
|
||||||
profileForm!: FormGroup;
|
profileForm!: FormGroup;
|
||||||
protected sectors = signal<Sector[]>([]);
|
protected sectors = signal<Sector[]>([]);
|
||||||
|
|
||||||
|
private readonly profileFacade = new ProfileFacade();
|
||||||
|
protected readonly loading = this.profileFacade.loading;
|
||||||
|
protected readonly error = this.profileFacade.error;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
effect(() => {
|
||||||
|
switch (this.loading().action) {
|
||||||
|
case ActionType.UPDATE:
|
||||||
|
if (!this.loading() && !this.error().hasError) {
|
||||||
|
this.authService.updateUser();
|
||||||
|
|
||||||
|
this.toastrService.success(
|
||||||
|
` Vos informations personnelles ont bien été modifier !`,
|
||||||
|
`Mise à jour`,
|
||||||
|
{
|
||||||
|
closeButton: true,
|
||||||
|
progressAnimation: 'decreasing',
|
||||||
|
progressBar: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.profileForm = this.formBuilder.group({
|
this.profileForm = this.formBuilder.group({
|
||||||
profession: new FormControl(
|
profession: new FormControl(
|
||||||
@@ -90,26 +116,6 @@ export class MyProfileUpdateFormComponent implements OnInit {
|
|||||||
reseaux: this.profileForm.getRawValue().reseaux,
|
reseaux: this.profileForm.getRawValue().reseaux,
|
||||||
} as Profile;
|
} as Profile;
|
||||||
|
|
||||||
this.profileService.updateProfile(this.profile.id, data).subscribe({
|
this.profileFacade.update(this.profile.id, data);
|
||||||
next: (value) => {
|
|
||||||
this.authService.updateUser();
|
|
||||||
|
|
||||||
this.toastrService.success(
|
|
||||||
` Vos informations personnelles ont bien été modifier !`,
|
|
||||||
`Mise à jour`,
|
|
||||||
{
|
|
||||||
closeButton: true,
|
|
||||||
progressAnimation: 'decreasing',
|
|
||||||
progressBar: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
this.toastrService.error(
|
|
||||||
'Une erreur est survenue lors de la mise à jour de votre profil',
|
|
||||||
'Erreur'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ export class MyProfileUpdateProjectFormComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
if (this.project() !== undefined) {
|
if (this.project() !== undefined) {
|
||||||
this.projectForm.setValue({
|
this.projectForm.setValue({
|
||||||
nom: this.project()!.nom,
|
nom: this.project().nom ?? '',
|
||||||
description: this.project()!.description,
|
description: this.project().description ?? '',
|
||||||
lien: this.project()!.lien,
|
lien: this.project().lien ?? '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { PdfViewerComponent } from './pdf-viewer.component';
|
import { PdfViewerComponent } from './pdf-viewer.component';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
|
|
||||||
describe('PdfViewerComponent', () => {
|
describe('PdfViewerComponent', () => {
|
||||||
let component: PdfViewerComponent;
|
let component: PdfViewerComponent;
|
||||||
let fixture: ComponentFixture<PdfViewerComponent>;
|
let fixture: ComponentFixture<PdfViewerComponent>;
|
||||||
|
|
||||||
const mockProfile: Profile = {
|
const mockProfile: ProfileViewModel = {
|
||||||
id: '123',
|
id: '123',
|
||||||
cv: 'cvfilename.pdf',
|
cv: 'cvfilename.pdf',
|
||||||
} as Profile;
|
} as ProfileViewModel;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, computed, Input } from '@angular/core';
|
import { Component, computed, Input } from '@angular/core';
|
||||||
import { PdfViewerModule } from 'ng2-pdf-viewer';
|
import { PdfViewerModule } from 'ng2-pdf-viewer';
|
||||||
import { Profile } from '@app/shared/models/profile';
|
|
||||||
import { environment } from '@env/environment';
|
import { environment } from '@env/environment';
|
||||||
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pdf-viewer',
|
selector: 'app-pdf-viewer',
|
||||||
@@ -11,7 +11,7 @@ import { environment } from '@env/environment';
|
|||||||
styleUrl: './pdf-viewer.component.scss',
|
styleUrl: './pdf-viewer.component.scss',
|
||||||
})
|
})
|
||||||
export class PdfViewerComponent {
|
export class PdfViewerComponent {
|
||||||
@Input({ required: true }) profile: Profile | undefined = undefined;
|
@Input({ required: true }) profile: ProfileViewModel | undefined = undefined;
|
||||||
protected readonly environment = environment;
|
protected readonly environment = environment;
|
||||||
protected readonly cv_link = computed(() => {
|
protected readonly cv_link = computed(() => {
|
||||||
return `${environment.baseUrl}/api/files/profiles/${this.profile!.id}/${this.profile!.cv}`;
|
return `${environment.baseUrl}/api/files/profiles/${this.profile!.id}/${this.profile!.cv}`;
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { RegisterComponent } from './register.component';
|
import { RegisterComponent } from './register.component';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
|
|
||||||
describe('RegisterComponent', () => {
|
describe('RegisterComponent', () => {
|
||||||
let component: RegisterComponent;
|
let component: RegisterComponent;
|
||||||
@@ -12,19 +13,22 @@ describe('RegisterComponent', () => {
|
|||||||
|
|
||||||
let mockToastrService: Partial<ToastrService>;
|
let mockToastrService: Partial<ToastrService>;
|
||||||
let mockAuthService: Partial<AuthService>;
|
let mockAuthService: Partial<AuthService>;
|
||||||
let mockProfileService: Partial<ProfileService>;
|
let mockProfileRepo: ProfileRepository;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockProfileRepo = {
|
||||||
|
create: jest.fn(),
|
||||||
|
list: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
getByUserId: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
mockToastrService = {
|
mockToastrService = {
|
||||||
success: jest.fn(),
|
success: jest.fn(),
|
||||||
error: jest.fn(),
|
error: jest.fn(),
|
||||||
warning: jest.fn(),
|
warning: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
mockProfileService = {
|
|
||||||
createProfile: jest.fn().mockResolvedValue(true),
|
|
||||||
};
|
|
||||||
|
|
||||||
mockAuthService = {};
|
mockAuthService = {};
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
@@ -33,7 +37,7 @@ describe('RegisterComponent', () => {
|
|||||||
provideRouter([]),
|
provideRouter([]),
|
||||||
{ provide: ToastrService, useValue: mockToastrService },
|
{ provide: ToastrService, useValue: mockToastrService },
|
||||||
{ provide: AuthService, useValue: mockAuthService },
|
{ provide: AuthService, useValue: mockAuthService },
|
||||||
{ provide: ProfileService, useValue: mockProfileService },
|
{ provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { ChangeDetectionStrategy, Component, inject, output, signal } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, effect, inject, output, signal } from '@angular/core';
|
||||||
import { Router, RouterLink } from '@angular/router';
|
import { Router, RouterLink } from '@angular/router';
|
||||||
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||||
import { RegisterDto } from '@app/shared/models/register-dto';
|
import { RegisterDto } from '@app/shared/models/register-dto';
|
||||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { ProfileService } from '@app/core/services/profile/profile.service';
|
|
||||||
import { ProfileDto } from '@app/shared/models/profile-dto';
|
|
||||||
import { ProgressBarModule } from 'primeng/progressbar';
|
import { ProgressBarModule } from 'primeng/progressbar';
|
||||||
|
import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
||||||
|
import { ActionType } from '@app/domain/action-type.util';
|
||||||
|
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-register',
|
selector: 'app-register',
|
||||||
@@ -20,7 +21,6 @@ import { ProgressBarModule } from 'primeng/progressbar';
|
|||||||
@UntilDestroy()
|
@UntilDestroy()
|
||||||
export class RegisterComponent {
|
export class RegisterComponent {
|
||||||
private readonly authService = inject(AuthService);
|
private readonly authService = inject(AuthService);
|
||||||
private readonly profileService = inject(ProfileService);
|
|
||||||
private readonly toastrService = inject(ToastrService);
|
private readonly toastrService = inject(ToastrService);
|
||||||
|
|
||||||
private readonly formBuilder = inject(FormBuilder);
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
@@ -34,6 +34,26 @@ export class RegisterComponent {
|
|||||||
formSubmitted = output<any>();
|
formSubmitted = output<any>();
|
||||||
protected isLoading = signal<boolean>(false);
|
protected isLoading = signal<boolean>(false);
|
||||||
|
|
||||||
|
private readonly profileFacade = new ProfileFacade();
|
||||||
|
protected readonly loading = this.profileFacade.loading;
|
||||||
|
protected readonly error = this.profileFacade.error;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
effect(() => {
|
||||||
|
switch (this.loading().action) {
|
||||||
|
case ActionType.CREATE:
|
||||||
|
if (!this.loading().isLoading) {
|
||||||
|
if (!this.error().hasError) {
|
||||||
|
this.router.navigate(['/auth']).then(() => {
|
||||||
|
this.sendVerificationEmail();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
if (this.registerForm.invalid) {
|
if (this.registerForm.invalid) {
|
||||||
this.isLoading.set(false);
|
this.isLoading.set(false);
|
||||||
@@ -63,13 +83,13 @@ export class RegisterComponent {
|
|||||||
register(registerDto: RegisterDto) {
|
register(registerDto: RegisterDto) {
|
||||||
this.authService.register(registerDto).then((res) => {
|
this.authService.register(registerDto).then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.createProfile(res.id, registerDto.email);
|
this.createProfile(res.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createProfile(userId: string, email: string) {
|
createProfile(userId: string) {
|
||||||
const profileDto: ProfileDto = {
|
const profileDto: ProfileDTO = {
|
||||||
profession: 'Profession non renseignée',
|
profession: 'Profession non renseignée',
|
||||||
utilisateur: userId,
|
utilisateur: userId,
|
||||||
reseaux: {
|
reseaux: {
|
||||||
@@ -83,28 +103,11 @@ export class RegisterComponent {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.profileService.createProfile(profileDto).subscribe({
|
this.profileFacade.create(profileDto);
|
||||||
next: (profile) => {
|
|
||||||
if (profile)
|
|
||||||
this.router.navigate(['/auth']).then(() => {
|
|
||||||
this.sendVerificationEmail(email);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error: (err) => {
|
|
||||||
this.toastrService.error(
|
|
||||||
`Une erreur est survenue lors de la création de votre profil.`,
|
|
||||||
`Erreur`,
|
|
||||||
{
|
|
||||||
closeButton: true,
|
|
||||||
progressAnimation: 'decreasing',
|
|
||||||
progressBar: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendVerificationEmail(email: string) {
|
sendVerificationEmail() {
|
||||||
|
const email = this.registerForm.getRawValue().email!;
|
||||||
this.authService.verifyEmail(email).then((isVerified: boolean) => {
|
this.authService.verifyEmail(email).then((isVerified: boolean) => {
|
||||||
this.isLoading.set(false);
|
this.isLoading.set(false);
|
||||||
this.registerForm.enable();
|
this.registerForm.enable();
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
export interface ProfileDto {
|
|
||||||
profession: string;
|
|
||||||
utilisateur: string;
|
|
||||||
reseaux: any;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export interface Profile {
|
|
||||||
id: string;
|
|
||||||
created: string;
|
|
||||||
updated: string;
|
|
||||||
profession: string;
|
|
||||||
utilisateur: string;
|
|
||||||
estVerifier: boolean;
|
|
||||||
secteur: string;
|
|
||||||
reseaux: JSON;
|
|
||||||
bio: string;
|
|
||||||
cv: string;
|
|
||||||
projets: string[];
|
|
||||||
apropos: string;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export interface ProjectDto {
|
|
||||||
nom: string;
|
|
||||||
description: string;
|
|
||||||
lien: string;
|
|
||||||
utilisateur: string;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
export interface Project {
|
|
||||||
id: string;
|
|
||||||
created: string;
|
|
||||||
updated: string;
|
|
||||||
nom: string;
|
|
||||||
lien: string;
|
|
||||||
description: string;
|
|
||||||
fichier: string[];
|
|
||||||
utilisateur: string;
|
|
||||||
}
|
|
||||||
@@ -8,8 +8,8 @@ export class FakeProfileRepository implements ProfileRepository {
|
|||||||
return of(mockProfiles);
|
return of(mockProfiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
getByUserId(userId: string): Observable<Profile | null> {
|
getByUserId(userId: string): Observable<Profile> {
|
||||||
const profile = mockProfiles.find((p) => p.utilisateur === userId) ?? null;
|
const profile = mockProfiles.find((p) => p.utilisateur === userId) ?? ({} as Profile);
|
||||||
return of(profile);
|
return of(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { ProjectRepository } from '@app/domain/projects/project.repository';
|
import { ProjectRepository } from '@app/domain/projects/project.repository';
|
||||||
import { Project } from '@app/shared/models/project';
|
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
||||||
import { fakeProjects } from '@app/testing/project.mock';
|
import { fakeProjects } from '@app/testing/project.mock';
|
||||||
|
import { Project } from '@app/domain/projects/project.model';
|
||||||
|
|
||||||
export class FakeProjectRepository implements ProjectRepository {
|
export class FakeProjectRepository implements ProjectRepository {
|
||||||
private projects: Project[] = [...fakeProjects];
|
private projects: Project[] = [...fakeProjects];
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
|
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
|
||||||
|
import { mockProfiles } from '@app/testing/profile.mock';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||||
|
|
||||||
describe('ProfileFacade', () => {
|
describe('ProfileFacade', () => {
|
||||||
let facade: ProfileFacade;
|
let facade: ProfileFacade;
|
||||||
@@ -27,4 +30,52 @@ describe('ProfileFacade', () => {
|
|||||||
done();
|
done();
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("doit charger le profile d'un utilisateur ", () => {
|
||||||
|
facade.loadOne('1');
|
||||||
|
const expectedProfile = mockProfiles[0];
|
||||||
|
|
||||||
|
// attendre un peu le .subscribe
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(facade.profile()).toBe(expectedProfile);
|
||||||
|
expect(facade.loading().isLoading).toBe(false);
|
||||||
|
expect(facade.error().hasError).toBe(false);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('doit mettre à jour un profile ', () => {
|
||||||
|
expect(mockProfiles[0].profession).toBe('Développeur Web');
|
||||||
|
|
||||||
|
const profileUpdated: Profile = {
|
||||||
|
...mockProfiles[0],
|
||||||
|
profession: 'Devops',
|
||||||
|
};
|
||||||
|
|
||||||
|
facade.update('1', profileUpdated);
|
||||||
|
|
||||||
|
// attendre un peu le .subscribe
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(facade.profile().profession).toBe('Devops');
|
||||||
|
expect(facade.loading().isLoading).toBe(false);
|
||||||
|
expect(facade.error().hasError).toBe(false);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('doit creer un nouveau profile ', () => {
|
||||||
|
const profile: ProfileDTO = {
|
||||||
|
utilisateur: 'john doe',
|
||||||
|
reseaux: {},
|
||||||
|
profession: 'Journaliste',
|
||||||
|
};
|
||||||
|
|
||||||
|
facade.create(profile);
|
||||||
|
|
||||||
|
// attendre un peu le .subscribe
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(mockProfiles.find((profile) => profile.id === facade.profile().id)).toBeDefined();
|
||||||
|
expect(facade.profile().profession).toBe('Journaliste');
|
||||||
|
expect(facade.loading().isLoading).toBe(false);
|
||||||
|
expect(facade.error().hasError).toBe(false);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ describe('ProfilePresenter', () => {
|
|||||||
utilisateur: 'user_abc',
|
utilisateur: 'user_abc',
|
||||||
createdAtFormatted: new Date(profile.created).toLocaleDateString(),
|
createdAtFormatted: new Date(profile.created).toLocaleDateString(),
|
||||||
avatarUrl: '',
|
avatarUrl: '',
|
||||||
|
apropos: 'Développeur Angular & Node.js',
|
||||||
|
bio: 'Passionné de code.',
|
||||||
|
cv: 'cv.pdf',
|
||||||
|
projets: ['p1', 'p2'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
|
||||||
|
import { mockProfiles } from '@app/testing/profile.mock';
|
||||||
|
import { CreateProfileUseCase } from '@app/usecase/profiles/create-profile.usecase';
|
||||||
|
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||||
|
|
||||||
|
describe('CreateProfileUseCase', () => {
|
||||||
|
it('doit creer nouveau un profile', () => {
|
||||||
|
const repo = new FakeProfileRepository();
|
||||||
|
const useCase = new CreateProfileUseCase(repo);
|
||||||
|
|
||||||
|
const profile: ProfileDTO = {
|
||||||
|
utilisateur: 'john doe',
|
||||||
|
profession: 'Designer',
|
||||||
|
reseaux: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
useCase.execute(profile).subscribe({
|
||||||
|
next: (profile) => {
|
||||||
|
expect(mockProfiles).toContain(profile);
|
||||||
|
expect(mockProfiles.find((current_profile) => profile.id === current_profile.id)).toBe(
|
||||||
|
profile.id
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
16
src/app/testing/usecase/profiles/get-profile.usecase.spec.ts
Normal file
16
src/app/testing/usecase/profiles/get-profile.usecase.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
|
||||||
|
import { mockProfiles } from '@app/testing/profile.mock';
|
||||||
|
import { GetProfileUseCase } from '@app/usecase/profiles/get-profile.usecase';
|
||||||
|
|
||||||
|
describe('GetProfileUseCase', () => {
|
||||||
|
it('doit retourner un profile', () => {
|
||||||
|
const repo = new FakeProfileRepository();
|
||||||
|
const useCase = new GetProfileUseCase(repo);
|
||||||
|
|
||||||
|
useCase.execute('1').subscribe({
|
||||||
|
next: (profile) => {
|
||||||
|
expect(profile).toEqual(mockProfiles[0]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { FakeProfileRepository } from '@app/testing/domain/profiles/fake-profile.repository';
|
||||||
|
import { mockProfiles } from '@app/testing/profile.mock';
|
||||||
|
import { UpdateProfileUseCase } from '@app/usecase/profiles/update-profile.usecase';
|
||||||
|
|
||||||
|
describe('UpdateProfileUseCase', () => {
|
||||||
|
it('doit retourner un profile modifier', () => {
|
||||||
|
const repo = new FakeProfileRepository();
|
||||||
|
const useCase = new UpdateProfileUseCase(repo);
|
||||||
|
const profile = mockProfiles[0];
|
||||||
|
|
||||||
|
expect(profile.profession).toBe('Développeur Web');
|
||||||
|
|
||||||
|
const profileUpdate = {
|
||||||
|
...profile,
|
||||||
|
profession: 'Développeur fullstack',
|
||||||
|
};
|
||||||
|
useCase.execute('1', profileUpdate).subscribe({
|
||||||
|
next: (profile) => {
|
||||||
|
expect(profile.profession).toEqual('Développeur fullstack');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,21 +1,30 @@
|
|||||||
import { ListProfilesUseCase } from '@app/usecase/profiles/list-profiles.usecase';
|
import { ListProfilesUseCase } from '@app/usecase/profiles/list-profiles.usecase';
|
||||||
import { inject, signal } from '@angular/core';
|
import { inject, Injectable, signal } from '@angular/core';
|
||||||
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-repository.token';
|
||||||
import { Profile } from '@app/domain/profiles/profile.model';
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { ProfilePresenter } from '@app/ui/profiles/profile.presenter';
|
import { ProfilePresenter } from '@app/ui/profiles/profile.presenter';
|
||||||
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||||
import { LoaderAction } from '@app/domain/loader-action.util';
|
import { LoaderAction } from '@app/domain/loader-action.util';
|
||||||
import { ActionType } from '@app/domain/action-type.util';
|
import { ActionType } from '@app/domain/action-type.util';
|
||||||
import { ErrorResponse } from '@app/domain/error-response.util';
|
import { ErrorResponse } from '@app/domain/error-response.util';
|
||||||
|
import { CreateProfileUseCase } from '@app/usecase/profiles/create-profile.usecase';
|
||||||
|
import { UpdateProfileUseCase } from '@app/usecase/profiles/update-profile.usecase';
|
||||||
|
import { GetProfileUseCase } from '@app/usecase/profiles/get-profile.usecase';
|
||||||
|
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ProfileFacade {
|
export class ProfileFacade {
|
||||||
private profileRepository = inject(PROFILE_REPOSITORY_TOKEN);
|
private profileRepository = inject(PROFILE_REPOSITORY_TOKEN);
|
||||||
|
|
||||||
private listUseCase = new ListProfilesUseCase(this.profileRepository);
|
private listUseCase = new ListProfilesUseCase(this.profileRepository);
|
||||||
|
private createUseCase = new CreateProfileUseCase(this.profileRepository);
|
||||||
|
private updateUseCase = new UpdateProfileUseCase(this.profileRepository);
|
||||||
|
private getUseCase = new GetProfileUseCase(this.profileRepository);
|
||||||
|
|
||||||
readonly profiles = signal<ProfileViewModel[]>([]);
|
readonly profiles = signal<ProfileViewModel[]>([]);
|
||||||
|
readonly profile = signal<ProfileViewModel>({} as ProfileViewModel);
|
||||||
readonly loading = signal<LoaderAction>({ isLoading: false, action: ActionType.NONE });
|
readonly loading = signal<LoaderAction>({ isLoading: false, action: ActionType.NONE });
|
||||||
readonly error = signal<ErrorResponse>({
|
readonly error = signal<ErrorResponse>({
|
||||||
action: ActionType.NONE,
|
action: ActionType.NONE,
|
||||||
@@ -37,6 +46,48 @@ export class ProfileFacade {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadOne(userId: string) {
|
||||||
|
this.handleError(ActionType.READ, false, null, true);
|
||||||
|
|
||||||
|
this.getUseCase.execute(userId).subscribe({
|
||||||
|
next: (profile: Profile) => {
|
||||||
|
this.profile.set(ProfilePresenter.toViewModel(profile));
|
||||||
|
this.handleError(ActionType.READ, false, null, false);
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
this.handleError(ActionType.READ, false, err, false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
create(profileDto: ProfileDTO) {
|
||||||
|
this.handleError(ActionType.CREATE, false, null, true);
|
||||||
|
|
||||||
|
this.createUseCase.execute(profileDto).subscribe({
|
||||||
|
next: (profile: Profile) => {
|
||||||
|
this.profile.set(ProfilePresenter.toViewModel(profile));
|
||||||
|
this.handleError(ActionType.CREATE, false, null, false);
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
this.handleError(ActionType.CREATE, false, err, false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(profileId: string, profile: Partial<Profile>) {
|
||||||
|
this.handleError(ActionType.UPDATE, false, null, true);
|
||||||
|
|
||||||
|
this.updateUseCase.execute(profileId, profile).subscribe({
|
||||||
|
next: (profile: Profile) => {
|
||||||
|
this.profile.set(ProfilePresenter.toViewModel(profile));
|
||||||
|
this.handleError(ActionType.UPDATE, false, null, false);
|
||||||
|
},
|
||||||
|
error: (err) => {
|
||||||
|
this.handleError(ActionType.UPDATE, false, err, false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private handleError(
|
private handleError(
|
||||||
action: ActionType = ActionType.NONE,
|
action: ActionType = ActionType.NONE,
|
||||||
hasError: boolean,
|
hasError: boolean,
|
||||||
|
|||||||
@@ -9,4 +9,8 @@ export interface ProfileViewModel {
|
|||||||
profession: string;
|
profession: string;
|
||||||
secteur: string;
|
secteur: string;
|
||||||
reseaux: any;
|
reseaux: any;
|
||||||
|
apropos: string;
|
||||||
|
bio: string;
|
||||||
|
cv: string;
|
||||||
|
projets: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ export class ProfilePresenter {
|
|||||||
profession: profile.profession,
|
profession: profile.profession,
|
||||||
secteur: profile.secteur,
|
secteur: profile.secteur,
|
||||||
reseaux: profile.reseaux,
|
reseaux: profile.reseaux,
|
||||||
|
apropos: profile.apropos,
|
||||||
|
projets: profile.projets,
|
||||||
|
cv: profile.cv,
|
||||||
|
bio: profile.bio,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/app/usecase/profiles/create-profile.usecase.ts
Normal file
12
src/app/usecase/profiles/create-profile.usecase.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||||
|
|
||||||
|
export class CreateProfileUseCase {
|
||||||
|
constructor(private readonly repo: ProfileRepository) {}
|
||||||
|
|
||||||
|
execute(profileDto: ProfileDTO): Observable<Profile> {
|
||||||
|
return this.repo.create(profileDto as Profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/app/usecase/profiles/get-profile.usecase.ts
Normal file
11
src/app/usecase/profiles/get-profile.usecase.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
|
||||||
|
export class GetProfileUseCase {
|
||||||
|
constructor(private readonly repo: ProfileRepository) {}
|
||||||
|
|
||||||
|
execute(userId: string): Observable<Profile> {
|
||||||
|
return this.repo.getByUserId(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/app/usecase/profiles/update-profile.usecase.ts
Normal file
11
src/app/usecase/profiles/update-profile.usecase.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||||
|
import { Profile } from '@app/domain/profiles/profile.model';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
export class UpdateProfileUseCase {
|
||||||
|
constructor(private readonly repo: ProfileRepository) {}
|
||||||
|
|
||||||
|
execute(profileId: string, profile: Partial<Profile>): Observable<Profile> {
|
||||||
|
return this.repo.update(profileId, profile as Profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,3 +22,33 @@ Object.defineProperty(document.body.style, 'transform', {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Simule la fonction fetch pour éviter les erreurs dans les tests Jest
|
||||||
|
global.fetch = jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve({}),
|
||||||
|
blob: () => Promise.resolve(new Blob()),
|
||||||
|
})
|
||||||
|
) as jest.Mock;
|
||||||
|
|
||||||
|
// 🟡 Ignore le warning pdfjs-dist
|
||||||
|
const originalWarn = console.warn;
|
||||||
|
console.warn = (...args) => {
|
||||||
|
if (
|
||||||
|
typeof args[0] === 'string' &&
|
||||||
|
args[0].includes('ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG')
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
originalWarn(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🔴 Ignore le log angularx-qrcode après les tests
|
||||||
|
const originalError = console.error;
|
||||||
|
console.error = (...args) => {
|
||||||
|
if (typeof args[0] === 'string' && args[0].includes('[angularx-qrcode]')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
originalError(...args);
|
||||||
|
};
|
||||||
|
|||||||
354
structure.md
354
structure.md
@@ -1,354 +0,0 @@
|
|||||||
.
|
|
||||||
├── .actrc
|
|
||||||
├── .angular
|
|
||||||
│ └── cache
|
|
||||||
│ └── 17.3.17
|
|
||||||
│ ├── TrouveTonProfile
|
|
||||||
│ │ └── .tsbuildinfo
|
|
||||||
│ └── vite
|
|
||||||
│ └── deps
|
|
||||||
│ ├── @angular_common.js
|
|
||||||
│ ├── @angular_common.js.map
|
|
||||||
│ ├── @angular_common_http.js
|
|
||||||
│ ├── @angular_common_http.js.map
|
|
||||||
│ ├── @angular_core.js
|
|
||||||
│ ├── @angular_core.js.map
|
|
||||||
│ ├── @angular_forms.js
|
|
||||||
│ ├── @angular_forms.js.map
|
|
||||||
│ ├── @angular_platform-browser.js
|
|
||||||
│ ├── @angular_platform-browser.js.map
|
|
||||||
│ ├── @angular_platform-browser_animations.js
|
|
||||||
│ ├── @angular_platform-browser_animations.js.map
|
|
||||||
│ ├── @angular_router.js
|
|
||||||
│ ├── @angular_router.js.map
|
|
||||||
│ ├── @fortawesome_angular-fontawesome.js
|
|
||||||
│ ├── @fortawesome_angular-fontawesome.js.map
|
|
||||||
│ ├── @ngneat_until-destroy.js
|
|
||||||
│ ├── @ngneat_until-destroy.js.map
|
|
||||||
│ ├── _metadata.json
|
|
||||||
│ ├── angularx-qrcode.js
|
|
||||||
│ ├── angularx-qrcode.js.map
|
|
||||||
│ ├── chunk-24ZYNOED.js
|
|
||||||
│ ├── chunk-24ZYNOED.js.map
|
|
||||||
│ ├── chunk-3EFO7QKA.js
|
|
||||||
│ ├── chunk-3EFO7QKA.js.map
|
|
||||||
│ ├── chunk-3VPQ5C6Q.js
|
|
||||||
│ ├── chunk-3VPQ5C6Q.js.map
|
|
||||||
│ ├── chunk-5HONZSNN.js
|
|
||||||
│ ├── chunk-5HONZSNN.js.map
|
|
||||||
│ ├── chunk-5S2WJ7I2.js
|
|
||||||
│ ├── chunk-5S2WJ7I2.js.map
|
|
||||||
│ ├── chunk-ARYSD6E7.js
|
|
||||||
│ ├── chunk-ARYSD6E7.js.map
|
|
||||||
│ ├── chunk-CMCTAO2J.js
|
|
||||||
│ ├── chunk-CMCTAO2J.js.map
|
|
||||||
│ ├── chunk-DMKDLVH4.js
|
|
||||||
│ ├── chunk-DMKDLVH4.js.map
|
|
||||||
│ ├── chunk-HW7FRNZO.js
|
|
||||||
│ ├── chunk-HW7FRNZO.js.map
|
|
||||||
│ ├── chunk-QJER22WX.js
|
|
||||||
│ ├── chunk-QJER22WX.js.map
|
|
||||||
│ ├── fs-BSX2J5PF.js
|
|
||||||
│ ├── fs-BSX2J5PF.js.map
|
|
||||||
│ ├── http-3CT2HGWN.js
|
|
||||||
│ ├── http-3CT2HGWN.js.map
|
|
||||||
│ ├── https-HEKUO7DA.js
|
|
||||||
│ ├── https-HEKUO7DA.js.map
|
|
||||||
│ ├── ng2-pdf-viewer.js
|
|
||||||
│ ├── ng2-pdf-viewer.js.map
|
|
||||||
│ ├── ngx-toastr.js
|
|
||||||
│ ├── ngx-toastr.js.map
|
|
||||||
│ ├── package.json
|
|
||||||
│ ├── pocketbase.js
|
|
||||||
│ ├── pocketbase.js.map
|
|
||||||
│ ├── primeng_paginator.js
|
|
||||||
│ ├── primeng_paginator.js.map
|
|
||||||
│ ├── primeng_progressbar.js
|
|
||||||
│ ├── primeng_progressbar.js.map
|
|
||||||
│ ├── rxjs.js
|
|
||||||
│ ├── rxjs.js.map
|
|
||||||
│ ├── tslib.js
|
|
||||||
│ ├── tslib.js.map
|
|
||||||
│ ├── url-JDV7XCKY.js
|
|
||||||
│ └── url-JDV7XCKY.js.map
|
|
||||||
├── .dockerignore
|
|
||||||
├── .editorconfig
|
|
||||||
├── .gitea
|
|
||||||
│ └── workflows
|
|
||||||
│ └── ci.yaml
|
|
||||||
├── .gitignore
|
|
||||||
├── .idea
|
|
||||||
│ ├── .gitignore
|
|
||||||
│ ├── TrouveTonProfile.iml
|
|
||||||
│ ├── misc.xml
|
|
||||||
│ ├── modules.xml
|
|
||||||
│ ├── vcs.xml
|
|
||||||
│ └── workspace.xml
|
|
||||||
├── CMD.md
|
|
||||||
├── Dockerfile
|
|
||||||
├── LICENSE
|
|
||||||
├── README.md
|
|
||||||
├── angular.json
|
|
||||||
├── jest.config.js
|
|
||||||
├── nginx.conf
|
|
||||||
├── package-lock.json
|
|
||||||
├── package.json
|
|
||||||
├── server.ts
|
|
||||||
├── src
|
|
||||||
│ ├── app
|
|
||||||
│ │ ├── app.component.html
|
|
||||||
│ │ ├── app.component.scss
|
|
||||||
│ │ ├── app.component.spec.ts
|
|
||||||
│ │ ├── app.component.ts
|
|
||||||
│ │ ├── app.config.server.ts
|
|
||||||
│ │ ├── app.config.ts
|
|
||||||
│ │ ├── app.routes.ts
|
|
||||||
│ │ ├── core
|
|
||||||
│ │ │ ├── guard
|
|
||||||
│ │ │ │ └── authentication
|
|
||||||
│ │ │ │ ├── auth.guard.spec.ts
|
|
||||||
│ │ │ │ └── auth.guard.ts
|
|
||||||
│ │ │ ├── resolvers
|
|
||||||
│ │ │ │ ├── my-profile
|
|
||||||
│ │ │ │ │ ├── my-profile.resolver.spec.ts
|
|
||||||
│ │ │ │ │ └── my-profile.resolver.ts
|
|
||||||
│ │ │ │ └── profile
|
|
||||||
│ │ │ │ ├── detail
|
|
||||||
│ │ │ │ │ ├── detail.resolver.spec.ts
|
|
||||||
│ │ │ │ │ └── detail.resolver.ts
|
|
||||||
│ │ │ │ └── list
|
|
||||||
│ │ │ │ ├── list.resolver.spec.ts
|
|
||||||
│ │ │ │ └── list.resolver.ts
|
|
||||||
│ │ │ └── services
|
|
||||||
│ │ │ ├── authentication
|
|
||||||
│ │ │ │ ├── auth.service.spec.ts
|
|
||||||
│ │ │ │ └── auth.service.ts
|
|
||||||
│ │ │ ├── profile
|
|
||||||
│ │ │ │ ├── profile.service.spec.ts
|
|
||||||
│ │ │ │ └── profile.service.ts
|
|
||||||
│ │ │ ├── project
|
|
||||||
│ │ │ │ ├── project.service.spec.ts
|
|
||||||
│ │ │ │ └── project.service.ts
|
|
||||||
│ │ │ ├── sector
|
|
||||||
│ │ │ │ ├── sector.service.spec.ts
|
|
||||||
│ │ │ │ └── sector.service.ts
|
|
||||||
│ │ │ ├── theme
|
|
||||||
│ │ │ │ ├── theme.service.spec.ts
|
|
||||||
│ │ │ │ └── theme.service.ts
|
|
||||||
│ │ │ └── user
|
|
||||||
│ │ │ ├── user.service.spec.ts
|
|
||||||
│ │ │ └── user.service.ts
|
|
||||||
│ │ ├── routes
|
|
||||||
│ │ │ ├── authentification
|
|
||||||
│ │ │ │ ├── auth
|
|
||||||
│ │ │ │ │ ├── auth.component.html
|
|
||||||
│ │ │ │ │ ├── auth.component.scss
|
|
||||||
│ │ │ │ │ ├── auth.component.spec.ts
|
|
||||||
│ │ │ │ │ └── auth.component.ts
|
|
||||||
│ │ │ │ ├── authentification-routing.module.ts
|
|
||||||
│ │ │ │ └── authentification.module.ts
|
|
||||||
│ │ │ ├── home
|
|
||||||
│ │ │ │ ├── home-routing.module.ts
|
|
||||||
│ │ │ │ ├── home.component.html
|
|
||||||
│ │ │ │ ├── home.component.scss
|
|
||||||
│ │ │ │ ├── home.component.spec.ts
|
|
||||||
│ │ │ │ ├── home.component.ts
|
|
||||||
│ │ │ │ └── home.module.ts
|
|
||||||
│ │ │ ├── my-profile
|
|
||||||
│ │ │ │ ├── my-profile-routing.module.ts
|
|
||||||
│ │ │ │ ├── my-profile.component.html
|
|
||||||
│ │ │ │ ├── my-profile.component.scss
|
|
||||||
│ │ │ │ ├── my-profile.component.spec.ts
|
|
||||||
│ │ │ │ ├── my-profile.component.ts
|
|
||||||
│ │ │ │ └── my-profile.module.ts
|
|
||||||
│ │ │ ├── not-found
|
|
||||||
│ │ │ │ ├── not-found-routing.module.ts
|
|
||||||
│ │ │ │ ├── not-found.component.html
|
|
||||||
│ │ │ │ ├── not-found.component.scss
|
|
||||||
│ │ │ │ ├── not-found.component.spec.ts
|
|
||||||
│ │ │ │ ├── not-found.component.ts
|
|
||||||
│ │ │ │ └── not-found.module.ts
|
|
||||||
│ │ │ └── profile
|
|
||||||
│ │ │ ├── profile-detail
|
|
||||||
│ │ │ │ ├── profile-detail.component.html
|
|
||||||
│ │ │ │ ├── profile-detail.component.scss
|
|
||||||
│ │ │ │ ├── profile-detail.component.spec.ts
|
|
||||||
│ │ │ │ └── profile-detail.component.ts
|
|
||||||
│ │ │ ├── profile-list
|
|
||||||
│ │ │ │ ├── profile-list.component.html
|
|
||||||
│ │ │ │ ├── profile-list.component.scss
|
|
||||||
│ │ │ │ ├── profile-list.component.spec.ts
|
|
||||||
│ │ │ │ └── profile-list.component.ts
|
|
||||||
│ │ │ ├── profile-routing.module.ts
|
|
||||||
│ │ │ └── profile.module.ts
|
|
||||||
│ │ └── shared
|
|
||||||
│ │ ├── components
|
|
||||||
│ │ │ ├── chips
|
|
||||||
│ │ │ │ ├── chips.component.html
|
|
||||||
│ │ │ │ ├── chips.component.scss
|
|
||||||
│ │ │ │ ├── chips.component.spec.ts
|
|
||||||
│ │ │ │ └── chips.component.ts
|
|
||||||
│ │ │ ├── footer
|
|
||||||
│ │ │ │ ├── footer.component.html
|
|
||||||
│ │ │ │ ├── footer.component.scss
|
|
||||||
│ │ │ │ ├── footer.component.spec.ts
|
|
||||||
│ │ │ │ └── footer.component.ts
|
|
||||||
│ │ │ ├── horizental-profile-item
|
|
||||||
│ │ │ │ ├── horizental-profile-item.component.html
|
|
||||||
│ │ │ │ ├── horizental-profile-item.component.scss
|
|
||||||
│ │ │ │ ├── horizental-profile-item.component.spec.ts
|
|
||||||
│ │ │ │ └── horizental-profile-item.component.ts
|
|
||||||
│ │ │ ├── horizental-profile-list
|
|
||||||
│ │ │ │ ├── horizental-profile-list.component.html
|
|
||||||
│ │ │ │ ├── horizental-profile-list.component.scss
|
|
||||||
│ │ │ │ ├── horizental-profile-list.component.spec.ts
|
|
||||||
│ │ │ │ └── horizental-profile-list.component.ts
|
|
||||||
│ │ │ ├── my-home-profile
|
|
||||||
│ │ │ │ ├── my-home-profile.component.html
|
|
||||||
│ │ │ │ ├── my-home-profile.component.scss
|
|
||||||
│ │ │ │ ├── my-home-profile.component.spec.ts
|
|
||||||
│ │ │ │ └── my-home-profile.component.ts
|
|
||||||
│ │ │ ├── my-profile-project-item
|
|
||||||
│ │ │ │ ├── my-profile-project-item.component.html
|
|
||||||
│ │ │ │ ├── my-profile-project-item.component.scss
|
|
||||||
│ │ │ │ ├── my-profile-project-item.component.spec.ts
|
|
||||||
│ │ │ │ └── my-profile-project-item.component.ts
|
|
||||||
│ │ │ ├── my-profile-project-list
|
|
||||||
│ │ │ │ ├── my-profile-project-list.component.html
|
|
||||||
│ │ │ │ ├── my-profile-project-list.component.scss
|
|
||||||
│ │ │ │ ├── my-profile-project-list.component.spec.ts
|
|
||||||
│ │ │ │ └── my-profile-project-list.component.ts
|
|
||||||
│ │ │ ├── my-profile-update-cv-form
|
|
||||||
│ │ │ │ ├── my-profile-update-cv-form.component.html
|
|
||||||
│ │ │ │ ├── my-profile-update-cv-form.component.scss
|
|
||||||
│ │ │ │ ├── my-profile-update-cv-form.component.spec.ts
|
|
||||||
│ │ │ │ └── my-profile-update-cv-form.component.ts
|
|
||||||
│ │ │ ├── my-profile-update-form
|
|
||||||
│ │ │ │ ├── my-profile-update-form.component.html
|
|
||||||
│ │ │ │ ├── my-profile-update-form.component.scss
|
|
||||||
│ │ │ │ ├── my-profile-update-form.component.spec.ts
|
|
||||||
│ │ │ │ └── my-profile-update-form.component.ts
|
|
||||||
│ │ │ ├── my-profile-update-project-form
|
|
||||||
│ │ │ │ ├── my-profile-update-project-form.component.html
|
|
||||||
│ │ │ │ ├── my-profile-update-project-form.component.scss
|
|
||||||
│ │ │ │ ├── my-profile-update-project-form.component.spec.ts
|
|
||||||
│ │ │ │ └── my-profile-update-project-form.component.ts
|
|
||||||
│ │ │ ├── nav-bar
|
|
||||||
│ │ │ │ ├── nav-bar.component.html
|
|
||||||
│ │ │ │ ├── nav-bar.component.scss
|
|
||||||
│ │ │ │ ├── nav-bar.component.spec.ts
|
|
||||||
│ │ │ │ └── nav-bar.component.ts
|
|
||||||
│ │ │ ├── project-item
|
|
||||||
│ │ │ │ ├── project-item.component.html
|
|
||||||
│ │ │ │ ├── project-item.component.scss
|
|
||||||
│ │ │ │ ├── project-item.component.spec.ts
|
|
||||||
│ │ │ │ └── project-item.component.ts
|
|
||||||
│ │ │ ├── project-list
|
|
||||||
│ │ │ │ ├── project-list.component.html
|
|
||||||
│ │ │ │ ├── project-list.component.scss
|
|
||||||
│ │ │ │ ├── project-list.component.spec.ts
|
|
||||||
│ │ │ │ └── project-list.component.ts
|
|
||||||
│ │ │ ├── project-picture-form
|
|
||||||
│ │ │ │ ├── project-picture-form.component.html
|
|
||||||
│ │ │ │ ├── project-picture-form.component.scss
|
|
||||||
│ │ │ │ ├── project-picture-form.component.spec.ts
|
|
||||||
│ │ │ │ └── project-picture-form.component.ts
|
|
||||||
│ │ │ ├── reseaux
|
|
||||||
│ │ │ │ ├── reseaux.component.html
|
|
||||||
│ │ │ │ ├── reseaux.component.scss
|
|
||||||
│ │ │ │ ├── reseaux.component.spec.ts
|
|
||||||
│ │ │ │ └── reseaux.component.ts
|
|
||||||
│ │ │ ├── user-avatar-form
|
|
||||||
│ │ │ │ ├── user-avatar-form.component.html
|
|
||||||
│ │ │ │ ├── user-avatar-form.component.scss
|
|
||||||
│ │ │ │ ├── user-avatar-form.component.spec.ts
|
|
||||||
│ │ │ │ └── user-avatar-form.component.ts
|
|
||||||
│ │ │ ├── user-form
|
|
||||||
│ │ │ │ ├── user-form.component.html
|
|
||||||
│ │ │ │ ├── user-form.component.scss
|
|
||||||
│ │ │ │ ├── user-form.component.spec.ts
|
|
||||||
│ │ │ │ └── user-form.component.ts
|
|
||||||
│ │ │ ├── user-password-form
|
|
||||||
│ │ │ │ ├── user-password-form.component.html
|
|
||||||
│ │ │ │ ├── user-password-form.component.scss
|
|
||||||
│ │ │ │ ├── user-password-form.component.spec.ts
|
|
||||||
│ │ │ │ └── user-password-form.component.ts
|
|
||||||
│ │ │ ├── vertical-profile-item
|
|
||||||
│ │ │ │ ├── vertical-profile-item.component.html
|
|
||||||
│ │ │ │ ├── vertical-profile-item.component.scss
|
|
||||||
│ │ │ │ ├── vertical-profile-item.component.spec.ts
|
|
||||||
│ │ │ │ └── vertical-profile-item.component.ts
|
|
||||||
│ │ │ └── vertical-profile-list
|
|
||||||
│ │ │ ├── vertical-profile-list.component.html
|
|
||||||
│ │ │ ├── vertical-profile-list.component.scss
|
|
||||||
│ │ │ ├── vertical-profile-list.component.spec.ts
|
|
||||||
│ │ │ └── vertical-profile-list.component.ts
|
|
||||||
│ │ ├── features
|
|
||||||
│ │ │ ├── display-profile-card
|
|
||||||
│ │ │ │ ├── display-profile-card.component.html
|
|
||||||
│ │ │ │ ├── display-profile-card.component.scss
|
|
||||||
│ │ │ │ ├── display-profile-card.component.spec.ts
|
|
||||||
│ │ │ │ └── display-profile-card.component.ts
|
|
||||||
│ │ │ ├── login
|
|
||||||
│ │ │ │ ├── login.component.html
|
|
||||||
│ │ │ │ ├── login.component.scss
|
|
||||||
│ │ │ │ ├── login.component.spec.ts
|
|
||||||
│ │ │ │ └── login.component.ts
|
|
||||||
│ │ │ ├── pdf-viewer
|
|
||||||
│ │ │ │ ├── pdf-viewer.component.html
|
|
||||||
│ │ │ │ ├── pdf-viewer.component.scss
|
|
||||||
│ │ │ │ ├── pdf-viewer.component.spec.ts
|
|
||||||
│ │ │ │ └── pdf-viewer.component.ts
|
|
||||||
│ │ │ ├── register
|
|
||||||
│ │ │ │ ├── register.component.html
|
|
||||||
│ │ │ │ ├── register.component.scss
|
|
||||||
│ │ │ │ ├── register.component.spec.ts
|
|
||||||
│ │ │ │ └── register.component.ts
|
|
||||||
│ │ │ ├── search
|
|
||||||
│ │ │ │ ├── search.component.html
|
|
||||||
│ │ │ │ ├── search.component.scss
|
|
||||||
│ │ │ │ ├── search.component.spec.ts
|
|
||||||
│ │ │ │ └── search.component.ts
|
|
||||||
│ │ │ └── update-user
|
|
||||||
│ │ │ ├── update-user.component.html
|
|
||||||
│ │ │ ├── update-user.component.scss
|
|
||||||
│ │ │ ├── update-user.component.spec.ts
|
|
||||||
│ │ │ └── update-user.component.ts
|
|
||||||
│ │ ├── models
|
|
||||||
│ │ │ ├── auth.ts
|
|
||||||
│ │ │ ├── login-dto.ts
|
|
||||||
│ │ │ ├── profile-dto.ts
|
|
||||||
│ │ │ ├── profile.ts
|
|
||||||
│ │ │ ├── project-dto.ts
|
|
||||||
│ │ │ ├── project.ts
|
|
||||||
│ │ │ ├── register-dto.ts
|
|
||||||
│ │ │ ├── sector.ts
|
|
||||||
│ │ │ └── user.ts
|
|
||||||
│ │ └── utils
|
|
||||||
│ ├── assets
|
|
||||||
│ │ ├── .gitkeep
|
|
||||||
│ │ ├── fonts
|
|
||||||
│ │ │ └── ubuntu
|
|
||||||
│ │ │ └── Ubuntu-Regular.ttf
|
|
||||||
│ │ └── images
|
|
||||||
│ │ ├── bg.avif
|
|
||||||
│ │ ├── pdf.svg
|
|
||||||
│ │ └── ttp.jpg
|
|
||||||
│ ├── environments
|
|
||||||
│ │ ├── environment.development.ts
|
|
||||||
│ │ └── environment.ts
|
|
||||||
│ ├── favicon.ico
|
|
||||||
│ ├── index.html
|
|
||||||
│ ├── main.server.ts
|
|
||||||
│ ├── main.ts
|
|
||||||
│ ├── setiterator-fix.d.ts
|
|
||||||
│ ├── setup-jest.ts
|
|
||||||
│ └── styles.scss
|
|
||||||
├── start.sh
|
|
||||||
├── structure.md
|
|
||||||
├── tailwind.config.js
|
|
||||||
├── tsconfig.app.json
|
|
||||||
├── tsconfig.json
|
|
||||||
└── tsconfig.spec.json
|
|
||||||
|
|
||||||
72 directories, 280 files
|
|
||||||
Reference in New Issue
Block a user