Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • minerva/frontend
1 result
Show changes
Commits on Source (7)
Showing
with 592 additions and 111 deletions
NEXT_PUBLIC_BASE_API_URL = 'https://corsproxy.io/?https://lux1.atcomp.pl/minerva/api'
NEXT_PUBLIC_BASE_NEW_API_URL = 'https://corsproxy.io/?https://lux1.atcomp.pl/minerva/new_api/'
BASE_MAP_IMAGES_URL = 'https://lux1.atcomp.pl/'
NEXT_PUBLIC_PROJECT_ID = 'pdmap_appu_test'
ZOD_SEED = 997
......@@ -10,6 +10,7 @@
"plugin:react/recommended",
"plugin:jsx-a11y/recommended",
"plugin:@next/next/recommended",
"plugin:prettier/recommended",
"prettier",
"next"
],
......@@ -87,7 +88,8 @@
"callees": ["twMerge"],
"config": "./tailwind.config.ts"
}
]
],
"prettier/prettier": "error"
},
"overrides": [
{
......
......@@ -50,6 +50,7 @@
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-n": "^16.1.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
......@@ -1885,6 +1886,26 @@
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz",
"integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ=="
},
"node_modules/@pkgr/utils": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz",
"integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"fast-glob": "^3.3.0",
"is-glob": "^4.0.3",
"open": "^9.1.0",
"picocolors": "^1.0.0",
"tslib": "^2.6.0"
},
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@reduxjs/toolkit": {
"version": "1.9.6",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.6.tgz",
......@@ -3208,6 +3229,15 @@
"tweetnacl": "^0.14.3"
}
},
"node_modules/big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
"dev": true,
"engines": {
"node": ">=0.6"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
......@@ -3239,6 +3269,18 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
"node_modules/bplist-parser": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
"integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
"dev": true,
"dependencies": {
"big-integer": "^1.6.44"
},
"engines": {
"node": ">= 5.10.0"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
......@@ -3347,6 +3389,21 @@
"semver": "^7.0.0"
}
},
"node_modules/bundle-name": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
"integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==",
"dev": true,
"dependencies": {
"run-applescript": "^5.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
......@@ -4379,6 +4436,150 @@
"node": ">=0.10.0"
}
},
"node_modules/default-browser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz",
"integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==",
"dev": true,
"dependencies": {
"bundle-name": "^3.0.0",
"default-browser-id": "^3.0.0",
"execa": "^7.1.1",
"titleize": "^3.0.0"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser-id": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz",
"integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==",
"dev": true,
"dependencies": {
"bplist-parser": "^0.2.0",
"untildify": "^4.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/execa": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
"integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.1",
"human-signals": "^4.3.0",
"is-stream": "^3.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^5.1.0",
"onetime": "^6.0.0",
"signal-exit": "^3.0.7",
"strip-final-newline": "^3.0.0"
},
"engines": {
"node": "^14.18.0 || ^16.14.0 || >=18.0.0"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/default-browser/node_modules/human-signals": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
"integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==",
"dev": true,
"engines": {
"node": ">=14.18.0"
}
},
"node_modules/default-browser/node_modules/is-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/npm-run-path": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
"integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
"dev": true,
"dependencies": {
"path-key": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/onetime": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
"dev": true,
"dependencies": {
"mimic-fn": "^4.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/path-key": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser/node_modules/strip-final-newline": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/defaults": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
......@@ -4404,6 +4605,18 @@
"node": ">= 0.4"
}
},
"node_modules/define-lazy-prop": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
......@@ -5211,6 +5424,35 @@
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz",
"integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.8.5"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/prettier"
},
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
"optional": true
},
"eslint-config-prettier": {
"optional": true
}
}
},
"node_modules/eslint-plugin-promise": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz",
......@@ -5730,6 +5972,12 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"node_modules/fast-glob": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
......@@ -6882,6 +7130,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-docker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
"dev": true,
"bin": {
"is-docker": "cli.js"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
......@@ -6944,6 +7207,24 @@
"node": ">=0.10.0"
}
},
"node_modules/is-inside-container": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
"dev": true,
"dependencies": {
"is-docker": "^3.0.0"
},
"bin": {
"is-inside-container": "cli.js"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-installed-globally": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
......@@ -7206,6 +7487,33 @@
"node": ">=0.10.0"
}
},
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"dependencies": {
"is-docker": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-wsl/node_modules/is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true,
"bin": {
"is-docker": "cli.js"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
......@@ -9784,6 +10092,24 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/open": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz",
"integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==",
"dev": true,
"dependencies": {
"default-browser": "^4.0.0",
"define-lazy-prop": "^3.0.0",
"is-inside-container": "^1.0.0",
"is-wsl": "^2.2.0"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/optionator": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
......@@ -10282,6 +10608,18 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/prettier-plugin-tailwindcss": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.6.tgz",
......@@ -11077,6 +11415,21 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/run-applescript": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz",
"integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==",
"dev": true,
"dependencies": {
"execa": "^5.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
......@@ -11720,6 +12073,22 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
"node_modules/synckit": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz",
"integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==",
"dev": true,
"dependencies": {
"@pkgr/utils": "^2.3.1",
"tslib": "^2.5.0"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/tailwind-merge": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz",
......@@ -11841,6 +12210,18 @@
"readable-stream": "3"
}
},
"node_modules/titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
"integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
......
......@@ -6,6 +6,7 @@ const config = {
plugins: [import('prettier-plugin-tailwindcss')],
tailwindConfig: './tailwind.config.ts',
tailwindFunctions: ['twMerge'],
tabWidth: 2,
};
module.exports = config;
import { TopBar } from '@/components/FunctionalArea/TopBar';
import { NavBar } from '@/components/FunctionalArea/NavBar';
import { MapNavigation } from '@/components/FunctionalArea/MapNavigation';
import { NavBar } from '@/components/FunctionalArea/NavBar';
import { TopBar } from '@/components/FunctionalArea/TopBar';
export const FunctionalArea = (): JSX.Element => (
<>
......
import { BASE_MAP_IMAGES_URL } from '@/constants';
import { getMapTileUrl } from './getMapTileUrl';
describe('getMapTileUrl - util', () => {
describe('when projectDirectory is empty', () => {
it('should return empty value', () => {
const projectDirectory = undefined;
const currentBackgroundImagePath = 'currentBackgroundImagePath';
const result = '';
expect(
getMapTileUrl({
projectDirectory,
currentBackgroundImagePath,
}),
).toBe(result);
});
});
describe('when all args are valid', () => {
it('should return correct value', () => {
const projectDirectory = 'directory';
const currentBackgroundImagePath = 'currentBackgroundImagePath';
const result = `${BASE_MAP_IMAGES_URL}/map_images/${projectDirectory}/${currentBackgroundImagePath}/{z}/{x}/{y}.PNG`;
expect(
getMapTileUrl({
projectDirectory,
currentBackgroundImagePath,
}),
).toBe(result);
});
});
});
import { BASE_MAP_IMAGES_URL } from '@/constants';
export const getMapTileUrl = ({
projectDirectory,
currentBackgroundImagePath,
}: {
projectDirectory?: string;
currentBackgroundImagePath: string;
}): string => {
if (!projectDirectory) {
return '';
}
return `${BASE_MAP_IMAGES_URL}/map_images/${projectDirectory}/${currentBackgroundImagePath}/{z}/{x}/{y}.PNG`;
};
/* eslint-disable no-magic-numbers */
import { OPTIONS } from '@/constants/map';
import { currentBackgroundImagePathSelector } from '@/redux/backgrounds/background.selectors';
import { mapDataPositionSelector, mapDataSizeSelector } from '@/redux/map/map.selectors';
import { projectDataSelector } from '@/redux/project/project.selectors';
import { Point } from '@/types/map';
import { usePointToProjection } from '@/utils/map/usePointToProjection';
import { View } from 'ol';
......@@ -9,6 +11,7 @@ import TileLayer from 'ol/layer/Tile';
import { XYZ } from 'ol/source';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { getMapTileUrl } from './getMapTileUrl';
interface UseOlMapConfigResult {
view: View;
......@@ -18,6 +21,8 @@ interface UseOlMapConfigResult {
export const useOlMapConfig = (): UseOlMapConfigResult => {
const mapPosition = useSelector(mapDataPositionSelector);
const mapSize = useSelector(mapDataSizeSelector);
const currentBackgroundImagePath = useSelector(currentBackgroundImagePathSelector);
const project = useSelector(projectDataSelector);
const pointToProjection = usePointToProjection();
const center = useMemo(() => {
......@@ -40,19 +45,18 @@ export const useOlMapConfig = (): UseOlMapConfigResult => {
);
const tileLayer = useMemo(
() =>
(): TileLayer<XYZ> =>
new TileLayer({
visible: true,
source: new XYZ({
url: 'https://pdmap.uni.lu/map_images/9d4911bdeeea752f076e57a91d9b1f45/_nested0/{z}/{x}/{y}.PNG',
// TODO: build url from data in redux
url: getMapTileUrl({ projectDirectory: project?.directory, currentBackgroundImagePath }),
maxZoom: mapSize.maxZoom,
minZoom: mapSize.minZoom,
tileSize: mapSize.tileSize,
wrapX: OPTIONS.wrapXInTileLayer,
}),
}),
[mapSize],
[mapSize, currentBackgroundImagePath, project?.directory],
);
return {
......
import Map from 'ol/Map';
import React, { MutableRefObject, useEffect, useState } from 'react';
import { MapInstance } from '../MapViewer.types';
import { useOlMapConfig } from './useOlMapConfig';
import { useOlMapInit } from './useOlMapInit';
import { useOlMapConfig } from './config/useOlMapConfig';
interface UseOlMapInput {
target?: HTMLElement;
......@@ -18,7 +17,6 @@ export const useOlMap: UseOlMap = ({ target } = {}) => {
const mapRef = React.useRef<null | HTMLDivElement>(null);
const [mapInstance, setMapInstance] = useState<MapInstance>(undefined);
const mapConfig = useOlMapConfig();
useOlMapInit();
useEffect(() => {
// checking if innerHTML is empty due to possibility of target element cloning by openlayers map instance
......
describe.skip('useOlMapConfig - util', () => {
// TODO: tests
// everything is mocked in the file, so we need to firstly wait for module API connection
it('noop', () => {
// eslint-disable-next-line no-magic-numbers
expect(1).toEqual(1);
});
});
/* eslint-disable no-magic-numbers */
// TODO: Remove mocks and implement communication with API
import { DEFAULT_ZOOM } from '@/constants/map';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { setMapData } from '@/redux/map/map.slice';
import { useCallback, useEffect } from 'react';
const MOCK_PROJECT = {
version: '',
disease: {
link: 'http://id.nlm.nih.gov/mesh/D010300',
type: 'MESH_2012',
resource: 'D010300',
id: 3211856,
annotatorClassName: '',
},
idObject: 6065,
status: 'Ok',
directory: '9d4911bdeeea752f076e57a91d9b1f45',
progress: 100,
notifyEmail: 'ewa.smula@uni.lu',
logEntries: true,
name: "Parkinson's disease map",
sharedInMinervaNet: true,
owner: 'ewa.smula',
projectId: 'pd_map_winter_23',
creationDate: '2023-02-15 16:35:11',
mapCanvasType: 'OPEN_LAYERS',
};
const MOCK_MODEL = {
idObject: 5053,
width: 26779.25,
height: 13503,
defaultCenterX: null,
defaultCenterY: null,
description: '',
name: 'Core PD map',
defaultZoomLevel: null,
tileSize: 256,
references: [],
authors: [],
creationDate: null,
modificationDates: [],
minZoom: 2,
maxZoom: 9,
};
export const useOlMapInit = (): void => {
const dispatch = useAppDispatch();
const mapInit = useCallback(() => {
dispatch(
setMapData({
meshId: MOCK_PROJECT.disease.resource,
modelId: MOCK_MODEL.idObject,
size: {
width: MOCK_MODEL.width,
height: MOCK_MODEL.height,
tileSize: MOCK_MODEL.tileSize,
minZoom: MOCK_MODEL.minZoom,
maxZoom: MOCK_MODEL.maxZoom,
},
position: {
x: MOCK_MODEL.defaultCenterX || MOCK_MODEL.width / 2,
y: MOCK_MODEL.defaultCenterY || MOCK_MODEL.height / 2,
z: MOCK_MODEL.defaultZoomLevel || DEFAULT_ZOOM,
},
}),
);
}, [dispatch]);
useEffect(() => mapInit(), [mapInit]);
};
import { FunctionalArea } from '@/components/FunctionalArea';
import { Map } from '@/components/Map';
import { Manrope } from '@next/font/google';
import { twMerge } from 'tailwind-merge';
import { Map } from '@/components/Map';
import { FunctionalArea } from '@/components/FunctionalArea';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useEffect } from 'react';
import { getModels } from '@/redux/models/models.thunks';
import { useInitializeStore } from './utils/useInitializeStore';
const manrope = Manrope({
variable: '--font-manrope',
......@@ -14,11 +12,7 @@ const manrope = Manrope({
});
export const MinervaSPA = (): JSX.Element => {
const dispatch = useAppDispatch();
useEffect(() => {
dispatch(getModels());
}, [dispatch]);
useInitializeStore();
return (
<div className={twMerge('relative', manrope.variable)}>
......
import { PROJECT_ID } from '@/constants';
import { backgroundsFixture } from '@/models/fixtures/backgroundsFixture';
import { modelsFixture } from '@/models/fixtures/modelsFixture';
import { overlaysFixture } from '@/models/fixtures/overlaysFixture';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { apiPath } from '@/redux/apiPath';
import { backgroundsDataSelector } from '@/redux/backgrounds/background.selectors';
import { modelsDataSelector } from '@/redux/models/models.selectors';
import { overlaysDataSelector } from '@/redux/overlays/overlays.selectors';
import { projectDataSelector } from '@/redux/project/project.selectors';
import { initDataLoadingInitialized } from '@/redux/root/init.selectors';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook, waitFor } from '@testing-library/react';
import { HttpStatusCode } from 'axios';
import * as hook from './useInitializeStore';
const mockedAxiosClient = mockNetworkResponse();
describe('useInitializeStore - hook', () => {
describe('when fired', () => {
beforeAll(() => {
mockedAxiosClient.onGet(apiPath.getModelsString()).reply(HttpStatusCode.Ok, modelsFixture);
mockedAxiosClient
.onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true }))
.reply(HttpStatusCode.Ok, overlaysFixture);
mockedAxiosClient
.onGet(apiPath.getProjectById(PROJECT_ID))
.reply(HttpStatusCode.Ok, projectFixture);
mockedAxiosClient
.onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID))
.reply(HttpStatusCode.Ok, backgroundsFixture);
});
it('should fetch project data in store', async () => {
const { Wrapper, store } = getReduxWrapperWithStore();
renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper });
await waitFor(() => {
const data = projectDataSelector(store.getState());
expect(data).toEqual(projectFixture);
});
});
it('should fetch backgrounds data in store', async () => {
const { Wrapper, store } = getReduxWrapperWithStore();
renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper });
await waitFor(() => {
const data = backgroundsDataSelector(store.getState());
expect(data).toEqual(backgroundsFixture);
});
});
it('should fetch overlays data in store', async () => {
const { Wrapper, store } = getReduxWrapperWithStore();
renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper });
await waitFor(() => {
const data = overlaysDataSelector(store.getState());
expect(data).toEqual(overlaysFixture);
});
});
it('should fetch models data in store', async () => {
const { Wrapper, store } = getReduxWrapperWithStore();
renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper });
await waitFor(() => {
const data = modelsDataSelector(store.getState());
expect(data).toEqual(modelsFixture);
});
});
it('should use valid initialize value', () => {
const { Wrapper, store } = getReduxWrapperWithStore();
const initializedeBefore = initDataLoadingInitialized(store.getState());
renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper });
const initializedAfter = initDataLoadingInitialized(store.getState());
expect(initializedeBefore).toBe(false);
expect(initializedAfter).toBe(true);
});
});
});
import { PROJECT_ID } from '@/constants';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { initMapData } from '@/redux/map/map.thunks';
import { getProjectById } from '@/redux/project/project.thunks';
import { initDataLoadingInitialized } from '@/redux/root/init.selectors';
import { AppDispatch } from '@/redux/store';
import { useEffect } from 'react';
import { useSelector } from 'react-redux';
/* prettier-ignore */
export const getInitStoreData =
() =>
(dispatch: AppDispatch): void => {
dispatch(getProjectById(PROJECT_ID));
dispatch(initMapData());
};
export const useInitializeStore = (): void => {
const dispatch = useAppDispatch();
const isInitialized = useSelector(initDataLoadingInitialized);
useEffect(() => {
if (isInitialized) {
return;
}
dispatch(getInitStoreData());
}, [dispatch, isInitialized]);
};
......@@ -8,3 +8,8 @@ export const modelsFixture = createFixture(z.array(mapModelSchema), {
seed: ZOD_SEED,
array: { min: 3, max: 3 },
});
export const singleModelFixture = createFixture(mapModelSchema, {
seed: ZOD_SEED,
array: { min: 3, max: 3 },
});
......@@ -6,7 +6,7 @@ export const backgroundsSelector = createSelector(rootSelector, state => state.b
export const backgroundsDataSelector = createSelector(
backgroundsSelector,
backgrounds => backgrounds.data || [],
backgrounds => backgrounds?.data || [],
);
export const currentBackgroundSelector = createSelector(
......
......@@ -26,3 +26,5 @@ export const MAP_DATA_INITIAL_STATE: MapData = {
maxZoom: DEFAULT_MAX_ZOOM,
},
};
export const MIDDLEWARE_ALLOWED_ACTIONS: string[] = ['map/setMapData', 'map/initMapData'];
import { PayloadAction } from '@reduxjs/toolkit';
import { MapData, MapState } from './map.types';
import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
import { initMapData } from './map.thunks';
import { MapState, SetMapDataAction } from './map.types';
export const setMapDataReducer = (
state: MapState,
action: PayloadAction<Partial<MapData> | undefined>,
): void => {
export const setMapDataReducer = (state: MapState, action: SetMapDataAction): void => {
state.data = { ...state.data, ...action.payload };
};
export const getMapReducers = (builder: ActionReducerMapBuilder<MapState>): void => {
builder.addCase(initMapData.pending, state => {
state.loading = 'pending';
});
builder.addCase(initMapData.fulfilled, (state, action) => {
const payload = action.payload || {};
state.data = { ...state.data, ...payload };
state.loading = 'succeeded';
});
builder.addCase(initMapData.rejected, state => {
state.loading = 'failed';
// TODO to discuss manage state of failure
});
};