diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index da4005ea4701c0cce6f1f64c25a93c3bdaa98af1..88620b3228b28ec5d5def6fa3a40f326987f8a67 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,6 @@
 cache:
   paths:
-   - node_modules/
+    - node_modules/
 
 stages:
   - build
@@ -29,4 +29,4 @@ publish package to npm repository:
     - echo "//registry.npmjs.org/:_authToken=${NPM_REGISTRY_TOKEN}" > .npmrc
     - npm install
     - if [[ "$CI_COMMIT_TAG" == v* ]]; then npm run ci-publish $CI_COMMIT_TAG; fi
-    - if [[ "$CI_COMMIT_TAG" == *@* ]]; then npm run ci-publish $CI_COMMIT_TAG; fi
\ No newline at end of file
+    - if [[ "$CI_COMMIT_TAG" == *@* ]]; then npm run ci-publish $CI_COMMIT_TAG; fi
diff --git a/.npmrc b/.npmrc
index 95b9bdc55e1fe67f19fd6f2ba741ab54c25cde15..69bb280739e850d4b892c0dd922c40e143691a48 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,4 +1,4 @@
-@piveau:registry=https://paca.fokus.fraunhofer.de/repository/npm-hosted/
+#@piveau:registry=https://paca.fokus.fraunhofer.de/repository/npm-hosted/
 @deu:registry=https://paca.fokus.fraunhofer.de/repository/npm-group/
 
 ########### Verdaccio: ###########
diff --git a/apps/vanilla-piveau-hub-ui b/apps/vanilla-piveau-hub-ui
index 574d0ea043a8a88e53af8638ed96ea0e9378720e..213dd60b390a07693073693d9c4900ad5a3121a1 160000
--- a/apps/vanilla-piveau-hub-ui
+++ b/apps/vanilla-piveau-hub-ui
@@ -1 +1 @@
-Subproject commit 574d0ea043a8a88e53af8638ed96ea0e9378720e
+Subproject commit 213dd60b390a07693073693d9c4900ad5a3121a1
diff --git a/packages/piveau-hub-ui-modules/3rd-party-licenses.csv b/packages/piveau-hub-ui-modules/3rd-party-licenses.csv
new file mode 100644
index 0000000000000000000000000000000000000000..4c3c01b8c9ce2040e8345af9e6f5c33e1e3de912
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/3rd-party-licenses.csv
@@ -0,0 +1,2 @@
+"module name","license","repository"
+"@piveau/piveau-hub-ui-modules@4.4.8","Apache-2.0",""
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/CHANGELOG.md b/packages/piveau-hub-ui-modules/CHANGELOG.md
index 65e4acd41e0890433041f8e516c7474e21656589..23b307c6a48774c124933d5a767b9195cf65bf65 100644
--- a/packages/piveau-hub-ui-modules/CHANGELOG.md
+++ b/packages/piveau-hub-ui-modules/CHANGELOG.md
@@ -23,6 +23,61 @@
 
 
 # [80.0.0-alpha.39](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.38...v80.0.0-alpha.39) (2025-01-29)
+## [4.6.13](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.12...v4.6.13) (2025-02-18)
+
+
+### Bug Fixes
+
+* **dpi:** disable catalog selection on edit ([94210e2](https://gitlab.com/piveau/ui/piveau-ui/commit/94210e282885a913d105089029e2414e4b9fe62a))
+* **dpi:** licence -> licenses ([799d4b8](https://gitlab.com/piveau/ui/piveau-ui/commit/799d4b8b9c29126631c01b7d10d328260296af8c))
+
+
+
+## [4.6.12](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.11...v4.6.12) (2025-02-17)
+
+
+
+## [4.6.11](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.10...v4.6.11) (2025-02-13)
+
+
+### Bug Fixes
+
+* handling of downloadprogress modal with activated cookie ([9a973a5](https://gitlab.com/piveau/ui/piveau-ui/commit/9a973a537054f7bf79f93aff1fda928ed094cc6f))
+* modal cookie conditional ([6f017c0](https://gitlab.com/piveau/ui/piveau-ui/commit/6f017c0f9d0945273f67db4f549ee6ef9de56055))
+* prevent close option by outside click or close button ([f02cd91](https://gitlab.com/piveau/ui/piveau-ui/commit/f02cd91094111a51ff36b60a4f14d0ad37ff6b4a))
+* text on downloadall button during download ([44cbf15](https://gitlab.com/piveau/ui/piveau-ui/commit/44cbf15f6c02cd5e6ae5210adf09694dc5f42080))
+* variable assignment in dpi ([9ceb086](https://gitlab.com/piveau/ui/piveau-ui/commit/9ceb0867c6722a87e525e69043c53d7784791025))
+
+
+
+## [4.6.10](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.9...v4.6.10) (2025-02-13)
+
+
+### Bug Fixes
+
+* **SimpleSelect:** fix bug that caused catalog select to break when catalog contains no title ([9c8ca53](https://gitlab.com/piveau/ui/piveau-ui/commit/9c8ca5307ad678731325b291e43dcde3334b903d))
+
+
+
+## [4.6.9](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.8...v4.6.9) (2025-02-12)
+
+
+### Bug Fixes
+
+* **SimpleSelect:** use more convenient template structuring to not break accordion logic ([f9e6123](https://gitlab.com/piveau/ui/piveau-ui/commit/f9e612348247a64b61b92a6c27303efd116cdaa3))
+
+
+
+## [4.6.8](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.7...v4.6.8) (2025-02-12)
+
+
+### Bug Fixes
+
+* **SimpleSelect:** rework SimpleSelect to make catalogue selection more robust ([9445a6e](https://gitlab.com/piveau/ui/piveau-ui/commit/9445a6e31120f323bca3c54da37306a8f0d98be3))
+
+
+
+## [4.6.7](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.6...v4.6.7) (2025-02-06)
 
 
 ### Bug Fixes
@@ -32,6 +87,11 @@
 
 
 # [80.0.0-alpha.38](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.37...v80.0.0-alpha.38) (2025-01-28)
+* fix preview button not working for geo distributions ([414d26d](https://gitlab.com/piveau/ui/piveau-ui/commit/414d26de5f538fa276549565c2f41ae89f660215))
+
+
+
+## [4.6.6](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.5...v4.6.6) (2025-01-30)
 
 
 ### Bug Fixes
@@ -65,6 +125,12 @@
 
 
 # [80.0.0-alpha.31](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.30...v80.0.0-alpha.31) (2025-01-15)
+* fix minor syntax ([55923f2](https://gitlab.com/piveau/ui/piveau-ui/commit/55923f2b5fc04c7d567db6bfd7e814cf92f60f15))
+* rename visualize -> preview + rearrange ([0086bef](https://gitlab.com/piveau/ui/piveau-ui/commit/0086bef61e406914e2faa871c25ed80a0ea10bf6))
+
+
+
+## [4.6.5](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.4...v4.6.5) (2025-01-28)
 
 
 ### Bug Fixes
@@ -84,6 +150,15 @@
 
 
 # [80.0.0-alpha.28](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.27...v80.0.0-alpha.28) (2025-01-13)
+* minor csv class namings to allow csv overwrite ([77f0cde](https://gitlab.com/piveau/ui/piveau-ui/commit/77f0cde0936bdbca1e0bed082fdfff703e4644da))
+
+
+
+## [4.6.4](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.3...v4.6.4) (2025-01-27)
+
+
+
+## [4.6.3](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.2...v4.6.3) (2025-01-23)
 
 
 ### Bug Fixes
@@ -100,6 +175,11 @@
 
 
 # [80.0.0-alpha.26](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.25...v80.0.0-alpha.26) (2025-01-08)
+* remove preview button when visualise is active ([401ddac](https://gitlab.com/piveau/ui/piveau-ui/commit/401ddac0077d4806cebd36e8275cbacd3ca7b27e))
+
+
+
+## [4.6.2](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.1...v4.6.2) (2025-01-22)
 
 
 ### Bug Fixes
@@ -127,6 +207,15 @@
 
 
 # [80.0.0-alpha.22](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.21...v80.0.0-alpha.22) (2025-01-07)
+* fix switching between visualisation of different distributions + implement auto scroll on click ([861c307](https://gitlab.com/piveau/ui/piveau-ui/commit/861c307e42e2cc8f2a98fa132cff679ba0c330a6))
+
+
+
+## [4.6.1](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.6.0...v4.6.1) (2025-01-22)
+
+
+
+# [4.6.0](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.13...v4.6.0) (2025-01-20)
 
 
 ### Features
@@ -144,6 +233,23 @@
 
 
 # [80.0.0-alpha.19](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.18...v80.0.0-alpha.19) (2024-12-18)
+* **DataProviderInterface:** enables standalone DPI operation ([ec9e235](https://gitlab.com/piveau/ui/piveau-ui/commit/ec9e2359cd2767fcd19860537702a18cc3d54ca7))
+
+
+
+## [4.5.13](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.12...v4.5.13) (2025-01-16)
+
+
+
+## [4.5.12](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.11...v4.5.12) (2025-01-15)
+
+
+
+## [4.5.11](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.10...v4.5.11) (2025-01-14)
+
+
+
+## [4.5.10](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.9...v4.5.10) (2025-01-10)
 
 
 ### Bug Fixes
@@ -190,6 +296,11 @@
 
 
 # [80.0.0-alpha.9](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.8...v80.0.0-alpha.9) (2024-12-04)
+* use established version of datasetsfacets ([3d16bbc](https://gitlab.com/piveau/ui/piveau-ui/commit/3d16bbc364fb8806ef2aec878aa717884262c290))
+
+
+
+## [4.5.9](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.8...v4.5.9) (2024-12-19)
 
 
 ### Bug Fixes
@@ -199,6 +310,12 @@
 
 
 # [80.0.0-alpha.8](https://gitlab.com/piveau/ui/piveau-ui/compare/v80.0.0-alpha.7...v80.0.0-alpha.8) (2024-12-03)
+* hide table for PPE ([4a034ec](https://gitlab.com/piveau/ui/piveau-ui/commit/4a034eca021f63f0a669c00a540846f1334f8784))
+* PPE UI ([b8e3ef9](https://gitlab.com/piveau/ui/piveau-ui/commit/b8e3ef9c6903ca5ef736bf41fdf6963e8680425f))
+
+
+
+## [4.5.8](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.7...v4.5.8) (2024-12-19)
 
 
 ### Bug Fixes
@@ -244,6 +361,401 @@
 
 
 
+# [100.0.0-alpha.0](https://gitlab.com/piveau/ui/piveau-ui/compare/v99.99.99...v100.0.0-alpha.0) (2024-10-10)
+
+
+
+## [99.99.99](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.4...v99.99.99) (2024-10-10)
+* better typing and no store use for facet injection ([82d71b3](https://gitlab.com/piveau/ui/piveau-ui/commit/82d71b38340256328c271cc50b041b71e58ce8a9))
+* correct usefacets composable ([2f5bf2a](https://gitlab.com/piveau/ui/piveau-ui/commit/2f5bf2ae93fabf8573901906bdba386ac97ab7a1))
+* extract query param handling ([fafb7ea](https://gitlab.com/piveau/ui/piveau-ui/commit/fafb7ea4ce1165fd934aab3af5b6f789be08de65))
+* getFacet.ts only taking id arg ([643d640](https://gitlab.com/piveau/ui/piveau-ui/commit/643d64027b0d7248d186c187e2e25f8544976315))
+* implement facetclicked emit ([ace90c8](https://gitlab.com/piveau/ui/piveau-ui/commit/ace90c854ce4fd1be9042e5ee5ae69b4565d4b5e))
+* improve facet clickhandling and display ([a8ef6ad](https://gitlab.com/piveau/ui/piveau-ui/commit/a8ef6ad322583fd4283b3dd42c1a1f8e1019e410))
+* introduce composable for facet ordering and filtering ([d691f16](https://gitlab.com/piveau/ui/piveau-ui/commit/d691f16d41236f78e51f148d2a439796d79cf151))
+* introduce facet stat ([29459d1](https://gitlab.com/piveau/ui/piveau-ui/commit/29459d1668d108687e1fc97ec1a034b3243c594e))
+* introduce search component ([cdcb803](https://gitlab.com/piveau/ui/piveau-ui/commit/cdcb803803a12f8912a8e8b1bf156f921a141553))
+* use env composable ([fe7bbb3](https://gitlab.com/piveau/ui/piveau-ui/commit/fe7bbb3ae93d5ce1b230068d6b77d8dee04e7e77))
+
+
+### Features
+
+* integrate ExpandableSelectFacet.vue into new facet handling ([2a5af46](https://gitlab.com/piveau/ui/piveau-ui/commit/2a5af460eb62e7e9b596f74294437e857c0a70c4))
+
+
+
+## [4.5.7](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.6...v4.5.7) (2024-12-18)
+
+
+### Bug Fixes
+
+* Ui formating ([20d01fc](https://gitlab.com/piveau/ui/piveau-ui/commit/20d01fc75908ddca38487832aab58ec0d3d1fcae))
+* Ui_Formatting_fix ([06853be](https://gitlab.com/piveau/ui/piveau-ui/commit/06853befc95ee0169d082e9159a6956008bcddc0))
+
+
+
+## [4.5.6](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.5...v4.5.6) (2024-12-11)
+
+
+### Bug Fixes
+
+* **dpi:** improve label clarity for spatialinput ([b05a046](https://gitlab.com/piveau/ui/piveau-ui/commit/b05a04656c908bdc31790c2a3250c46e6c7df819))
+
+
+
+## [4.5.5](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.4...v4.5.5) (2024-12-09)
+
+
+### Bug Fixes
+
+* eurovoc clean ([627f9f8](https://gitlab.com/piveau/ui/piveau-ui/commit/627f9f82c57ebdc466c398f20fe82c720d349c7a))
+* uifix ([53d04f6](https://gitlab.com/piveau/ui/piveau-ui/commit/53d04f6649466841dbb65676be22d406f79d9ae6))
+
+
+
+## [4.5.4](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.3...v4.5.4) (2024-12-05)
+
+
+### Bug Fixes
+
+* only show visualize button on distributions with supported formats ([fddaae7](https://gitlab.com/piveau/ui/piveau-ui/commit/fddaae72f5d359bdd96edebdd04aeac369417eec))
+
+
+
+## [4.5.3](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.2...v4.5.3) (2024-12-05)
+
+
+### Bug Fixes
+
+* fix distribution format for visualisation tool ([0f97c41](https://gitlab.com/piveau/ui/piveau-ui/commit/0f97c41cb26e0770db5f6288715eda3bf493bad0))
+
+
+
+## [4.5.2](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.1...v4.5.2) (2024-12-04)
+
+
+### Bug Fixes
+
+* formating ([632dec0](https://gitlab.com/piveau/ui/piveau-ui/commit/632dec0d3d62bc710e6693523b09c17fb007c994))
+* userprofilefix ([0c0760b](https://gitlab.com/piveau/ui/piveau-ui/commit/0c0760baf6f562f67b114ace013e5401bdbbb64c))
+* userprofilepage ([b36c158](https://gitlab.com/piveau/ui/piveau-ui/commit/b36c15898268c9761c0326911db499aeb041c78e))
+
+
+
+## [4.5.1](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.5.0...v4.5.1) (2024-11-25)
+
+
+### Bug Fixes
+
+* **dpi:** remove debug information ([8b9bc2d](https://gitlab.com/piveau/ui/piveau-ui/commit/8b9bc2d1702d2f160009ff2e6563f81bc51eae6a))
+
+
+
+# [4.5.0](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.29...v4.5.0) (2024-11-25)
+
+
+### Bug Fixes
+
+* **dpi:** Fix Repeatable input elements not being displayed; address repeatable problems specific for SpatialInputs ([5ef443b](https://gitlab.com/piveau/ui/piveau-ui/commit/5ef443b61a42eae139e359376a895b3ad52bc20f))
+
+
+### Features
+
+* **DatasetDetails:** expose DatasetDetailsDataset through configureComponent; add slots to DatasetDetailsProperties ([7d5ad2b](https://gitlab.com/piveau/ui/piveau-ui/commit/7d5ad2b9fae1fc4f8dcc64065cedf886fbd0ff46))
+* **dpi:** make autocomplete implementation customizable; fix issue preventing license field not being resolved properly when editing ([b23c2b0](https://gitlab.com/piveau/ui/piveau-ui/commit/b23c2b0f6ab152d4f8964b13e17bc1986426f68b))
+
+
+
+## [4.4.29](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.28...v4.4.29) (2024-11-22)
+
+
+### Bug Fixes
+
+* quickfix for the legal notice ([ddd161b](https://gitlab.com/piveau/ui/piveau-ui/commit/ddd161b264299eb1a5332eff76db264f99bd545e))
+
+
+
+## [4.4.28](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.27...v4.4.28) (2024-11-20)
+
+
+### Bug Fixes
+
+* removed the details element ([b29e559](https://gitlab.com/piveau/ui/piveau-ui/commit/b29e5596beb8699bdcda66a94c2d5428f2dbdb7c))
+
+
+
+## [4.4.27](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.26...v4.4.27) (2024-11-19)
+
+
+### Bug Fixes
+
+* fixed the repeatable (addition and deletion of repeatable fields) ([81236d4](https://gitlab.com/piveau/ui/piveau-ui/commit/81236d49c49872e8503fc4d4a9b5cef9d1ef6482))
+* quickfix for the catalogue selection in harvested datasets ([00497b8](https://gitlab.com/piveau/ui/piveau-ui/commit/00497b8b230a4b876719a9f6980d77dd4d2cfad4))
+
+
+
+## [4.4.26](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.25...v4.4.26) (2024-11-18)
+
+
+### Bug Fixes
+
+* addedlegalnotice to overview tab ([2d1b6d1](https://gitlab.com/piveau/ui/piveau-ui/commit/2d1b6d18f886f47188269b4475a077a441f9d95a))
+
+
+
+## [4.4.25](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.24...v4.4.25) (2024-11-14)
+
+
+### Bug Fixes
+
+* **dpi:** fix dcatde prefix for dcat-ap.de spec ([9e123ce](https://gitlab.com/piveau/ui/piveau-ui/commit/9e123cebe63cf444a4a1f39b9463813036cf94b7))
+
+
+
+## [4.4.24](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.23...v4.4.24) (2024-11-12)
+
+
+### Bug Fixes
+
+* **dpi:** fix edit mode not working on direct navigation ([050118f](https://gitlab.com/piveau/ui/piveau-ui/commit/050118f796aad8b134be61b072e4ce96a323e4c5))
+* fix bug where visualisation is activated by clicking on wrong buttons ([2683786](https://gitlab.com/piveau/ui/piveau-ui/commit/268378624129d2bcbb9dea99786f5b04776e70a2))
+
+
+
+## [4.4.23](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.21...v4.4.23) (2024-11-08)
+
+
+### Bug Fixes
+
+* **dpi:** fix edge case temporal resolution causing edit mode to break ([f7e4cfc](https://gitlab.com/piveau/ui/piveau-ui/commit/f7e4cfc1c4dfcbcf07203159f39a6185f1c8dffe))
+* **dpi:** fix spatialinput to show vocabulary only ([43b6e89](https://gitlab.com/piveau/ui/piveau-ui/commit/43b6e89d86692f1be3b1ec85b1e28a180b6c3147))
+* **dpi:** fix UniqueIdentifierInput being sometimes disabled when creating new dataset ([bc58d60](https://gitlab.com/piveau/ui/piveau-ui/commit/bc58d60e3420149d77c62fa62e33c82c55d61b4d))
+* several fixes in the DPI (DKSR Feedback table) ([6868e0c](https://gitlab.com/piveau/ui/piveau-ui/commit/6868e0c21459d7855f7cddc6042f6f31578055e3))
+
+
+
+## [4.4.21](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.20...v4.4.21) (2024-11-06)
+
+
+### Bug Fixes
+
+* fix bug that visualisation tool appears on a click on 'Access' button ([a812c04](https://gitlab.com/piveau/ui/piveau-ui/commit/a812c047489a4303d15fb325d455874d2d99dcd4))
+
+
+
+## [4.4.20](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.19...v4.4.20) (2024-11-05)
+
+
+### Bug Fixes
+
+* fixed the AutocompleteInput and removed catalog restrictions for operators ([abceaef](https://gitlab.com/piveau/ui/piveau-ui/commit/abceaef9c9e0af24eb3f2fb8cb8a97539a350d1c))
+
+
+
+## [4.4.19](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.18...v4.4.19) (2024-10-31)
+
+
+
+## [4.4.18](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.17...v4.4.18) (2024-10-31)
+
+
+### Bug Fixes
+
+* **DatasetDetailsHeaderTitle:** fix a case where title is appended by dataset ID in separate h1 ([16776d8](https://gitlab.com/piveau/ui/piveau-ui/commit/16776d89280d44656085838b5ebb47cd67925f3f))
+
+
+
+## [4.4.17](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.16...v4.4.17) (2024-10-30)
+
+
+### Bug Fixes
+
+* **dpi:** use "-" instead of "Invalid Date" ([d5e3312](https://gitlab.com/piveau/ui/piveau-ui/commit/d5e33122d551c55dd1d8d5b25b4f90a1ae23e51e))
+
+
+
+## [4.4.16](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.15...v4.4.16) (2024-10-30)
+
+
+### Bug Fixes
+
+* **dpi:** properly apply localized strings for politicalGeocoding and spatial ([ef8f0f4](https://gitlab.com/piveau/ui/piveau-ui/commit/ef8f0f4083734f3870a0eb933bde186f96f5ed1d))
+
+
+
+## [4.4.15](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.14...v4.4.15) (2024-10-30)
+
+
+
+## [4.4.14](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.13...v4.4.14) (2024-10-29)
+
+
+
+## [4.4.13](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.12...v4.4.13) (2024-10-28)
+
+
+
+## [4.4.12](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.11...v4.4.12) (2024-10-24)
+
+
+### Bug Fixes
+
+* fixed the dcatapde specification (downloadURL was buggy) ([1b6f526](https://gitlab.com/piveau/ui/piveau-ui/commit/1b6f526befe24b94cb62e24292a34e123be8dcd9))
+* fixed the overview and the distribution input field of the DPI ([f1f70d9](https://gitlab.com/piveau/ui/piveau-ui/commit/f1f70d9814137c27b08b11f121b833a8740a70c1))
+* fixed the overview page of the dpi and added components to handle dcatapde properties ([1147d77](https://gitlab.com/piveau/ui/piveau-ui/commit/1147d7731c9ea1fa3330a3c112de6e510c5ec4c5))
+* quickfix for the distribution table ([bb672b2](https://gitlab.com/piveau/ui/piveau-ui/commit/bb672b2df415193471beb18cff933b5d94293f88))
+
+
+
+## [4.4.11](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.10...v4.4.11) (2024-10-24)
+
+
+### Bug Fixes
+
+* activate visualisation tool through button ([01b2b8a](https://gitlab.com/piveau/ui/piveau-ui/commit/01b2b8a527f0b17f4340e7e432c747abec9b2921))
+
+
+
+## [4.4.10](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.9...v4.4.10) (2024-10-21)
+
+
+### Bug Fixes
+
+* fixed the autocomplete and the conditionalinput ([f526d23](https://gitlab.com/piveau/ui/piveau-ui/commit/f526d2368ad421026a05e6c4d83c3e69e11922fd))
+
+
+
+## [4.4.9](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.7...v4.4.9) (2024-10-17)
+
+
+
+## [4.4.7](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.6...v4.4.7) (2024-10-16)
+
+
+### Bug Fixes
+
+* **dpi:** fix confirmation button not showing on form reset ([92b886f](https://gitlab.com/piveau/ui/piveau-ui/commit/92b886ffd67355fd9a0450db16525fb217949b9a))
+
+
+
+## [4.4.6](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.5...v4.4.6) (2024-10-16)
+
+
+### Bug Fixes
+
+* **dpi:** fix validation messages not showing properly for UniqueIdentifierInput ([298f5ae](https://gitlab.com/piveau/ui/piveau-ui/commit/298f5ae5805f286667c72badb21437ded4150f3d))
+
+
+
+## [4.4.5](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.4...v4.4.5) (2024-10-16)
+
+
+### Bug Fixes
+
+* **dpi:** fix language selector not responding ([d5beb02](https://gitlab.com/piveau/ui/piveau-ui/commit/d5beb02f2ade876e6446d789bacb04b9ae510f5c))
+* **dpi:** fix overview page not properly showing distribution properties on load ([8387753](https://gitlab.com/piveau/ui/piveau-ui/commit/8387753961ab3ba13703b1764fd28e5c034fe6aa))
+* updatedlicensetext ([d77e870](https://gitlab.com/piveau/ui/piveau-ui/commit/d77e870a07490ae6814eaa8d4425cd8efc701f20))
+
+
+
+## [4.4.4](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.3...v4.4.4) (2024-10-15)
+
+
+### Bug Fixes
+
+* edited the results of the autocompletes and excluded OP_DATPRO ([8541db9](https://gitlab.com/piveau/ui/piveau-ui/commit/8541db909a09c95ddf536e5632cb3078804edfa7))
+* fixed the spatial input (added translation paths) ([d721227](https://gitlab.com/piveau/ui/piveau-ui/commit/d721227a8b17b5e2a06cb849fca8eb65c334813b))
+* small fix in the license description field ([b764e55](https://gitlab.com/piveau/ui/piveau-ui/commit/b764e55ff0a57f8bde5a85eaddbf8b57b990efbb))
+* Updated the DPI License Text ([a1e0c0a](https://gitlab.com/piveau/ui/piveau-ui/commit/a1e0c0a1a4ff43dcaa8c1c1fc2a79cc925499532))
+
+
+
+## [4.4.3](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.2...v4.4.3) (2024-10-11)
+
+
+### Bug Fixes
+
+* **LanguageSelector:** use vue3 convention for v-model ([402252e](https://gitlab.com/piveau/ui/piveau-ui/commit/402252ef8307d26c5f6891ad6fd6ed1a1c9fbca4))
+* **OverviewPage:** properly localize OverviewPage ([efb4fae](https://gitlab.com/piveau/ui/piveau-ui/commit/efb4faea4b3b0ace7835eb0954e0f1a390208dae))
+
+
+
+## [4.4.2](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.1...v4.4.2) (2024-10-11)
+
+
+
+## [4.4.1](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.4.0...v4.4.1) (2024-10-11)
+
+
+### Bug Fixes
+
+* **SpatialInput:** localize hardcoded messages ([daae1fb](https://gitlab.com/piveau/ui/piveau-ui/commit/daae1fbbe50a05244e06b8adfb661a1b5503c097))
+
+
+
+# [4.4.0](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.14...v4.4.0) (2024-10-11)
+
+
+### Bug Fixes
+
+* **dpi:** fix query param conflict in edit mode ([e04d654](https://gitlab.com/piveau/ui/piveau-ui/commit/e04d6542e2fc237a3f935636713b1565728c0567))
+
+
+
+## [4.3.14](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.13...v4.3.14) (2024-10-10)
+
+
+
+## [4.3.13](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.12...v4.3.13) (2024-10-10)
+
+
+### Features
+
+* **dpi:** implement dpiContext prop for custom specifications ([0f83ef6](https://gitlab.com/piveau/ui/piveau-ui/commit/0f83ef63a591fd32c0d21ee21c4d4fdcdada7565))
+
+
+
+## [4.3.12](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.11...v4.3.12) (2024-10-10)
+
+
+
+## [4.3.11](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.10...v4.3.11) (2024-10-09)
+
+
+
+## [4.3.10](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.8...v4.3.10) (2024-10-02)
+
+
+
+## [4.3.8](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.7...v4.3.8) (2024-10-01)
+
+
+### Bug Fixes
+
+* hvd meta tag ([e5c7ec9](https://gitlab.com/piveau/ui/piveau-ui/commit/e5c7ec96f78eb3508c5b9cd004bd61f9aa35a553))
+
+
+
+## [4.3.7](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.6...v4.3.7) (2024-10-01)
+
+
+### Bug Fixes
+
+* hvd meta tag ([761c691](https://gitlab.com/piveau/ui/piveau-ui/commit/761c69128a9c2b62e0968950bab26cd40789c674))
+
+
+
+## [4.3.6](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.5...v4.3.6) (2024-09-26)
+
+
+### Bug Fixes
+
+* adding exclude uris field to knn_request ([27c8e6c](https://gitlab.com/piveau/ui/piveau-ui/commit/27c8e6c4dea5e070c96befb5e8a48835894d1692))
+* correct exclude uris field to knn_request ([46eaed9](https://gitlab.com/piveau/ui/piveau-ui/commit/46eaed92c1d799cbd43d061231670cb816f4b7f8))
+
+
+
+## [4.3.5](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.4...v4.3.5) (2024-09-26)
 # [100.0.0-alpha.0](https://gitlab.com/piveau/ui/piveau-ui/compare/v4.3.4...v100.0.0-alpha.0) (2024-10-10)
 
 
diff --git a/packages/piveau-hub-ui-modules/lib/catalogues/CatalogPage.vue b/packages/piveau-hub-ui-modules/lib/catalogues/CatalogPage.vue
index 19cc585b564ddf4a5e48b709a4eb39fa8055a961..9b77e1533c78b33f1d45a913aefece41beca790d 100644
--- a/packages/piveau-hub-ui-modules/lib/catalogues/CatalogPage.vue
+++ b/packages/piveau-hub-ui-modules/lib/catalogues/CatalogPage.vue
@@ -290,6 +290,7 @@ export default {
       this.$env.api.hubUrl,
       this.$env.api.qualityBaseUrl,
       this.$env.api.similarityBaseUrl,
+      this.$env.api.similarityServiceName,
       this.$env.content.datasets.facets.scoringFacets.defaultScoringFacets,
     );
 
@@ -314,7 +315,7 @@ export default {
       // We should refactor this code to use the store instead of making
       // a dedicated HTTP request for dataset search.
       // This will ensure that the most relevant datasets for the catalog are always displayed,
-      // even if the search page has filtered datasets. 
+      // even if the search page has filtered datasets.
       Axios.get(`${this.$env.api.baseUrl}search`, {
         params: {
           q: '',
@@ -539,4 +540,4 @@ export default {
     margin-left: 1.5rem;
   }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/composables/head/useDatasetDetailsDatasetHead.ts b/packages/piveau-hub-ui-modules/lib/composables/head/useDatasetDetailsDatasetHead.ts
index d2f569d3d62e3a9ae9009f1d3c13def02c888bcf..e4bf6f374bbacec3a4e73fe126585863b63b766b 100644
--- a/packages/piveau-hub-ui-modules/lib/composables/head/useDatasetDetailsDatasetHead.ts
+++ b/packages/piveau-hub-ui-modules/lib/composables/head/useDatasetDetailsDatasetHead.ts
@@ -22,7 +22,7 @@ function showKeyword(keyword: any) {
     && !isNil(keyword.title);
 }
 
-/** 
+/**
  * Returns a schema.org license object by providing dcat-ap license
  * See https://schema.org/license
  * See https://confluencesrv.fokus.fraunhofer.de/pages/viewpage.action?spaceKey=PIV&title=DCAT-AP+Guide
@@ -47,7 +47,7 @@ function getSchemaOfLicense(license: any) {
   return licenseObject;
 }
 
-/** 
+/**
  * Returns a json-ld object of the license of the first distribution where a license exists in this dataset
  * or null, if first distribution or license does not exist
  */
@@ -277,15 +277,22 @@ export function useDatasetDetailsDatasetHead() {
         name: 'robots',
         content: 'index',
       },
+      {
+        name: 'dataset_type',
+        content: () => {
+          // return store.getters['datasetDetails/getIsHvd'] ? 'High-Value Dataset' : 'Dataset';
+          return computed(() => (store.getters['datasetDetails/getIsHvd'] ? 'High-Value Dataset' : 'Dataset')).value;
+        }
+      }
     ],
     script: schemaOrg,
     link: [
       { rel: 'canonical', href: window.location.href },
     ],
   })
-  
+
   return {
     head,
     schemaOrg,
   }
-}
\ No newline at end of file
+}
diff --git a/packages/piveau-hub-ui-modules/lib/composables/useDataInfoBox.js b/packages/piveau-hub-ui-modules/lib/composables/useDataInfoBox.js
index 3aedd8d923a32ec4c36124d54b3467c859ecd8b0..640d7443abd17e09d2efa8d18657e2ea4bbb67ca 100644
--- a/packages/piveau-hub-ui-modules/lib/composables/useDataInfoBox.js
+++ b/packages/piveau-hub-ui-modules/lib/composables/useDataInfoBox.js
@@ -1,11 +1,13 @@
-import { computed, getCurrentInstance, unref } from "vue";
-import { getTranslationFor, truncate, getImg } from "../utils/helpers";
-import { toPairs, uniqBy, groupBy, has } from "lodash-es";
+import {computed, unref} from "vue";
+import {getImg, getTranslationFor, truncate} from "../utils/helpers";
+import {groupBy, has, toPairs, uniqBy} from "lodash-es";
+import {useRuntimeEnv} from "./useRuntimeEnv.ts";
 
 export function useDataInfoBox({ datasets, locale }) {
 
-  const vm = getCurrentInstance();
-  const $env = vm.proxy.$env;
+  // const vm = getCurrentInstance();
+  // const $env = vm.proxy.$env;
+  const $env = useRuntimeEnv();
 
   function getCatalogImage(catalog) {
     return $env.content.catalogs.useCatalogCountries
@@ -41,10 +43,9 @@ export function useDataInfoBox({ datasets, locale }) {
     const onlyFormatObjectsArray = sortedArray.map(arr => arr[1][0]);
     // lodash uniqBy funtion removes duplicate id´s from array of objects
     const uniqById = uniqBy(onlyFormatObjectsArray, "id");
-    const uniqByIdAndLabel = uniqBy(uniqById, "label");
-    return uniqByIdAndLabel;
+    return uniqBy(uniqById, "label");
   }
-  
+
   return computed(() => {
     const dsList = unref(datasets);
     const l = unref(locale);
@@ -68,4 +69,4 @@ export function useDataInfoBox({ datasets, locale }) {
       }
     })
   })
-}
\ No newline at end of file
+}
diff --git a/packages/piveau-hub-ui-modules/lib/composables/useTed.ts b/packages/piveau-hub-ui-modules/lib/composables/useTed.ts
new file mode 100644
index 0000000000000000000000000000000000000000..07e7314ebb2e62d31beffeced0b648974c541327
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/composables/useTed.ts
@@ -0,0 +1,22 @@
+import { computed, MaybeRefOrGetter, toValue } from 'vue';
+import { useI18n } from 'vue-i18n'
+
+/**
+ * A shorthand for `i18n.te(key) ? i18n.t(key) : def`.
+ *
+ * @example
+ * const ted = useTed()
+ * const label = ted('my-key', 'My Label')
+ * // label is computed and returns the translation for 'my-key' if it exists, otherwise 'My Label'
+ *
+ * @param {MaybeRefOrGetter<string>} key The key to translate
+ * @param {MaybeRefOrGetter<string>} def The default value if the key does not exist
+ * @returns {ComputedRef<string>} The translated value
+ */
+export function useTed() {
+  const { t, te } = useI18n();
+
+  const ted = (key: MaybeRefOrGetter<string>, def: MaybeRefOrGetter<string>) => computed(() => te(toValue(key)) ? t(toValue(key)) : toValue(def))
+
+  return ted
+}
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/configurations/configureComponents.ts b/packages/piveau-hub-ui-modules/lib/configurations/configureComponents.ts
index 8e99360240fdf2ccad0e8f3ee944ddcfb71a94f8..b1849ff383c61fd48bdc5171ef86db988105b35e 100644
--- a/packages/piveau-hub-ui-modules/lib/configurations/configureComponents.ts
+++ b/packages/piveau-hub-ui-modules/lib/configurations/configureComponents.ts
@@ -12,17 +12,20 @@ import SelectedFacetsOverview from "../facets/SelectedFacetsOverview.vue"
 import SubNavigation from "../navigation/SubNavigation.vue";
 import DatasetDetailsHeader  from "../datasetDetails/header/DatasetDetailsHeader.vue";
 import DatasetDetailsDescription from "../datasetDetails/DatasetDetailsDescription.vue";
+import DatasetDetailsDataset from "../datasetDetails/DatasetDetailsDataset.vue";
 import Distribution from "../datasetDetails/distributions/Distribution.vue";
 import DistributionActions from "../datasetDetails/distributions/distributionActions/DistributionActions.vue";
 import DatasetDetailsProperties from "../datasetDetails/properties/DatasetDetailsProperties.vue";
 import DatasetDetailsFeatures from "../datasetDetails/features/DatasetDetailsFeatures.vue";
 import DatasetDetailsFeatureHeader from "../datasetDetails/features/DatasetDetailsFeatureHeader.vue"
 import DistributionVisualisationSlot from "../datasetDetails/distributions/distributionPreview/DistributionVisualisationSlot.vue";
+import DownloadAllDistributions from "../datasetDetails/distributions/DownloadAllDistributions";
 
 export type ComponentMap = { [key: string]: any };
 
 const defaultComponents: ComponentMap = {
   SelectFacet: ExpandableSelectFacet,
+  DownloadAllDistributions,
   RadioFacet,
   PvShowMore,
   PvButton,
@@ -36,6 +39,7 @@ const defaultComponents: ComponentMap = {
   SubNavigation,
   DatasetDetailsHeader,
   DatasetDetailsDescription,
+  DatasetDetailsDataset,
   Distribution,
   DistributionActions,
   DatasetDetailsProperties,
@@ -47,7 +51,7 @@ const defaultComponents: ComponentMap = {
 export function configureComponents(app: any, components?: ComponentMap) {
   const allComponents: ComponentMap = { ...defaultComponents, ...components };
   const componentKeys: string[] = Object.keys(allComponents);
-  componentKeys.forEach((key: string) => { 
+  componentKeys.forEach((key: string) => {
     app.component(key, allComponents[key]);
   });
 }
diff --git a/packages/piveau-hub-ui-modules/lib/configurations/configureModules.ts b/packages/piveau-hub-ui-modules/lib/configurations/configureModules.ts
index 62d861f78741d8dea50283fd39db6cb3c920e650..9d0f640197a98ef5fc53a55cba0c72f96dcd6b3c 100644
--- a/packages/piveau-hub-ui-modules/lib/configurations/configureModules.ts
+++ b/packages/piveau-hub-ui-modules/lib/configurations/configureModules.ts
@@ -4,12 +4,16 @@ import { ComponentMap, configureComponents } from "./configureComponents";
 type ModulesConfig = {
   components: ComponentMap,
   serviceParams: {[key: string]: unknown},
+  customFacets: any
 };
 
+export const extras: {[key:string]: any} = {};
+
 export function configureModules(app: any, store: any, config?: ModulesConfig) {
   store.$app = app;
   if (config) {
-    configureServices(store, config.serviceParams);
-    configureComponents(app, config.components);
+    configureServices(store, config?.serviceParams);
+    configureComponents(app, config?.components);
   }
+  extras.customFacets = config?.customFacets
 }
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/CatalogueMQA.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/CatalogueMQA.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6eb9057b387e301ee8462c4e5b9674315625fe0f
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/CatalogueMQA.vue
@@ -0,0 +1,655 @@
+<template>
+    <div class="container mb-3">
+        <div>
+            <div>
+                <div class="debug">
+                    <strong> API object:</strong> <br><br>
+                    <!-- Disabled for PPE release (no backend on PPE yet)-->
+                    {{ notficationInfo }}
+
+                    <br> --- <br>
+
+                    {{ mailList }}
+
+                    <br>---<br>
+                    <strong>Fequency:</strong> <br>
+                    weekly: {{ weekly }}<br>
+                    monthly: {{ monthly }} <br>
+                    <p></p>
+                    unit: {{ frequencyUnit }} <br>
+                    value: {{ frequencyValue }}
+
+                    <br>---<br>
+                    treshold: {{ treshold }}
+
+                </div>
+                <h1>MQA Report Settings</h1>
+                <p>Configuration for
+
+                    <strong>{{ catalogId }}</strong>
+                    <!-- <strong>Test Catalogue</strong> -->
+                </p>
+                <p>For this Catalogue the <b>MQA Rating Checks </b>are currently <b>
+                        <span v-if="!active">deactivated</span>
+                        <span v-if="active">activated</span></b>.</p>
+            </div>
+
+            <button type="button"  :class="{ 'btn btn-primary mb-5': !active, 'btn btn-secondary': active }" @click="handleActivate()">
+                {{ activatedString }}
+            </button>
+        </div>
+       
+        <div v-if="active">
+            <div class="mqaWrapper" >
+                <h3>Recipients Mail</h3>
+                <span>Add and edit mail addresses for recieving the MQA report</span>
+                <table class="mt-4" ref="mailButtonWrap" v-if="mailList.length != 0">
+                    <tr>
+                        <th>Mail</th>
+                    </tr>
+                    <tr v-for="(item, index) in mailList" class="mailItems" :key="index">
+                        <td>
+                            <span v-if="!editMode">{{ item }}</span>
+                            <input type="text" v-model="mailList[index]" class="mail-input" v-if="editMode"
+                                @input="editErrors[index] = ''"
+                                :class="{ 'invalidNewMail': editErrors[index] }" >
+                              
+                            <div>
+                                <button type="button" class="btn btn-simple"
+                                    @click="editMode ? saveMail(index) : editMail(index)">
+                                    {{ editMode ? 'Save' : 'Edit' }}
+                                </button>
+                                <button type="button" class="btn btn-simple"
+                                    @click="deleteMail(index)">Delete</button>
+                            </div>
+                        </td>
+                        <span class="errormsg" v-if="editErrors[index]">{{ editErrors[index] }}</span>
+                    </tr>
+                </table>
+                <div class="d-flex mt-3">
+                    <input type="text" v-model="newMail.mail" @input="newMail.isValid = true"
+                        :class="{ 'invalidNewMail': !newMail.isValid }" placeholder="Enter email address"
+                        class="mail">
+                    <button type="button" class="btn btn-simple mx-3" @click="addNewMail()">+ Add Mail</button>
+                </div>
+                <span class="errormsg" v-if="!newMail.isValid">*Invalid email format</span>
+            </div>
+            <div class="mqaWrapper">
+                <h3>Frequency of Rating Checks</h3>
+                <span>Configure the frequency of the MQA rating checks.</span>
+
+                <div class="d-flex mt-3">
+                    <div class="mr-3 my-3">
+                        <button type="button" class="btn btn-simple" @click="setWeekly()"
+                            :class="{ 'activeChoiceButton': weekly }">Weekly</button>
+                        <div class="weekdays" :class="{ 'blur': !weekly }">
+                            <span v-for="(day, index) in week" :key="index">
+                                <button :disabled="!weekly" class="dayButtons"
+                                    :class="{ 'activeItem': selectedDay === index }" @click="selectDay(index)">
+                                    {{ day }}
+                                </button>
+                            </span>
+                        </div>
+                    </div>
+                    <div class="my-3">
+                        <button type="button" :class="{ 'activeChoiceButton': monthly }" class="btn btn-simple"
+                            @click="setMonthly()">Monthly</button>
+                        <div class="d-flex daypicker my-3" :class="{ 'blur': !monthly }">
+                            <input v-model="daysInMonth" @input="selectDay(index)" :class="{ dynamicWidth: inputWidth }"
+                                :disabled="!monthly">
+                            <div class="caretWrap">
+                                <button @click="editDate('up')" class="caretButtons ml-1"><svg
+                                        xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor"
+                                        class="bi bi-caret-up-fill" viewBox="0 0 16 16">
+                                        <path
+                                            d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z" />
+                                    </svg></button>
+                                <button @click="editDate()" class="caretButtons mr-1"><svg
+                                        xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor"
+                                        class="bi bi-caret-down-fill" viewBox="0 0 16 16">
+                                        <path
+                                            d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z" />
+                                    </svg></button>
+                            </div>
+                            <span>day of the month</span> 
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="mqaWrapper">
+                <h3>Notification Treshold</h3>
+                <span>Set the threshold for triggering the report.</span>
+                <div class="w-50 mt-3">
+                    <div class="d-flex justify-content-between">
+                        <span><b>0</b></span>
+                        <span><b>400</b></span>
+                    </div>
+                    <input type="range" v-model="treshold" min="0" max="400" />
+                    <p>Lower than <b>{{ treshold }}</b> Points</p>
+                </div>
+            </div>
+            <div class="actionWrapper">
+                <button type="button" class="btn btn-primary" @click="postNotificationSettings">Save</button>
+                <button type="button" class="btn btn-cancel" @click="back()">Cancel</button>
+            </div>
+        </div>
+    </div>
+
+</template>
+<script setup>
+
+import { ref } from 'vue';
+import { useRoute } from 'vue-router'
+import { getCurrentInstance } from "vue";
+import { useStore } from 'vuex';
+import { useRouter } from 'vue-router';
+
+
+import axios from 'axios'
+
+const store = useStore();
+const router = useRouter();
+
+const showSnackbar = (payload) => {
+  store.dispatch('snackbar/showSnackbar', payload);
+};
+
+
+const triggerSnackbar = () => {
+            showSnackbar({
+                message: 'Saved Successfully',
+                variant: 'success',
+            });
+            };
+
+// Map the showSnackbar action from the snackbar module
+
+const route = useRoute()
+
+let monthly = ref(false)
+let weekly = ref(false)
+let mailButtonWrap = ref(null)
+let activatedString = ref('Activate')
+let inputWidth = ref(false)
+let active = ref(false)
+let mailList = ref()
+let week = ['Mo', 'Tue', 'We', 'Th', 'Fr', 'Sa', 'Su']
+let daysInMonth = ref(1)
+let editMode = ref(false);
+let treshold = ref(0);
+let frequencyUnit = ref('');
+let frequencyValue = ref('');
+let selectedDay = ref(null);
+const catalogId = route.params.id
+const app = getCurrentInstance()
+const notificationBaseUrl = app.appContext.app.config.globalProperties.$env.api.notificationBaseUrl
+const apiKey = app.appContext.app.config.globalProperties.$env.api.apiKey
+
+const selectDay = (index) => {
+    if (weekly.value) {
+        selectedDay.value = index;
+        frequencyValue.value = selectedDay; // Update frequencyValue when a day is selected
+    } 
+};
+
+const setWeekly = () => {
+    weekly.value = true;
+    monthly.value = false;
+    selectedDay.value = frequencyValue.value; // Set the selected day based on frequencyValue
+};
+
+const setMonthly = () => {
+    weekly.value = false;
+    monthly.value = true;
+    selectedDay.value = frequencyValue.value; // Set the day of the month based on frequencyValue
+};
+
+const notficationInfo = ref({})
+
+const isValidEmail = (email) => {
+    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+    return regex.test(email);
+};
+
+let newMail = ref({ mail: '', isValid: true });
+let editErrors = ref({});
+
+// enabeld for PPE release (dummy data)
+//  mailList.value = [{ 'mail': "mail@mail2.com" }, { 'mail': "mail@mail1.com" }]
+
+const fetchNotificationInfo = async () => {
+    const config = {
+        method: 'get',
+        url: `${notificationBaseUrl}/catalogue/${catalogId}/setting`,
+        headers: {
+            'Authorization': apiKey,
+            'Accept': 'application/json',
+        },
+        withCredentials: true
+    }
+
+    try {
+        const response = await axios.request(config)
+        notficationInfo.value = response.data
+
+        if (notficationInfo.value.activeStatus === true) {
+            active.value = true
+            activatedString.value = 'Deactivate'
+        } if (notficationInfo.value.activeStatus === false) {
+            active.value = false
+            activatedString.value = 'Activate'
+        }
+
+        mailList.value = notficationInfo.value.receiverEmailList
+        frequencyUnit.value = notficationInfo.value.frequency.unit
+        frequencyValue.value = notficationInfo.value.frequency.value
+        treshold.value = notficationInfo.value.threshold
+
+        if (frequencyUnit.value === 'week') {
+            weekly.value = true
+            monthly.value = false
+            selectedDay.value = frequencyValue.value; // Set the selected day based on frequencyValue
+        } else if (frequencyUnit.value === 'month') {
+            weekly.value = false
+            monthly.value = true
+            daysInMonth.value = frequencyValue.value
+        }
+
+        console.log('Response:', response)
+    } catch (error) {
+        console.log('Full error:', error)
+    }
+}
+
+const postNotificationSettings = async () => {
+
+    if (weekly.value === true) {
+        frequencyUnit.value = "week"
+        frequencyValue.value = selectedDay.value
+    } else if (monthly.value === true) {
+        frequencyUnit.value = "month"
+        frequencyValue.value = daysInMonth.value
+    }
+
+    const config = {
+        method: 'post',
+        url: `https://piveau-metrics-notifications-piveau.apps.osc.fokus.fraunhofer.de/catalogue/${catalogId}/setting`,
+        headers: {
+            'Authorization': apiKey,
+            'Accept': 'application/json',
+            'Content-Type': 'application/json',
+            'Access-Control-Allow-Origin': '*',
+            'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
+            'Access-Control-Allow-Headers': 'Authorization'
+        },
+        withCredentials: true,
+        data: JSON.stringify({
+            receiverEmailList: mailList.value,
+            threshold: Number(treshold.value),
+            frequency: {
+                unit: frequencyUnit.value,
+                value: frequencyValue.value
+            },
+            activeStatus: true
+        })
+    }
+
+    try {
+        const response = await axios.request(config)
+        console.log('Settings updated:', response.data)
+        triggerSnackbar();
+        router.push({ name: 'DataProviderInterface-UserCatalogues' });
+        return response.data
+       
+
+    } catch (error) {
+        triggerSnackbar({
+        message: 'Error updating settings.',
+        variant: 'error',
+      });
+
+        console.log('Error updating settings:', error)
+        
+        throw error
+        
+    }
+   
+
+}
+
+fetchNotificationInfo()
+
+const postDeactive = async () => {
+
+    const config = {
+        method: 'post',
+        url: `https://piveau-metrics-notifications-piveau.apps.osc.fokus.fraunhofer.de/catalogue/${catalogId}/setting`,
+        headers: {
+            'Authorization': apiKey,
+            'Accept': 'application/json',
+            'Content-Type': 'application/json',
+            'Access-Control-Allow-Origin': '*',
+            'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
+            'Access-Control-Allow-Headers': 'Authorization'
+        },
+        withCredentials: true,
+        data: JSON.stringify({
+            activeStatus: active.value
+        })
+    }
+
+    try {
+        const response = await axios.request(config)
+        console.log('Settings updated:', response.data)
+        triggerSnackbar();
+        if(!active.value) {router.push({ name: 'DataProviderInterface-UserCatalogues' });}
+        return response.data
+       
+
+    } catch (error) {
+        triggerSnackbar({
+        message: 'Error updating settings.',
+        variant: 'error',
+      });
+
+        console.log('Error updating settings:', error)
+        
+        throw error
+        
+    }
+}
+
+const editMail = () => {
+    editMode.value = true
+    showSnackbar({
+      message: 'Email added successfully.',
+      variant: 'success',
+    });
+}
+
+const saveMail = (index) => {
+    const email = mailList.value[index].trim();
+    if (isValidEmail(email)) {
+        editMode.value = false;
+        delete editErrors.value[index];
+    } else {
+        editErrors.value[index] = '*Invalid email format';
+    }
+};
+
+const deleteMail = (index) => {
+        mailList.value.splice(index, 1);
+}
+
+const editDate = (count) => {
+    if (count === "up" && daysInMonth.value < 28) {
+        if (daysInMonth.value > 8) {
+            inputWidth.value = true
+        }
+        daysInMonth.value++
+    }
+    else if (daysInMonth.value > 1) {
+        if (daysInMonth.value < 11) {
+            inputWidth.value = false
+        }
+        daysInMonth.value--
+    }
+}
+
+const addNewMail = () => {
+    if (newMail.value.mail.trim() === '') {
+        newMail.value.isValid = false;
+        return;
+    }
+    if (isValidEmail(newMail.value.mail)) {
+        mailList.value.push(newMail.value.mail);
+        newMail.value.mail = ''; // Clear input after successful addition
+        newMail.value.isValid = true;
+    } else {
+        newMail.value.isValid = false;
+    }
+}
+const handleActivate = () => {
+    if (!active.value) {
+        active.value = true
+        activatedString.value = 'Deactivate'
+        postDeactive()
+    } else {
+        active.value = false
+        activatedString.value = 'Activate'
+        postDeactive()
+    }
+}
+
+const back = () => {
+    router.push({ name: 'DataProviderInterface-UserCatalogues' });
+}
+
+</script>
+<style scoped>
+.debug {
+    position: fixed;
+    right: 20px;
+    top: 20px;
+    border-radius: 20px;
+    width: 400px;
+    z-index: 999999;
+    padding: 20px;
+    background: rgba(255, 255, 255, 0.2);
+    border-radius: 16px;
+    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
+    backdrop-filter: blur(5px);
+    -webkit-backdrop-filter: blur(5px);
+    border: 1px solid rgba(255, 255, 255, 0.3);
+    display: none; 
+}
+
+.btn-simple {
+    border-color: rgb(115, 115, 115);
+}
+
+.btn-cancel {
+    border-color: transparent;
+}
+
+.mail {
+    width: 270px;
+    padding: 5px 5px 5px 10px;
+}
+
+
+.errormsg {
+    color: red;
+    font-size: 10px;
+}
+
+.activeChoiceButton {
+    background-color: var(--primary);
+    color: white;
+    border-color:  var(--primary);
+
+    &:active {
+        background-color: #3E6CD5 !important;
+    }
+
+    &:focus {
+        outline: none;
+        background-color: #3E6CD5;
+    }
+
+    &:focus-visible {
+        outline: none;
+        background-color: #3E6CD5;
+    }
+}
+
+
+.invalid {
+    border-bottom: 1px solid red !important;
+}
+
+.blur {
+    opacity: 0.3;
+}
+
+.invalidNewMail {
+
+    border-radius: 2px;
+    border: 2px solid rgba(255, 0, 0, 0.336);
+
+    &:focus {
+        border-radius: 2px;
+        box-shadow: 0 0 0 0.1rem rgba(255, 0, 0, 0.774);
+        border: 1px solid rgba(255, 0, 0, 0.336);
+    }
+
+    &:focus-visible {
+        outline: 0;
+        border-radius: 2px;
+        box-shadow: 0 0 0 0.1rem rgba(255, 0, 0, 0.774);
+        border: 1px solid rgba(255, 0, 0, 0.336);
+    }
+}
+
+.editable {
+    transition: all 200ms ease-in-out;
+    padding-left: 0.5rem;
+    border-bottom: 2px solid var(--primary) !important;
+}
+
+.invalid {
+    border-bottom: 1px solid red !important;
+}
+
+.caretButtons {
+    all: unset;
+    cursor: pointer;
+}
+
+.caretWrap {
+    display: contents;
+
+}
+
+.actionWrapper {
+    display: flex;
+    flex-direction: row-reverse;
+    margin-bottom: 100px;
+
+    button {
+        margin-left: 1rem;
+    }
+}
+
+input[type="range"] {
+    width: 100%;
+}
+
+.mqaWrapper {
+    margin: 3rem 0;
+}
+
+table {
+    margin-top: 1rem;
+    min-width: 50%;
+}
+
+th {
+    border-bottom: 1px solid lightgray;
+}
+
+td {
+    display: flex;
+    justify-content: space-between;
+    padding: 15px 0 0 0cap;
+}
+
+.daypicker {
+    padding: 1rem;
+    border: 1px solid lightgray;
+    border-radius: 15px;
+
+    input {
+        width: 25px;
+        border: none;
+        background-color: unset;
+        font-weight: 700;
+    }
+
+}
+
+.dynamicWidth {
+    width: 22px !important;
+}
+
+.activeItem {
+    background-color: var(--primary);
+    color: white;
+}
+
+.weekdays {
+    border: 1px solid lightgray;
+    border-radius: 15px;
+    margin: 1rem 0;
+    overflow: hidden;
+
+    .dayButtons {
+        border: none;
+        display: inline-block;
+        text-align: center;
+        flex-direction: row;
+        min-width: 60px;
+        padding: 1rem;
+        border-right: 1px solid lightgray;
+        cursor: pointer;
+
+        &:focus-visible {
+            outline: unset;
+            background-color: #3E6CD5;
+            color: white;
+        }
+
+        &:hover {
+            background-color: #3E6CD5;
+            color: white;
+        }
+    }
+
+    span:last-child button {
+        border: none;
+    }
+}
+
+.mqaWrapper {
+    padding: 1rem;
+    background-color: #f3f6fc;
+    border-radius: 3px;
+}
+
+button {
+    background-color: unset;
+    border: 1px solid var(--primary);
+    color: black;
+
+    &:hover {
+        background-color: #3E6CD5;
+        color: white;
+        border: 1px solid #3E6CD5;
+    }
+}
+
+.btn-primary {
+    background-color: var(--primary);
+    color: white;
+
+}
+
+.btn-secondary {
+    color: #0e47cb;
+}
+
+button,
+span {
+    transition: all 100ms ease-in-out;
+}
+</style>
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/DPIMenu.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/DPIMenu.vue
index 9dc2fa1557ed8bab25fd760d003c65455cd233dc..694b66bf341946e742748f452bedccfbc63e5e18 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/DPIMenu.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/DPIMenu.vue
@@ -11,7 +11,7 @@
         <router-link :to="{ name: 'DPI-Comp-Lib' }">Component Library</router-link>
       </button>
       <div style="margin-top:1%;">
-        <dropup v-for="(group, index) in menuGroups"  :key="`Group${index}`" :groupName="group.group"
+        <dropup v-for="(group, index) in menuGroups" :key="`Group${index}`" :groupName="group.group"
           :groupItems="group.items" :show="$env.content.dataProviderInterface.buttons[group.group]"
           :isOperator="getUserData.roles.includes('operator')" :isCatalog="group.group === 'Catalogue' ? true : false">
         </dropup>
@@ -37,7 +37,7 @@
         <slot name="right" :get-user-data="getUserData">
           <small class="text-white">{{ $t('message.dataupload.menu.loggedInAs') }} {{ getUserData.userName
             }}</small>
-            <br>
+          <br>
           <button type="button" class="btn btn-default logout">
             <router-link :to="{ name: 'Logout' }">{{ $t('message.dataupload.menu.logout') }}</router-link>
           </button>
@@ -147,7 +147,7 @@ export default {
                 },
               },
             },
-           
+
             {
               key: 'draft-dataset',
               name: 'setToDraft',
@@ -275,9 +275,9 @@ export default {
       if (!onCatalogPage) return false;
       const catalogId = onCatalogPage && this.$route.params.ctlg_id;
 
-      const permissions = this.getUserData && this.getUserData.permissions;
-      const hasPermission = permissions.find(permission => permission.rsname === catalogId);
-
+      // const permissions = this.getUserData && this.getUserData.permissions;
+      // const hasPermission = permissions.find(permission => permission.rsname === catalogId);
+      const hasPermission = true
       // does user have permission on current catalogue
       return hasPermission && onCatalogPage;
     }
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/DataProviderInterface.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/DataProviderInterface.vue
index c7e71f6365b0c85bb8ce7daae6bf6becf6e373ae..e24e111101cdc30d61f742521f420d1c0d79466a 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/DataProviderInterface.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/DataProviderInterface.vue
@@ -11,23 +11,44 @@
   <div class="dpi dpiV3_dpi"
     :key="property">
     <!-- CONTENT -->
-    <router-view ref="view" :key="$route.query.edit">
+    <router-view v-if="isReady" ref="view" :key="key">
     </router-view>
   </div>
 </template>
 
-<script>
+<script lang="ts">
 /* eslint-disable no-nested-ternary, no-lonely-if, no-param-reassign */
-import { defineAsyncComponent } from 'vue';
-import { mapActions, mapGetters } from 'vuex';
+import { DpiContext, setupDpiContext } from './composables/useDpiContext';
+import { computed, defineAsyncComponent, defineComponent, PropType , provide, ref, toRef, toRefs, toValue, watch, watchEffect} from 'vue';
+import { mapActions, mapGetters, useStore } from 'vuex';
+import dpiSpecs from './config/dpi-spec-config';
+import { useRuntimeEnv } from '../composables/useRuntimeEnv';
+import { useRoute } from 'vue-router';
+import { useAsyncState, watchOnce } from '@vueuse/core';
+import { useDpiEditMode } from './composables/useDpiEditMode';
+import { AutocompleteInstance, autocompleteKey, defaultAutocompleteAdapter, useAutocomplete } from './composables/aucotomplete';
 
 
-export default {
+
+export default defineComponent({
   name: 'DataProviderInterface',
   components: {
-    InputPage: defineAsyncComponent(() => import('./views/InputPage')),
+    InputPage: defineAsyncComponent(() => import('./views/InputPage.vue')),
+  },
+  props: {
+    name: {
+      type: String,
+      default: '',
+    },
+    dpiContext: {
+      type: Object as PropType<DpiContext>,
+      default: () => undefined,
+    },
+    autocomplete: {
+      type: Object as PropType<AutocompleteInstance>,
+      default: () => undefined,
+    }
   },
-  props: ['name'],
   metaInfo() {
     return {
       title: `${this.$t('message.metadata.upload')} | ${this.$t('message.header.navigation.data.datasets')}`,
@@ -72,11 +93,11 @@ export default {
     },
     handleScroll() {
       try {
-        if (document.getElementById("stepperAnchor").offsetTop >= 35) {
-          document.getElementById("stepperAnchor").classList.add("border-bottom-lightgray");
+        if (document.getElementById("stepperAnchor")?.offsetTop || 0 >= 35) {
+          document.getElementById("stepperAnchor")?.classList.add("border-bottom-lightgray");
         }
         else {
-          document.getElementById("stepperAnchor").classList.remove("border-bottom-lightgray");
+          document.getElementById("stepperAnchor")?.classList.remove("border-bottom-lightgray");
         }
       } catch (error) {
 
@@ -96,7 +117,63 @@ export default {
     window.removeEventListener('scroll', this.handleScroll);
 
   },
-};
+  setup(props) {
+    const route = useRoute()
+    const store = useStore()
+    const env = useRuntimeEnv()
+    const userSpec = env.content.dataProviderInterface.specification as 'dcatap' | 'dcatapde' | 'dcatapdeODB'
+    const fallbackSpec = dpiSpecs[userSpec]
+    const dpiContext = toRef(props, 'dpiContext')
+
+    const resolvedDpiContext = computed<DpiContext>(() => {
+      const _dpiContext = toValue(dpiContext)
+
+      return {
+        specification: fallbackSpec,
+        specificationName: userSpec,
+        edit: {
+          enabled: route.query.edit === 'true',
+          id: route.query.id as string || undefined,
+          fromDraft: route.query.fromDraft === 'true',
+        },
+        ..._dpiContext
+      }
+    })
+
+    const specification = computed(() => {
+      return resolvedDpiContext.value.specification
+    })
+
+    const specificationName = computed(() => {
+      return resolvedDpiContext.value.specificationName
+    })
+
+    setupDpiContext(resolvedDpiContext)
+    const defaultAutocompleteInstance = defaultAutocompleteAdapter({
+      envs: env,
+      dpiContext: resolvedDpiContext
+    });
+    provide(autocompleteKey, props.autocomplete || defaultAutocompleteInstance.adapter);
+
+    watchEffect(() => {
+      store.dispatch('dpiStore/setSpecification', specification.value)
+      store.dispatch('dpiStore/setSpecificationname', specificationName.value)
+    })
+
+    const key = computed(() => {
+      return `${route.query.key}@${specificationName.value}`
+    })
+
+    const { isReady } = useDpiEditMode(resolvedDpiContext)
+
+    return {
+      resolvedDpiContext,
+      key,
+      isReady,
+    }
+
+  }
+});
 </script>
 
 <style lang="scss">
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/AutocompleteInput.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/AutocompleteInput.vue
index 1b6854e267539bfd2fc1c12f7117f40576e44257..c7ce83c8167579e597767387af496b1c6e015454 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/AutocompleteInput.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/AutocompleteInput.vue
@@ -6,8 +6,8 @@
     <h4 class="formkitHeader" v-if="inDis">
       {{ $t('message.dataupload.distributions.' + props.context.attrs.identifier + '.label') }}
     </h4>
-    <h4 v-if="props.context.attrs.identifier != 'licence' && !inDis">{{ $t('message.dataupload.datasets.' +
-      props.context.attrs.identifier + '.label') }}</h4>
+    <h4 v-if="props.context.attrs.identifier != 'licence' && !inDis" v-html="$t('message.dataupload.datasets.' + props.context.attrs.identifier + '.label')">
+      </h4>
 
     <div class="formkitCmpWrap">
 
@@ -24,9 +24,11 @@
             <!-- <div class="infoI">
               <div class="tooltipFormkit">{{ props.context.attrs.info }}</div>
             </div> -->
-            <input class="autocompleteInputfield" :placeholder="props.context.attrs.placeholder" v-model="inputText"
+
+            <input ref="acInput" class="autocompleteInputfield" :placeholder="props.context.attrs.placeholder" v-model="inputText"
               type="text" v-on:keyup="getAutocompleteSuggestions($event)" @click="activeList = !activeList">
           </div>
+
           <ul ref="dropdownList" v-show="activeList" class="autocompleteResultList">
             <li v-for="match in matches" :key="match" @click="setValue(match); activeList = !activeList"
               class="p-2 border-b border-gray-200 data-[selected=true]:bg-blue-100 choosableItemsAC">{{ match.name }}
@@ -44,7 +46,7 @@
             </div>
             <div class="w-100 mt-4">
               <div class="d-flex justify-content-between align-items-center flex-wrap">
-                <h3>{{ props.context.label }} - {{ $t('message.dataupload.info.suggestions') }}</h3>
+                <h3>{{ $t('message.dataupload.info.suggestions') }}</h3>
                 <span>{{ $t('message.dataupload.info.suggestionText') }}</span>
                 <button class="navlikeButton" type="button"
                   @click="fillAnnifsuggestions(); annifTrigger.value = true">{{ $t('message.dataupload.info.tryIt')
@@ -70,9 +72,14 @@
               <div class="removeX" @click="removeMultipleProperty(item)"></div>
             </div>
           </div>
-          <div class="formkit-wrapper">
-            <div class="formkit-help">{{ props.context.help }}</div>
-          </div>
+
+
+          <!-- <div class="formkit-wrapper mb-3">
+            <div v-html="$t('message.dataupload.distributions.licence.vocabulary.help')" class="formkit-help"> 
+            </div> 
+          </div> -->
+
+          <div v-html="props.context.attrs.info" class="formkit-help"></div>
         </div>
       </div>
     </div>
@@ -89,14 +96,17 @@ import { useI18n } from 'vue-i18n';
 
 import qs from 'qs';
 import axios from 'axios';
+import { useAutocomplete } from '../composables/aucotomplete';
 
 let instance = getCurrentInstance().appContext.app.config.globalProperties.$env
 
+const { requestAutocompleteSuggestions, requestResourceName } = useAutocomplete()
+
 const props = defineProps({
   context: Object
 })
 const store = useStore();
-const { t,locale } = useI18n();
+const { t, locale } = useI18n();
 
 let listOfValues = computed(() => {
   return props.context.value;
@@ -116,6 +126,7 @@ let matches = ref({
 })
 let activeList = ref()
 let dropdownList = ref(null)
+let acInput = ref(null)
 let inputText = ref({})
 let cacheList = [];
 let annifList = [];
@@ -151,7 +162,7 @@ const requestURIname = async (res) => {
 
     let name;
 
-    await store.dispatch('dpiStore/requestResourceName', { voc: voc, uri: res, envs: instance }).then(
+    await requestResourceName({ voc: voc, uri: res, envs: instance }).then(
       (response) => {
         if (props.context.attrs.property === 'dcatde:politicalGeocodingURI') {
           if (response != undefined) {
@@ -159,7 +170,7 @@ const requestURIname = async (res) => {
               ? response.data.result.results
                 .filter((dataset) => dataset.resource === res)
                 .map((dataset) => dataset.alt_label)[0].en
-              : getTranslationFor(response.data.result.alt_label, 'en', []);
+              : getTranslationFor(response.data.result.alt_label, locale.value, []);
             name = result;
           }
         } else {
@@ -169,7 +180,7 @@ const requestURIname = async (res) => {
               ? response.data.result.results
                 .filter((dataset) => dataset.resource === res)
                 .map((dataset) => dataset.pref_label)[0].en
-              : getTranslationFor(response.data.result.pref_label, 'en', []);
+              : getTranslationFor(response.data.result.pref_label, locale.value, []);
             name = result;
 
           }
@@ -240,6 +251,8 @@ function findPropertyToUpdate(trigger) {
   window.removeEventListener("click", onClickOutside);
 }
 onClickOutside(dropdownList, event => activeList.value = false)
+onClickOutside(acInput, event => inputText.value = "")
+
 let annifHandlerTheme = async (input, limit) => {
 
   let finalLimit = 10;
@@ -269,10 +282,10 @@ let annifHandlerTheme = async (input, limit) => {
 
   axios(config)
     .then(async (response) => {
-     
+
       for (let i = 0; i < response.data.results.length; i++) {
-        
-        
+
+
         annifList[i] = { "name": response.data.results[i].label, "resource": response.data.results[i].uri, "activeValue": false }
       }
       let annifCacheList = []
@@ -338,6 +351,7 @@ const fillAnnifsuggestions = async (limitChange) => {
 props.context.classes.outer += ' autocompleteInput ' + props.context.attrs.identifier
 
 const setValue = async (e) => {
+  inputText.value = ""
   if (Object.keys(e).length === 1) {
     return
   }
@@ -375,11 +389,11 @@ const setValue = async (e) => {
 
 const getAutocompleteSuggestions = async (e) => {
   let innerText = e.target.value
-console.log(locale);
-
+  await requestAutocompleteSuggestions({ voc, text: innerText, base: instance.api.baseUrl }).then((response) => {
+    // filter OP_DATPRO
+    const updatedArray = response.data.result.results.filter(obj => obj.id !== 'OP_DATPRO');
 
-  await store.dispatch('dpiStore/requestAutocompleteSuggestions', { voc: voc, text: innerText, base: instance.api.baseUrl }).then((response) => {
-    const results = response.data.result.results.map((r) => ({
+    const results = updatedArray.map((r) => ({
       name: getTranslationFor(r.pref_label, locale.value, []) + " (" + r.id + ")",
       resource: r.resource,
     }));
@@ -408,4 +422,4 @@ function removeMultipleProperty(e) {
   props.context.node.input(selection);
   findPropertyToUpdate();
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/ConditionalInput.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/ConditionalInput.vue
index 610793c47140dae36cf1ff849f421d6eeb09ef6d..b4bd09608738ebb6fde2f6fed5ca1ded0d7dceda 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/ConditionalInput.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/ConditionalInput.vue
@@ -18,30 +18,29 @@
           d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0" />
       </svg>
       <div class="w-80">
-        <p>For <strong>European</strong>&nbsp;<strong>Commission's datasets</strong>, bear in mind that&nbsp;<a
-            class="external-link" href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32011D0833"
-            target="_blank" rel="nofollow noopener"><ins>Decision 2011/833/EU</ins></a>] allows for their commercial
-          reuse without prior authorisation, except for the material subject to the third party intellectual property
-          rights. This Decision has been implemented under the&nbsp;<a class="external-link"
-            href="https://ec.europa.eu/transparency/documents-register/detail?ref=C(2019)1655&amp;lang=en"
-            target="_blank" rel="nofollow noopener"><ins>Decision C(2019) 1655 final</ins></a>] by which Creative
-          Commons Attribution 4.0 International Public License (CC BY 4.0) is adopted as an open licence for the
-          Commission's reuse policy. Additionally, raw data, metadata or other documents of comparable nature may
-          alternatively be distributed under the provisions of the Creative Commons Universal Public Domain Dedication
-          deed (CC0 1.0).</p>
+        <p>For&nbsp;<strong>European</strong>&nbsp;<strong>Commission's datasets</strong>, bear in mind
+          that&nbsp;&nbsp;<a href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32011D0833]"
+            target="_blank" rel="nofollow noopener"><ins>Decision 2011/833/EU</ins></a> allows for their commercial
+          reuse without
+          prior authorisation, except for the material subject to the third party intellectual property rights. This
+          Decision has been implemented under the&nbsp;&nbsp;<a
+            href="https://ec.europa.eu/transparency/documents-register/detail?ref=C(2019)1655&amp;lang=en]"
+            target="_blank" rel="nofollow noopener"><ins>Decision C(2019) 1655 final</ins></a>&nbsp; by which Creative
+          Commons
+          Attribution 4.0 International Public License (CC BY 4.0) is adopted as an open licence for the Commission's
+          reuse policy. Additionally, raw data, metadata or other documents of comparable nature may alternatively be
+          distributed under the provisions of the Creative Commons Universal Public Domain Dedication deed (CC0
+          1.0).</p>
         <p>The&nbsp;<strong>Council</strong>&nbsp;and the&nbsp;<strong>European Court of Auditors</strong>&nbsp;have
           approved similar decisions on reuse. It is advisable that you check&nbsp;<strong>the reuse policy of your
             organisation</strong>&nbsp;before publishing or submitting your dataset.</p>
-        <p>If you need further information regarding copyright issues, please contact us at&nbsp;<span class="nobr"><a
-              class="external-link" href="mailto:op-copyright@publications.europa.eu" target="_blank"
-              rel="nofollow noopener">op-copyright@publications.europa.eu<sup><img class="rendericon"
-                  src="https://citnet.tech.ec.europa.eu/CITnet/jira/images/icons/mail_small.gif" alt="" width="13"
-                  height="12" align="absmiddle" border="0" /></sup></a></span></p>
-
+        <p>If you need further information regarding copyright issues, please contact us at&nbsp;<a
+            href="mailto:op-copyright@publications.europa.eu" target="_blank"
+            rel="nofollow noopener">op-copyright@publications.europa.eu</a></p>
       </div>
 
-
     </div>
+
     <div v-if="props.context.attrs.identifier === 'rights' && env.content.dataProviderInterface.annifIntegration"
       class="d-flex infoLicense py-5">
       <svg xmlns="http://www.w3.org/2000/svg" width="30px" height="30px" fill="currentColor"
@@ -93,6 +92,7 @@
         <div class="conditionalSelectDiv">
           <input ref="I1" type="text" class="conditionalSelect formkit-input formkit-inner" @click="openSelect($event)"
             :placeholder=props.context.attrs.placeholder v-model="selectModeVal">
+
           <div v-if="showSelect">
             <ul class="selectListConditional">
               <li v-for="el, index in props.context.attrs.selection" class="p-2 border-b border-gray-200 "
@@ -100,6 +100,10 @@
                   $t('message.dataupload.datasets.conditional.' + el) }}</li>
             </ul>
           </div>
+          <div v-if="selectedItem === 'vocabulary'"
+            v-html="$t('message.dataupload.distributions.licence.vocabulary.help')"
+            class="formkit-help position-absolute">
+          </div>
         </div>
         <div class="conditionalManual">
           <div class="d-flex" v-if="selectedItem === 'manually' ||
@@ -113,13 +117,14 @@
         <div v-if="selectedItem === 'vocabulary' && !props.context.value['name']" class="">
           <AutocompleteInput :context="props.context"></AutocompleteInput>
         </div>
+
         <div v-if="props.context.value['name']" class="conditionalVocabulary d-flex">
           <a class="autocompleteInputSingleValue">{{
-            props.context.value['name'] }}</a>
+            resolvedUriName }}</a>
           <div class="removeX" @click="removeProperty"></div>
 
         </div>
-
+        <div v-if="selectedItem === 'manually'" v-html="props.context.attrs.info" class="formkit-help"></div>
 
       </div>
 
@@ -128,25 +133,54 @@
 
 </template>
 <script setup>
-import { ref, watchEffect } from 'vue';
+
 import AutocompleteInput from './AutocompleteInput.vue';
 import { onClickOutside } from '@vueuse/core'
 import { useRuntimeEnv } from "../../composables/useRuntimeEnv.ts";
+import { ref, watch, computed, onMounted, watchEffect, toRef } from 'vue';
+import { useStore } from 'vuex';
+import { getTranslationFor } from "../../utils/helpers";
+import { getCurrentInstance } from "vue";
+import { getNode } from '@formkit/core'
 import { useI18n } from 'vue-i18n';
+import { useRequestUriName } from '../composables/useRequestUriName';
 
 let env = useRuntimeEnv()
 const props = defineProps({
   context: Object,
 })
-const { t } = useI18n();
+let instance = getCurrentInstance().appContext.app.config.globalProperties.$env
+const { t, locale } = useI18n();
 let selectModeVal = ref()
 let selectedItem = ref(false)
 let showSelect = ref(false)
-
-
+let voc = props.context.attrs.voc;
+const store = useStore();
+let resolvedUriName = ref();
+
+const { execute: requestURIname, error: requestURInameError, isLoading: requestURInameLoading } = useRequestUriName({
+  res: computed(() => props.context.value.name),
+  voc: computed(() => props.context.attrs.voc),
+  property: computed(() => props.context.attrs.property),
+  locale,
+})
 
 watchEffect(() => {
   if (props.context.value['name']) {
+    if (resolvedUriName.value != props.context.value.name) {
+
+      if (props.context.value.name === props.context.value.resource) {
+        requestURIname().then(result => {
+          resolvedUriName.value = result;
+        }).catch(error => {
+          console.error(error);
+        })
+      }
+      else {
+        resolvedUriName.value = props.context.value.name
+      }
+    }
+
     selectModeVal.value = t('message.dataupload.datasets.conditional.' + 'vocabulary');
   }
   if (props.context.value['foaf:name']) {
@@ -211,4 +245,4 @@ onClickOutside(I1, event => showSelect.value = false)
 .textInfoI {
   width: 95%;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DataFetchingComponent.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DataFetchingComponent.vue
index 7d1c9e8a82c4d426eae9cdd405f1d7a884256280..51d17dadbd660340a9d5cd6c59394e64ace7ba7c 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DataFetchingComponent.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DataFetchingComponent.vue
@@ -33,6 +33,22 @@ export default {
       'convertToInput',
     ]),
     async setupEditPage() {
+      this.$router.push({
+        name: 'DataProviderInterface-Input',
+        params: { property: this.property },
+        query: { 
+          locale: this.$route.query.locale,
+          edit: true,
+          id: !this.getIsDraft && this.property === 'catalogues'
+            ? this.catalog
+            : this.id,
+          catalog: this.catalog,
+          fromDraft: this.getIsDraft ? 'true' : undefined,
+        },
+      })
+
+      return;
+
       let endpoint;
       this.setIsEditMode(true);
       const specification = this.$env.content.dataProviderInterface.specification;
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DistributionStepper.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DistributionStepper.vue
index 667376a33e284f83fe08d81aca2e54cace50a254..62e02bf196f1ec1172480cc17a6f030b5849a153 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DistributionStepper.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/DistributionStepper.vue
@@ -6,12 +6,13 @@
           <li v-for="(step, stepName, index) in steps" :key="index" class="step"
             :data-step-active="activeStep === stepName" :data-step-valid="step.valid && step.errorCount === 0" :class="{
               activeItem: activeStep === stepName, inactiveStep: stepName != activeStep, 'has-errors': checkStepValidity(stepName)
-            }" @click="activeStep = stepName">
+            }" @click="activeStep = stepName; indexOfDis = index + 1">
+
             <div class="stepBubbleWrap">
-              <div class="circle stepCircle">{{ index + 1 }}</div>
+              <div class="circle stepCircle">{{ convertToRoman(index + 1) }}</div>
               <span v-if="checkStepValidity(stepName)" class="step--errors"
                 v-text="step.errorCount + step.blockingCount" />
-                {{ $t('message.dataupload.steps.' + stepName+'Step') }}
+              {{ $t('message.dataupload.steps.' + stepName + 'Step') }}
             </div>
             <div
               v-if="index + 1 != Object.keys(getNavSteps($env.content.dataProviderInterface.specification).distributions).length"
@@ -30,18 +31,24 @@
               <!-- <PropertyChooser></PropertyChooser> -->
               <FormKitSchema :schema="schema[stepName]" :library="library" />
               <p v-if="stepName === 'Mandatory'" class="p-1"> <b>*</b> {{ $t('message.dataupload.steps.MandatoryStep')
-              }}</p>
+                }}</p>
             </InputPageStep>
           </div>
         </div>
       </div>
     </div>
   </FormKit>
+
   <div class="m-3 d-flex justify-content-end">
-    <button type="button" class="btn btn-secondary" @click="goToPreviousStep(); scrollToTop();">{{ $t('message.dataupload.steps.previousDisStep')
-              }}</button>
-    <button type="button" class="btn btn-secondary ml-3" @click="goToNextStep(); scrollToTop();">{{ $t('message.dataupload.steps.nextDisStep')
-              }}</button>
+
+    <button v-if="indexOfDis > 1" type="button" class="btn btn-secondary"
+      @click="goToPreviousStep(); scrollToTop(); indexOfDis = indexOfDis - 1">{{
+        $t('message.dataupload.steps.previousDisStep')
+      }}</button>
+    <button v-if="indexOfDis < 4" type="button" class="btn btn-secondary ml-3"
+      @click="goToNextStep(); scrollToTop(); indexOfDis = indexOfDis + 1">{{
+        $t('message.dataupload.steps.nextDisStep')
+      }}</button>
   </div>
 </template>
 
@@ -91,7 +98,8 @@ export default defineComponent({
           .replace(/([A-Z])/g, (match) => ` ${match}`)
           .replace(/^./, (match) => match.toUpperCase())
           .trim(),
-      isActive: false
+      isActive: false,
+      indexOfDis: 1
     }
   },
   methods: {
@@ -103,6 +111,20 @@ export default defineComponent({
       let { x, y } = useWindowScroll({ behavior: 'smooth' })
       y.value = 0
 
+    },
+    convertToRoman(element) {
+      if (element === 1) {
+        return "A"
+      }
+      if (element === 2) {
+        return "B"
+      }
+      if (element === 3) {
+        return "C"
+      }
+      if (element === 4) {
+        return "D"
+      }
     }
   },
   computed: {
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/LanguageSelector.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/LanguageSelector.vue
index 542f10cdd1cd90b4f72fe225b51ddf338502546c..0c24c16ff46f57e5857ca4b422df6916eb491648 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/LanguageSelector.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/LanguageSelector.vue
@@ -8,7 +8,10 @@
 </template>
   
   <script>
-  export default {
+  import { useVModel } from '@vueuse/core';
+import { defineComponent } from 'vue';
+
+  export default defineComponent({
     name: 'LanguageSelector',
     data() {
       return {
@@ -41,23 +44,18 @@
       };
     },
     props: {
-      value: {
+      modelValue: {
         type: String,
         default: 'en',
       },
     },
-    computed: {
-        locale: {
-            get() {
-                return this.value;
-            },
-            set(newLocale) {
-                this.$emit('input', newLocale);
-            }
-        }
-    },
     created() {},
-  };
+    setup(props, { emit }) {
+      const locale = useVModel(props, 'modelValue', emit, { passive: true });
+
+      return { locale }
+    }
+  });
   </script>
   
   <style lang="scss" scoped>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/Navigation.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/Navigation.vue
index 54dea90c129143d73c9c1d34c1b853125b7e73d3..0597db1eb728de427d75ae3a6a5a58466369ffe7 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/Navigation.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/Navigation.vue
@@ -123,7 +123,7 @@ export default {
     }
   },
   created() {
-    this.$i18n.locale = this.$route.query.locale
+    // this.$i18n.locale = this.$route.query.locale
     this.modals.clear.message = this.$t('message.dataupload.modal.resetForm')
     this.modals.clear.confirm = this.$t('message.dataupload.modal.confirmReset')
 
@@ -160,7 +160,7 @@ export default {
     },
     async submit(mode) {
       this.uploading[mode] = true;
-      this.$Progress.start();
+      this.$Progress?.start();
 
       const specification = this.$env.content.dataProviderInterface.specification;
       const RDFdata = await this.convertToRDF({ property: this.property, specification: specification }).then((response) => { return response; });
@@ -221,8 +221,8 @@ export default {
           await this.$store.dispatch(actionName, actionParams);
           // await new Promise(resolve => setTimeout(resolve, 250));
 
-          this.$Progress.finish();
-          this.uploading = false;
+          this.$Progress?.finish();
+          this.uploading[mode] = false;
 
           if (mode === 'createcatalogue') this.createCatalogue(datasetId);
           if (mode === 'dataset') this.createDataset(datasetId);
@@ -233,12 +233,13 @@ export default {
         }
         else {
           this.uploading[mode] = false;
-          this.$Progress.fail();
+          this.$Progress?.fail();
           this.handleIDError();
         }
       } catch (err) {
+        console.error(err)
         this.uploading[mode] = false;
-        this.$Progress.fail();
+        this.$Progress?.fail();
         this.showSnackbar({ message: 'Network Error', variant: 'error' });
       }
     },
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SimpleSelect.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SimpleSelect.vue
index 2783e57760d52bd49941a9aacd6a2de832d1b0dd..f780f739cfbab609669b73d6dc2ad0939ea5f8f8 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SimpleSelect.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SimpleSelect.vue
@@ -1,126 +1,171 @@
 <template>
-    <div class="formkitProperty">
-        <h4>{{ props.context.label }}</h4>
-        <div class="position-relative formkitCmpWrap">
-            <FormKit v-if="isEditMode.value && !isDuplicate" class="autocompleteInputfield" type="text" readonly
-                :placeholder="getNode('dcat:catalog').value" :name="props.context.node.name" />
-            <FormKit v-else class="autocompleteInputfield" v-model="catVal"
-                :placeholder="props.context.attrs.placeholder" type="text" @click="showList = !showList"
-                validation="required" mandatory="true" readonly :validation-messages="{
-                    required: props.context.attrs.placeholder,
-                }" :name="props.context.node.name" />
-
-            <ul ref="dropdownList" v-show="showList" class="autocompleteResultList selectListFK catSelectList">
-
-                <li v-for="match in filteredCatalogs" :key="match" @click="setvalue(match)"
-                    class="p-2 border-b border-gray-200 data-[selected=true]:bg-blue-100 choosableItemsAC">{{
-                        match.name }}
-                </li>
-                <li v-if="filteredCatalogs.length === 0" v-for="idMatch in userCats" :key="idMatch"
-                    @click="setvalue(idMatch)"
-                    class="p-2 border-b border-gray-200 data-[selected=true]:bg-blue-100 choosableItemsAC">{{
-                        idMatch }}
-                </li>
-            </ul>
-        </div>
+  <div class="formkitProperty">
+    <h4>{{ props.context.label }}</h4>
+    <div class="position-relative formkitCmpWrap">
+
+      <div v-if="isReady">
+
+        <!-- Hidden input that contains the actual catalog id. We rely on that to pass the catalog id to backend later -->
+        <FormKit v-show="false" v-model="selectedCatalogId" :name="`${props.context.node.name}`" type="text" />
+
+        <!-- User-facing input that displays the name of the selected catalog -->
+        <FormKit
+          class="autocompleteInputfield"
+          v-model="selectedCatalogTitle"
+          :placeholder="props.context.attrs.placeholder"
+          type="text" 
+          validation="required"
+          mandatory="true"
+          :validation-messages="{
+            required: props.context.attrs.placeholder,
+          }" :name="`${props.context.node.name}__displayedValue`"
+          :disabled="isDisabled"
+          @click="showList = !showList"
+        />
+        <ul ref="dropdownList" v-show="showList" class="autocompleteResultList selectListFK catSelectList">
+          <li v-for="match in authorizedCatalogs" :key="match" @click="setvalue(match)"
+            class="p-2 border-b border-gray-200 data-[selected=true]:bg-blue-100 choosableItemsAC">{{
+              match.name }}
+          </li>
+          <li v-if="authorizedCatalogs.length === 0" v-for="idMatch in userCats" :key="idMatch" @click="setvalue(idMatch)"
+            class="p-2 border-b border-gray-200 data-[selected=true]:bg-blue-100 choosableItemsAC">{{
+              idMatch }}
+          </li>
+        </ul>
+      </div>
     </div>
+  </div>
 
 </template>
 <script setup>
-import { ref, computed, onMounted } from 'vue';
+import { ref, computed, onMounted, watch, nextTick } from 'vue';
 import { useStore } from 'vuex';
 import { getNode } from '@formkit/core'
 import { onClickOutside } from '@vueuse/core'
 import axios from 'axios'
 import { useRuntimeEnv } from "../../composables/useRuntimeEnv.ts";
-import {
-    has,
-    isNil,
-} from 'lodash-es';
+import { useI18n } from 'vue-i18n';
+import { useAsyncState } from '@vueuse/core';
 import { FormKit } from '@formkit/vue';
+import { useDpiContext } from '../composables/useDpiContext';
 
 const props = defineProps({
-    context: Object
+  context: Object
 })
 
+const dpiContext = useDpiContext()
+const { locale, fallbackLocale } = useI18n({ useScope: 'global' })
 
-
-const isDuplicate = computed(()=> localStorage.getItem('dpi_duplicate'))
 const userCats = computed(() => store.getters['auth/getUserCatalogIds']);
-let showList = ref()
+const showList = ref(false)
 const store = useStore()
 const dropdownList = ref(null)
-const isEditMode = ref()
-let validationTrigger = ref(true)
-isEditMode.value = computed(() => store.getters['auth/getIsEditMode']);
-let filteredCatalogs = ref([])
-let env = useRuntimeEnv()
-let catVal = ref()
-
-catVal = getNode('dcat:catalog').value
+const env = useRuntimeEnv()
+const selectedCatalogTitle = ref('')
+const selectedCatalogId = ref('')
+const hasMounted = ref(false)
 
 onClickOutside(dropdownList, event => showList.value = false)
 
 const setvalue = async (e) => {
-   
-    validationTrigger = false
-    if (e.id) {
-        props.context.node.input(e.id)
-        showList.value = !showList.value;
-        getNode('dcat:catalog').value = e.id
-        catVal = e.name
-    } else {
-        props.context.node.input(e)
-        showList.value = !showList.value;
-        getNode('dcat:catalog').value = e
-        catVal = e
-    }
-
-}
-let filterCatList = async () => {
-    let cache;
-    await axios
-        .get(env.api.baseUrl + 'search?filter=catalogue&limit=1000')
-        .then(response => (cache = response))
-        .catch((err) => {
-            reject(err);
-        });
-
-    
-    cache.data.result.results.forEach((e) => {
-        // console.log(cache);
-        
-        if (has(e, 'title') && !isNil(e.title) && has(e, 'id') && !isNil(e.id)) filteredCatalogs.value.push({ title: Object.values(e.title)[0], id: e.id })
-    });
-
-    filteredCatalogs.value = await filteredCatalogs.value
-        .filter(item => userCats.value.includes(item.id))
-        .map(item => ({ id: item.id, name: item.title }));
-
-    // Check if theres only one catalog and set it directly
-
-    let clone = JSON.parse(JSON.stringify(filteredCatalogs.value))
-    if (clone.length === 1) {
-        catVal = clone[0].id
-    }
+  if (e.id) {
+    selectedCatalogId.value = e.id
+    selectedCatalogTitle.value = e?.name || e.id
+  } else {
+    selectedCatalogId.value = e
+    selectedCatalogTitle.value = e
+  }
+
+  showList.value = false
 }
 
+const { execute: filterCatList, state: catalogListData, isReady: isQueryReady, error } = useAsyncState(async () => {
+  const catalogListData = await axios.get(env.api.baseUrl + 'search?filter=catalogue&limit=1000')
+  return catalogListData
+}, { data: { result: { results: [] } } }, { immediate: false })
+
+// Wait until everything mounted and loaded tu ensure that the catalog list is available and selected catalog from edit mode is available
+const isReady = computed(() => hasMounted.value && !!catalogListData.value && isQueryReady.value)
+
+watch(error, () => {
+  console.error(error.value)
+})
+
+const hasResults = computed(() => {
+  return catalogListData?.value?.data?.result?.results?.length > 0
+})
+
+const hasOneResultOnly = computed(() => {
+  return hasResults && catalogListData?.value?.data?.result?.results?.length === 1
+})
+
+/**
+ * Computes list of users' authorized catalogs in { id: string; name: string } format
+ */
+const authorizedCatalogs = computed(() => {
+  if (!hasResults.value || !isQueryReady.value) return []
+
+  const allCatalogs = catalogListData.value?.data?.result?.results || []
+  const authorizedCatalogs = allCatalogs.filter(catalog => userCats.value?.includes(catalog.id))
+
+  // map to { id: string; name: string } pairs
+  const authorizedCatalogsDataModel = authorizedCatalogs.map((catalog) => {
+    const id = catalog?.id || ''
+    let title = ''
+
+    if (!catalog?.title) title = id
+    else if (typeof catalog?.title === 'string') title = catalog?.title
+    else if (typeof catalog?.title === 'object') title =
+      catalog?.title[locale.value]
+      || catalog?.title[fallbackLocale.value]
+      || Object.values(catalog?.title)?.[0]
+      || id
+
+    return { id, name: title || id }
+  });
+  return authorizedCatalogsDataModel
+})
+
+watch(hasOneResultOnly, (yes) => {
+  if (yes) {
+    const result = catalogListData.value.data.result.results[0]
+    setvalue({ id: result.id, name: result.name })
+  }
+}, { immediate: true })
 
 onMounted(async () => {
-    filterCatList();
+  // When editing, we can restore the selected catalog id immediately, but we rely on fetching from hub-search for its catalog title.
+  // So we need to wait until everything is fetched before proceeding further.
+  await filterCatList()
+  await nextTick()
+  // todo: can this be made more robust by using dpiContext.value.edit?.id?
+  const catalogIdToLoadForEdit = getNode?.('dcat:catalog')?.value || undefined
+  const maybeFoundCatalogFromQuery = authorizedCatalogs.value?.find(item => item.id === catalogIdToLoadForEdit)
+  if (maybeFoundCatalogFromQuery) {
+    setvalue({ id: maybeFoundCatalogFromQuery.id, name: maybeFoundCatalogFromQuery.name })
+  }
+  await nextTick()
+  hasMounted.value = true
 });
 
+// Disable select option if in edit mode
+// Note: Decision is made due to a backend limitation that causes dataset duplicates to occur when changing a catalog
+const isDisabled = computed(() => {
+  const isInEditMode = dpiContext.value.edit?.enabled
+  return isInEditMode
+})
+
 </script>
 <style>
 .catSelectList {
-    width: 97.3% !important;
-    margin: 0 1rem;
+  width: 97.3% !important;
+  margin: 0 1rem;
 }
 
 .selectListFK {
 
-    max-height: 20rem;
-    overflow: overlay;
-    overflow-x: hidden;
+  max-height: 20rem;
+  overflow: overlay;
+  overflow-x: hidden;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SpatialInput.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SpatialInput.vue
index 57d081574697d26de65b87afaf03e690e4a1d0c3..b44170283b1c5714dd90b852082edbb074cef4d5 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SpatialInput.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/SpatialInput.vue
@@ -1,45 +1,148 @@
 <script setup>
 
-import { ref, reactive, watch, computed, onBeforeMount, onMounted, nextTick } from 'vue';
+import { ref, reactive, watch, computed, onBeforeMount, onMounted, nextTick, watchEffect } from 'vue';
 import { useStore } from 'vuex';
 import { getTranslationFor } from "../../utils/helpers";
-import { onClickOutside } from '@vueuse/core'
+import { onClickOutside, whenever } from '@vueuse/core'
 import { getCurrentInstance } from "vue";
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import { useTed } from '../../composables/useTed';
+import { useAutocomplete } from '../composables/aucotomplete';
+import { useRequestUriName } from '../composables/useRequestUriName';
+import { useDpiContext } from '../composables';
+
 
 let instance = getCurrentInstance().appContext.app.config.globalProperties.$env
 let route = useRoute();
+const dpiContext = useDpiContext();
 
 const props = defineProps({
     context: Object,
 })
+
+const { requestAutocompleteSuggestions } = useAutocomplete()
+
 // let listOfVoc: [{ item: 'Country', active: false }, { item: 'Place', active: false }, { item: 'Continent', active: false }],
 let listOfVoc = ref([])
+const typeText = ref('')
 let inputText = ref({})
 let voc = ref({})
 let matches = ref({})
 let manURL = ref({})
 const store = useStore();
+const { t, locale } = useI18n({ inheritLocale: true, useScope: 'global' });
+const ted = useTed();
+
+const man = ref(false)
+const vocSearch = ref(false)
+
+const isEdit = computed(() => !!dpiContext.value.edit?.enabled)
+const resourceNameWhenEditing = computed(() => !!isEdit.value && props.context.value.resource)
+// e.g. extract "municipalityKey" (second to last) out of resourceName
+const keyFromResourceName = computed(() => {
+    if (resourceNameWhenEditing.value) {
+        return resourceNameWhenEditing.value.split('/')[resourceNameWhenEditing.value.split('/').length - 2]
+    }
+    return ''
+})
+const spatialVocabName = computed(() => {
+  if (!keyFromResourceName.value) {
+    return ''
+  }
+
+  const maybePrefix = props.context.attrs.identifier === 'politicalGeocodingURI'
+    ? 'political-geocoding-'
+    // todo: extend this for other vocabularies
+    : ''
+
+  // transform key from camelCase to kebab-case
+  const vocabKey = keyFromResourceName.value.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
+  return `${maybePrefix}${vocabKey}`
+})
+
+const translatedResourceName = computed(() => {
+  // transform key 'districtKey' to 'District Key'
+  const vocabKey = keyFromResourceName.value.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase()
+  // make first letters of each word uppercase
+  const vocabKeyUpper = vocabKey.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')
+  return t(`message.dataupload.datasets.conditional.${vocabKeyUpper}`)
+})
+
+const { execute, state, isLoading } = useRequestUriName({
+  voc: spatialVocabName,
+  res: computed(() => props.context.value.resource),
+  // property: 'dcatde:politicalGeocodingURI',
+  property: computed(() => props.context.attrs.identifier === 'politicalGeocodingURI' ? 'dcatde:politicalGeocodingURI' : 'dct:spatial'),  
+  locale,
+})
+
+const restoredValueFromEditMode = computed(() => {
+  if (isEdit.value && !isLoading.value && resourceNameWhenEditing.value && state.value) {
+    return `${translatedResourceName.value}: ${state.value} (${resourceNameWhenEditing.value.split('/').pop()})`
+  }
+
+  return ''
+})
+
+const once = ref(false)
+watchEffect(() => {
+  if (once.value) return;
+
+  if (!!resourceNameWhenEditing.value) {
+    once.value = true
+    execute()
+  }
+}, { immediate: true })
+
+whenever(restoredValueFromEditMode, () => {
+  const v = { name: restoredValueFromEditMode.value, resource: resourceNameWhenEditing.value }
+  props.context.node.input(v)
+})
+
+// If true, then:
+// - hides the select input for manual and vocabulary
+// - pre-selects the vocabulary option
+// When using formkit schema, enable this option by setting vocabularyOnly to true
+// {
+//     $formkit: 'spatialinput',
+//     name: 'dcatde:politicalGeocodingURI',
+//     identifier: 'politicalGeocodingURI',
+//     vocabularyOnly: true,
+// }
+const vocabularyOnly = computed(() => !!props.context?.attrs?.vocabularyOnly)
 
 if (props.context.attrs.identifier === 'politicalGeocodingURI') {
-    listOfVoc.value.push({ item: 'Municipality Key', active: false }, { item: 'Regional Key', active: false }, { item: 'Municipal Association Key', active: false }, { item: 'District Key', active: false }, { item: 'Government District Key', active: false }, { item: 'State Key', active: false })
+    listOfVoc.value.push(
+        { item: 'Municipality Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.Municipality Key', 'Municipality Key') },
+        { item: 'Regional Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.Regional Key', 'Regional Key') },
+        { item: 'Municipal Association Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.Municipal Association Key', 'Municipal Association Key') },
+        { item: 'District Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.District Key', 'District Key') },
+        { item: 'Government District Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.Government District Key', 'Government District Key') },
+        { item: 'State Key', active: false, placeholder: ted('message.dataupload.datasets.conditional.State Key', 'State Key') },
+    )
 
 }
 if (props.context.attrs.identifier === 'spatial') {
-    listOfVoc.value.push({ item: 'Country', active: false }, { item: 'Place', active: false }, { item: 'Continent', active: false })
+    listOfVoc.value.push(
+        { item: 'Country', active: false, placeholder: ted('message.dataupload.datasets.conditional.Country', 'Country') },
+        { item: 'Place', active: false, placeholder: ted('message.dataupload.datasets.conditional.Place', 'Place') },
+        { item: 'Continent', active: false, placeholder: ted('message.dataupload.datasets.conditional.Continent', 'Continent') },
+    )
 }
 
 watch(inputText, async () => {
     getAutocompleteSuggestions();
 })
-watch(voc, async () => {
+watch(voc, async (newValue, oldValue) => {
+    if (newValue === oldValue) { return }
     voc.value = voc.value.toLowerCase();
 })
 watch(manURL, async () => {
     props.context.node.input({ 'name': manURL, 'resource': manURL })
 })
 onMounted(async () => {
-    matches = [{ name: '--- Type in anything for a live search of the vocabulary ---', resource: 'invalid' }]
+    matches = [{ name: ted('message.dataupload.info.searchVocabulary', '--- Type in anything for a live search of the vocabulary ---').value, resource: 'invalid' }]
 
     await nextTick()
     // DOM loaded
@@ -48,6 +151,10 @@ onMounted(async () => {
     } else showTable.activeValue = true
     // console.log(showTable.activeValue);
 
+    if (vocabularyOnly.value) {
+        activeInput('showTable'); vocSearch.value = true; if (man.value) { man.value = false }
+    }
+
 });
 
 function closeAll() {
@@ -83,7 +190,8 @@ function saveToLocal(el) {
     localStorage.setItem(`dpi_${route.params.property}`, JSON.stringify(pathToLocalStorage))
 }
 const getAutocompleteSuggestions = async () => {
-    let vocCache = voc.value
+
+    let vocCache = voc.value?.toLowerCase()
 
     if (props.context.attrs.identifier === 'politicalGeocodingURI') {
 
@@ -91,9 +199,9 @@ const getAutocompleteSuggestions = async () => {
 
         try {
             let text = inputText.value;
-            await store.dispatch('dpiStore/requestAutocompleteSuggestions', { voc: vocCache, text: text, base: instance.api.baseUrl }).then((response) => {
+            await requestAutocompleteSuggestions({ voc: vocCache, text: text, base: instance.api.baseUrl }).then((response) => {
                 const results = response.data.result.results.map((r) => ({
-                    name: getTranslationFor(r.alt_label, 'en', []) + " (" + r.id + ")",
+                    name: getTranslationFor(r.alt_label, locale.value, []) + " (" + r.id + ")",
                     resource: r.resource,
                 }));
                 matches = results;
@@ -104,9 +212,9 @@ const getAutocompleteSuggestions = async () => {
     else {
         try {
             let text = inputText.value;
-            await store.dispatch('dpiStore/requestAutocompleteSuggestions', { voc: vocCache, text: text, base: instance.api.baseUrl }).then((response) => {
+            await requestAutocompleteSuggestions({ voc: vocCache, text: text, base: instance.api.baseUrl }).then((response) => {
                 const results = response.data.result.results.map((r) => ({
-                    name: getTranslationFor(r.pref_label, 'en', []) + " (" + r.id + ")",
+                    name: getTranslationFor(r.pref_label, locale.value, []) + " (" + r.id + ")",
                     resource: r.resource,
                 }));
                 matches = results;
@@ -145,6 +253,19 @@ function activeInput(e) {
 function manURLInput(e) {
     props.context.node.input({ 'name': e.target.value, 'resource': e.target.value })
 }
+
+function handleSpatielListClick(el) {
+  props.context.node.input(el);
+  inputText.value = el.name;
+  activeInput('showVocEntries');
+  showTable.third = false;
+  saveToLocal(el)
+}
+
+function submitType() {
+    activeInput('showVocTable');
+
+}
 // console.log(voc);
 </script>
 
@@ -154,15 +275,18 @@ function manURLInput(e) {
             <!-- <div class="infoI">
                 <div class="tooltipFormkit">{{ props.context.attrs.info }}</div>
             </div> -->
-            <a class="autocompleteInputSingleValue ">{{ props.context.value.name }}</a>
+            <a class="autocompleteInputSingleValue ">{{ restoredValueFromEditMode }}</a>
             <div class="removeX" @click="removeProperty"></div>
         </div>
         <div v-else>
             <div class=" w-100 d-flex">
-                <div class="d-flex position-relative m-3 w-100">
-                    <input id="I1" type="text" class="selectInputField formkit-inner" readonly="readonly"
-                        :placeholder="$t('message.dataupload.info.preferredInput')"
-                        @click="activeInput('showTable')" />
+                <div v-if="!vocabularyOnly" class="d-flex position-relative m-3 w-100">
+                    <label class="w-100"> {{ $t('message.dataupload.info.preferredInput') }}
+                        <input id="I1" type="text" class="selectInputField formkit-inner" readonly="readonly"
+                            :placeholder="$t('message.dataupload.info.preferredInput')"
+                            @click="activeInput('showTable')" />
+                    </label>
+
                     <ul ref="I1" v-show="showTable.first" class="spatialListUpload">
                         <li @click="activeInput('showTable'); man = true; if (vocSearch) { vocSearch = false; };"
                             class="p-2 border-b border-gray-200 choosableItemsAC">
@@ -175,32 +299,40 @@ function manURLInput(e) {
                     </ul>
                 </div>
                 <div v-if="man" class="d-flex position-relative m-3 w-100">
-                    <label class="w-100"> Provide an URL
+                    <label class="w-100">
+                        <!-- todo: I borrowed this from another input. Maybe refactor? -->
+                        {{ $te('message.dataupload.datasets.isReferencedByUrl.placeholder') ? $t('message.dataupload.datasets.isReferencedByUrl.placeholder') : 'Provide an URL' }}
                         <input type="URL" class="selectInputField formkit-inner" placeholder="URL"
                             @input="manURLInput($event)">
                     </label>
                 </div>
                 <div v-if="vocSearch" class="d-flex position-relative m-3 w-100">
-                    <label class="w-100"> Choose type of vocabulary
-                        <input id="I2" type="text" class="selectInputField formkit-inner" readonly="readonly"
-                            placeholder="Search the vocabulary" @click="activeInput('showVocTable');">
+                    <!-- todo: I borrowed this from another input. Maybe refactor? -->
+                    <label class="w-100"> {{ $te('message.dataupload.datasets.contributorType.placeholder') ? $t('message.dataupload.datasets.contributorType.placeholder') : 'Choose type of vocabulary' }} 
+                        <input id="I2" type="text" class="selectInputField formkit-inner" readonly="readonly" v-model="typeText"
+                            :placeholder="$te('message.dataupload.datasets.accessRights.placeholder') ? $t('message.dataupload.datasets.accessRights.placeholder') : 'Choose type of vocabulary'" @click="activeInput('showVocTable');">
                     </label>
                     <ul ref="I2" v-if="showTable.second" class="spatialListUpload">
                         <li v-for="el in listOfVoc" :key="el" class="p-2 border-b border-gray-200 choosableItemsAC"
-                            @click=" closeAll(); el.active = !el.active; activeInput('showVocTable'); inputText = ''; voc = el.item">
-                            {{ el.item }}</li>
+                            @click=" closeAll(); el.active = !el.active; activeInput('showVocTable'); inputText = ''; voc = el.item; typeText = el.placeholder">
+                            {{ $t('message.dataupload.datasets.conditional.' + el.item) }}</li>
                     </ul>
                 </div>
             </div>
             <div class="m-3" v-if="vocSearch">
                 <div v-for="el in listOfVoc" :key="el" class="position-relative">
-                    <label class="w-100" v-if="el.active"> Search the vocabulary <input id="I3" type="text"
-                            v-model="inputText" class="selectInputField formkit-inner" :placeholder="el.item"
-                            @click="activeInput('showVocEntries'); inputText = ''">
+                    <label class="w-100" v-if="el.active">
+                    <!-- todo: I borrowed this from another input. Maybe refactor? -->
+                    <!-- {{ $te('message.dataupload.datasets.accessRights.placeholder') ? $t('message.dataupload.datasets.accessRights.placeholder') : 'Choose type of vocabulary' }}  -->
+                    {{ el.placeholder ? el.placeholder : $t('message.dataupload.datasets.conditional.' + el.item) }}
+                        <input id="I3" type="text"
+                            v-model="inputText" class="selectInputField formkit-inner" :placeholder="$te('message.dataupload.datasets.accessRights.placeholder') ? $t('message.dataupload.datasets.accessRights.placeholder') : 'Choose type of vocabulary'"
+                            @click="activeInput('showVocEntries'); inputText = ''"
+                        >
                     </label>
                     <ul ref="I3" v-if="showTable.third && el.active" class="spatialListUpload">
                         <li v-for="el in matches" :key="el" class="p-2 border-b border-gray-200 choosableItemsAC"
-                            @click="props.context.node.input(el); inputText = el.name; activeInput('showVocEntries'); showTable.third = false; saveToLocal(el)">
+                            @click="handleSpatielListClick(el)">
                             {{ el.name }}</li>
                     </ul>
                 </div>
@@ -213,15 +345,6 @@ function manURLInput(e) {
 
 <script>
 
-export default {
-    data() {
-        return {
-            man: false,
-            vocSearch: false,
-        }
-    },
-
-}
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/UniqueIdentifierInput.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/UniqueIdentifierInput.vue
index b44b8f24e3f0b964a1db5351ea854edc430b04ac..4f4fe096399d65a2c21398a955a6084eaff0f6ab 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/UniqueIdentifierInput.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/components/UniqueIdentifierInput.vue
@@ -1,34 +1,34 @@
 <script setup>
-import { ref, onMounted, watchEffect } from 'vue'
+import { ref, onMounted, watchEffect, computed } from 'vue'
+import { useRoute } from 'vue-router';
 import { isNil } from 'lodash';
 import axios from 'axios';
 import { useStore } from 'vuex';
 import { getCurrentInstance } from "vue";
 import { useI18n } from 'vue-i18n';
+import { useDpiContext } from '../composables';
 let env = getCurrentInstance().appContext.app.config.globalProperties.$env;
 
 const store = useStore();
-const isEditMode = ref();
+const dpiContext = useDpiContext();
 const isDuplicate = ref();
+const isEditMode = computed(() => !!dpiContext.value.edit?.enabled)
 isDuplicate.value = localStorage.getItem('dpi_duplicate');
-isEditMode.value = store.getters['auth/getIsEditMode'];
-const { t, locale } = useI18n();
 
-let validationMessages = {
+const { t, locale } = useI18n({ useScope: 'global' });
+
+const validationMessages = ref({
   idformatvalid: "",
   idunique: "",
   required: ""
 
-};
+});
 
 onMounted(() => {
   // This is kind of buggy, its taking the strings from the wrong json (de and en is switched)
-  validationMessages = {
-    idformatvalid: t('message.dataupload.datasets.datasetID.invalidFormat'),
-    idunique: t('message.dataupload.datasets.datasetID.duplicate'),
-    required: t('message.dataupload.datasets.datasetID.required')
-  };
-
+  validationMessages.value.idformatvalid = t('message.dataupload.datasets.datasetID.invalidFormat');
+  validationMessages.value.idunique = t('message.dataupload.datasets.datasetID.duplicate');
+  validationMessages.value.required = t('message.dataupload.datasets.datasetID.required');
 });
 
 
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/aucotomplete.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/aucotomplete.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9c2629d77e99972ad7bfe5736abbcd905b8bcc67
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/aucotomplete.ts
@@ -0,0 +1,91 @@
+import { computed, inject, InjectionKey, toValue } from "vue";
+import axios from "axios";
+import { ComputedDpiContext, useDpiContext } from "./useDpiContext";
+import { useRuntimeEnv } from "../../composables/useRuntimeEnv";
+import { ResolvedConfig } from "../../configurations/config-schema";
+
+export interface AutocompleteInstance {
+  requestFirstEntrySuggestions(voc: string, base: string): Promise<any>;
+  requestAutocompleteSuggestions(options: {
+    voc: string;
+    text: string;
+    base: string;
+  }): Promise<any>;
+  requestResourceName(options: {
+    voc: string;
+    uri: string;
+    envs: any;
+  }): Promise<any>;
+}
+
+export interface AutocompleteOptions {
+  name: string;
+  adapter: AutocompleteInstance;
+}
+
+export const autocompleteKey = Symbol(
+  "autocomplete"
+) as InjectionKey<AutocompleteInstance>;
+
+export function defaultAutocompleteAdapter(options: {
+  envs: ResolvedConfig
+  dpiContext: ComputedDpiContext
+}): AutocompleteOptions {
+  const { envs, dpiContext } = options
+  
+  return {
+    name: "default",
+    adapter: {
+      requestFirstEntrySuggestions: async (voc, base) => {
+        return axios.get(`${base}search?filter=vocabulary&vocabulary=${voc}`);
+      },
+      requestAutocompleteSuggestions: async (options) => {
+        return axios.get(
+          `${options.base}search?filter=vocabulary&vocabulary=${options.voc}&q=${options.text}&limit=14`
+        );
+      },
+      requestResourceName: async (options) => {
+        const { voc, uri } = options;
+        const specification = computed(
+          () => toValue(dpiContext)?.specification
+        );
+
+        // // Catching invalid URIs
+        if (voc === undefined) return;
+        if (voc === "application") return;
+
+        let req = "";
+
+        // vocabularies for spdx checksum and inana-media-types are structured differently in the backend then other vocabularies
+        if (voc === "iana-media-types" || voc === "spdx-checksum-algorithm") {
+          req = `${envs.api.baseUrl}vocabularies/${voc}`;
+        } else {
+          const value = uri.replace(
+            (specification.value.vocabPrefixes as any)[voc],
+            ""
+          );
+          const valueEncoded = encodeURIComponent(value);
+          const requestByUri = value !== valueEncoded;
+          req = !requestByUri
+            ? `${envs.api.baseUrl}vocabularies/${voc}/${valueEncoded}`
+            : `${
+                envs.api.baseUrl
+              }vocabularies/${voc}/vocable?resource=${encodeURIComponent(uri)}`;
+        }
+        return axios.get(req);
+      },
+    },
+  };
+}
+
+export function useAutocomplete() {
+  const autocomplete = inject(autocompleteKey);
+
+  if (!autocomplete) {
+    throw new Error(
+      "[useAutocomplete] Autocomplete not found. Did you forget to inject it?"
+    );
+  }
+
+  return autocomplete;
+}
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/index.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..198eb0c4d251d8430f9d62ef5abd6ff770b1a694
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/index.ts
@@ -0,0 +1,7 @@
+export * from './useDpiContext'
+export * from './useDpiStepper'
+export * from './useDpiContext'
+export * from './useDpiEditMode'
+export * from './useDpiStepper'
+export * from './useRequestUriName'
+export * from './useFormSchema'
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiContext.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiContext.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7af596bfe5f1fe2117b7097a31a6a13086c59781
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiContext.ts
@@ -0,0 +1,38 @@
+import { FormKitLibrary } from "@formkit/core"
+import { computed, ComputedRef, getCurrentInstance, inject, InjectionKey, MaybeRefOrGetter, provide, toValue } from "vue"
+
+export interface DpiSpecification {
+  pageConent?: object
+  inputDefinition: object
+  prefixes: object
+  formatTypes: object
+  vocabPrefixes: object
+}
+
+export interface DpiContext {
+  specification: DpiSpecification
+  specificationName: string
+  edit?: {
+    enabled?: boolean
+    id?: string
+    fromDraft?: boolean
+  }
+}
+
+export type ComputedDpiContext = ComputedRef<DpiContext>
+
+export const dpiContextKey: InjectionKey<ComputedDpiContext> = Symbol('dpiContext')
+
+export function useDpiContext(): ComputedDpiContext {
+  const dpiContext = inject(dpiContextKey)
+
+  if (!dpiContext) {
+    throw new Error('[useDpiContext] DPI Context not found. Did you forget to inject it?')
+  }
+
+  return dpiContext
+}
+
+export function setupDpiContext(context: MaybeRefOrGetter<DpiContext>) {
+  provide(dpiContextKey, computed(() => toValue(context)))
+}
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiEditMode.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiEditMode.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4b1557a43c28b4d4b79a54431153bcdec8cfb9f6
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useDpiEditMode.ts
@@ -0,0 +1,86 @@
+import { useRoute } from "vue-router";
+import { type DpiContext } from "./useDpiContext";
+import { computed, MaybeRefOrGetter, toValue, watch } from "vue";
+import { useStore } from "vuex";
+import { useRuntimeEnv } from "../../composables/useRuntimeEnv";
+import { useAsyncState, watchOnce } from "@vueuse/core";
+
+  /**
+   * Use this composable in the DataProviderInterface to fetch a dataset from the Hub API and
+   * convert it to a form input via localStorage. This composable is used when the user navigates to a dataset
+   * by clicking on the "Edit" on the DatasetDetails page or in DraftsPage
+   *
+   *
+   * @param dpiContext - The DPI context as returned by `useDpiContext`.
+   * @returns The computed properties described above.
+   */
+export function useDpiEditMode(dpiContext: MaybeRefOrGetter<DpiContext>) {
+  const route = useRoute();
+  const store = useStore();
+  const env = useRuntimeEnv();
+
+  const editQuery = computed(() => {
+    return toValue(dpiContext)?.edit?.enabled ?? route.query.edit === 'true';
+  });
+
+  const editIdQuery = computed(() => {
+    return toValue(dpiContext)?.edit?.id ?? route.query.id;
+  });
+
+  const editFromDraft = computed(() => {
+    return toValue(dpiContext)?.edit?.fromDraft ?? route.query.fromDraft ?? store.getters["auth/getIsDraft"];
+  });
+
+  // For legacy purposes, set editmode to false if editQuery is false
+  if (!!editQuery.value) {
+    localStorage.setItem('dpi_editmode', 'false');
+    store.dispatch("auth/setIsEditMode", false);
+  }
+
+  const requestParams = computed(() => {
+    const isDraft = editFromDraft.value;
+    const token = store.getters["auth/getUserData"]?.rtpToken;
+    const property = route.params.property;
+    const id = route.params.id;
+
+    const endpoint = isDraft
+      ? `${env.api.hubUrl}drafts/datasets/${editIdQuery.value}.nt?catalogue=${route.query.catalog}`
+      : route.params.property === "catalogues"
+      ? `${env.api.hubUrl}catalogues/${route.query.catalog}.nt`
+      : `${env.api.hubUrl}datasets/${editIdQuery.value}.nt?useNormalizedId=true`;
+    return { endpoint, token, property, id };
+  });
+
+  const { execute, isLoading, error } = useAsyncState(
+    async () => {
+      return await store.dispatch(
+        "dpiStore/convertToInput",
+        { ...requestParams.value }
+      );
+    },
+    undefined,
+    {
+      immediate: false,
+    }
+  );
+
+  const inEditModeAndRptAvailable = computed(() => !!editIdQuery.value && !!requestParams.value.token)
+  watch(inEditModeAndRptAvailable, () => {
+    if (!inEditModeAndRptAvailable.value) return;
+    const isDraft = editFromDraft.value;
+    store.dispatch("auth/setIsEditMode", true);
+    store.dispatch("auth/setIsDraft", isDraft);
+    execute();
+  }, { immediate: true });
+
+  // Ensure dpiStore contains a specification before rendering the input page.
+  // Maybe it's not needed but better safe than sorry.
+  const isReady = computed(() => {
+    return !!store.getters["dpiStore/getSpecificationName"] && !isLoading.value;
+  });
+
+  return {
+    isReady,
+    error,
+  }
+}
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useFormSchema.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useFormSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df8f099cbfa82d97d88a9e9b25203e8b03552b37
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useFormSchema.ts
@@ -0,0 +1,103 @@
+import { createSharedComposable } from '@vueuse/core'
+import { computed, MaybeRefOrGetter, ref, toValue, watch } from 'vue'
+import { useDpiContext } from './useDpiContext'
+import { useI18n } from 'vue-i18n'
+import translate from '../utils/translation-helper'
+
+const useFormSchemaGlobal = createSharedComposable(() => {
+  const state = ref({
+    schema: {
+      datasets: {},
+      distributions: {},
+      catalogues: {}
+    },
+    usersCatalogs: {}
+  })
+
+  /**
+   * Retrieves the schema for a given property.
+   *
+   * @param property - The property whose schema should be retrieved.
+   *                  Can be a string or a ref to a string.
+   * @returns A computed ref to the schema of the given property.
+   */
+  const getSchema = (property: MaybeRefOrGetter<string>) => computed(() => {
+    const _property = toValue(property)
+
+    if (property === 'catalogues' || property === 'datasets' || property === 'distributions') {
+      return state.value.schema[_property as keyof typeof state.value.schema]
+    }
+
+    return undefined
+  })
+
+  return { state, getSchema }
+})
+
+export interface UseFormSchemaOptions {
+  t?: (key: string) => string
+  te?: (key: string) => boolean
+}
+
+export function useFormSchema(options?: UseFormSchemaOptions) {
+  const dpiContext = useDpiContext()
+  const { t, te } = options || useI18n({ useScope: 'global' })
+  const { state, getSchema } = useFormSchemaGlobal()
+
+  const dpiConfig = computed(() => dpiContext.value.specification)
+
+  function createSchema({ property, page }: { property: string, page: string }) {
+    const pageProperties = dpiConfig.value.pageConent?.[property as keyof typeof dpiConfig.value.pageConent][page] as unknown as string[]
+    const propertyDefinitions = dpiConfig.value.inputDefinition?.[property as keyof typeof dpiConfig.value.inputDefinition]
+
+    // Create copy of state because extractSchema does in-place modifications.
+    // Just to be safe.
+    const stateCopy = JSON.parse(JSON.stringify(state.value))
+    extractSchema({ state: stateCopy, pageProperties, propertyDefinitions, property, page })
+
+    state.value = stateCopy
+  }
+
+  function extractSchema({
+    state,
+    pageProperties,
+    propertyDefinitions,
+    property,
+    page,
+  }: {
+    state: any
+    pageProperties: string[]
+    propertyDefinitions: any
+    property: string
+    page: string
+  }) {
+    // important: create new empty schema each time so already existing schema will be overwritten on route/view-change
+    const newSchema = [];
+
+    for (let index = 0; index < pageProperties.length; index += 1) {
+      const propertyKey = pageProperties[index];
+      try {
+        newSchema.push(propertyDefinitions[propertyKey]);
+      } catch (err) {
+        console.warn(
+          `DCATAP doens't include a property called: ${propertyKey}`
+        );
+      }
+    }
+
+    state.schema[property][page] = newSchema;
+  }
+
+  function translateSchema({ property, page }: { property: string, page: string }) {
+    const schemaCopy = { ...state.value.schema }
+    // @ts-ignore
+    translate(schemaCopy[property][page], property, t, te);
+
+    // Update the global state with the new schema
+    // @ts-ignore
+    state.value.schema[property][page] = schemaCopy[property][page]
+  }
+
+  return { createSchema, translateSchema, getSchema }
+
+}
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useRequestUriName.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useRequestUriName.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6c8c75c53144c8aaab537b0b49b03ff795616142
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/composables/useRequestUriName.ts
@@ -0,0 +1,98 @@
+import { useStore } from "vuex";
+import { useRuntimeEnv } from "../../composables/useRuntimeEnv";
+import { getTranslationFor } from "../../utils/helpers";
+import { MaybeRefOrGetter, toValue } from "vue";
+import { useAsyncState } from "@vueuse/core";
+import { useAutocomplete } from "./aucotomplete";
+
+/**
+ * Fetches the name of a resource based on its URI, vocabulary, and property.
+ */
+export function useRequestUriName(options: {
+  res: MaybeRefOrGetter<string>;
+  voc: MaybeRefOrGetter<string>;
+  property: MaybeRefOrGetter<string>;
+  locale: MaybeRefOrGetter<string>;
+}) {
+  const {
+    res: _res,
+    voc: _voc,
+    property: _property,
+    locale: _locale,
+  } = options;
+
+  const envs = useRuntimeEnv();
+  const store = useStore();
+  const { requestResourceName } = useAutocomplete()
+
+  const request = useAsyncState(
+    async () => {
+      const res = toValue(_res);
+      const voc = toValue(_voc);
+      const property = toValue(_property);
+      const locale = _locale;
+
+      if (res != undefined) {
+        let vocMatch =
+          voc === "iana-media-types" || voc === "spdx-checksum-algorithm";
+
+        let name;
+
+        await requestResourceName({
+            voc: voc,
+            uri: res,
+            envs,
+          })
+          .then((response) => {
+            if (property === "dcatde:politicalGeocodingURI") {
+              if (response != undefined) {
+                let result = vocMatch
+                  ? response.data.result.results
+                      .filter((dataset: any) => dataset.resource === res)
+                      .map((dataset: any) =>
+                        getTranslationFor(
+                          dataset.alt_label,
+                          toValue(locale),
+                          []
+                        )
+                      )[0]
+                  : getTranslationFor(
+                      response.data.result.alt_label,
+                      toValue(locale),
+                      []
+                    );
+                name = result;
+              }
+            } else {
+              if (response != undefined) {
+                let result = vocMatch
+                  ? response.data.result.results
+                      .filter((dataset: any) => dataset.resource === res)
+                      .map((dataset: any) =>
+                        getTranslationFor(
+                          dataset.pref_label,
+                          toValue(locale),
+                          []
+                        )
+                      )[0]
+                  : getTranslationFor(
+                      response.data.result.pref_label,
+                      toValue(locale),
+                      []
+                    );
+                name = result;
+              }
+            }
+          });
+
+        return name;
+      }
+    },
+    undefined,
+    { immediate: false }
+  );
+
+  return {
+    ...request,
+  };
+}
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatap/input-definition.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatap/input-definition.ts
index 95a1dcf028ef34e48df5ed7ad6c4ca2509233821..189a004232432f368bac942dac43bbb30d75fea3 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatap/input-definition.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatap/input-definition.ts
@@ -1818,7 +1818,7 @@ const dcatapProperties: InputDefinition = {
       identifier: 'licence',
       voc: 'licence',
       options: { text: 'dct:title', textarea: 'skos:prefLabel', url: 'skos:exactMatch' },
-      selection: { 1: 'Vocabulary', 2: 'Manually' }
+      selection: { 1: 'vocabulary', 2: 'manually' }
 
     },
     spatial: {
@@ -1836,7 +1836,7 @@ const dcatapProperties: InputDefinition = {
       identifier: 'homepage',
       $formkit: 'simpleInput',
       name: 'foaf:homepage',
-      validation: 'optional|url',
+      validationType: 'url',
     },
     hasPart: {
       identifier: 'hasPart',
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/input-definition.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/input-definition.ts
index 2d7ff8ff9ec74ad3684e86360a5b48e3fb618d41..81adb7fe35b93cc568fee1338829472599c8759c 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/input-definition.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/input-definition.ts
@@ -1420,7 +1420,6 @@ const dcatapProperties: InputDefinition = {
           identifier: 'accessUrl',
           name: 'dcat:accessURL',
           $formkit: 'fileupload',
-
         }
       ]
     },
@@ -1483,7 +1482,8 @@ const dcatapProperties: InputDefinition = {
       $formkit: 'simpleConditional',
       name: 'dct:license',
       identifier: 'licence',
-      voc: 'licence',
+      // 👇 Intentionally set to 'licenses' instead of 'licence'. License submission and fetching will break otherwise for dcat-ap.de
+      voc: 'licenses',
       class: 'property inDistribution',
       options: { text: 'dct:title', textarea: 'skos:prefLabel', url: 'skos:exactMatch' },
       selection: { 1: 'vocabulary', 2: 'manually' },
@@ -1540,13 +1540,21 @@ const dcatapProperties: InputDefinition = {
       class: 'property inDistribution',
       children: [
         {
-          identifier: 'downloadUrl',
-          $formkit: 'url',
-          name: '@id',
-          validation: 'optional|url',
-          classes: {
-            outer: 'w100-textfield'
-          }
+          $formkit: 'group',
+          identifier: 'relation',
+          name: 'dct:relation',
+          class: 'property',
+          children: [
+            {
+              identifier: 'downloadUrl',
+              $formkit: 'url',
+              name: '@id',
+              validation: 'optional|url',
+              classes: {
+                outer: 'w100-textfield'
+              }
+            },
+          ],
         },
       ],
     },
@@ -2118,7 +2126,7 @@ const dcatapProperties: InputDefinition = {
       identifier: 'homepage',
       $formkit: 'simpleInput',
       name: 'foaf:homepage',
-      validation: 'optional|url',
+      validationType: 'url',
       class: ''
     },
     hasPart: {
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/page-content-config.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/page-content-config.js
index 52ba41cd0a53f81cdf857cf8be03737c1cd6f09f..48058b7d015e5602a53794d19a7e46c86f56d779 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/page-content-config.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/page-content-config.js
@@ -1,7 +1,7 @@
 const config = {
     datasets: {
       Mandatory: [ 'title', 'datasetID', 'description', 'catalog', 'publisher', 'theme', 'issued', 'modified' ],
-      Advised: [ 'politicalGeocodingLevelURI', 'politicalGeocodingURI', 'availabilityDE', 'contributorID', 'geocodingDescription', 'legalBasis', 'qualityProcessURI', 'references', 'contributor', 'originator', 'maintainer', 'keyword', 'subject', 'contactPoint', 'landingPage', 'accrualPeriodicity', 'language', 'spatial', 'temporal', 'creator', 'identifier', 'admsIdentifier', 'page', 'accessRights' ],
+      Advised: [ 'politicalGeocodingLevelURI', 'politicalGeocodingURI', 'availabilityDE', 'contributorID', 'geocodingDescription', 'legalBasis', 'qualityProcessURI', 'references', 'contributor', 'originator', 'maintainer', 'keyword', 'contactPoint', 'landingPage', 'accrualPeriodicity', 'language', 'spatial', 'temporal', 'creator', 'identifier', 'admsIdentifier', 'page', 'accessRights' ],
       Recommended: [ 'type', 'isUsedBy', 'conformsTo', 'versionInfo', 'versionNotes', 'temporalResolution', 'spatialResolutionInMeters', 'relation', 'qualifiedRelation', 'isReferencedBy', 'hasVersion', 'isVersionOf', 'source', 'provenance', 'qualifiedAttribution', 'wasGeneratedBy' ],
       Distributions: [],
       Overview: [ 'overview' ]
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/prefixes.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/prefixes.js
index f76df2b136d25bdae969a4b475ba9d0774dd1d03..dcf67d9c1fa979d39175a8b635b89f59bc94008b 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/prefixes.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/prefixes.js
@@ -19,7 +19,7 @@ const prefixes = {
     vcard: "http://www.w3.org/2006/vcard/ns#",
     time: "http://www.w3.org/2006/time#",
     dext: "https://data.europa.eu/ns/ext#",
-    dcatde:"http://www.dcat-ap.de/def/dcatde/"
+    dcatde: "http://dcat-ap.de/def/dcatde/"
 };
   
 export default prefixes;
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/vocab-prefixes.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/vocab-prefixes.js
index 3e13196fbbd88f7a9de83d61094abe4bf265cd9d..614a35d52ca0edbfe5fa378020c633a897b313cf 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/vocab-prefixes.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dcatapde/vocab-prefixes.js
@@ -1,5 +1,5 @@
 const vocabPrefixesDCATAPDE = {
-    "licenses": "http://dcat-ap.de/def/licenses/",
+    "licence": "http://dcat-ap.de/def/licenses/",
     "contributors": "http://dcat-ap.de/def/contributors/",
     "dataset-type": "http://publications.europa.eu/resource/authority/dataset-type/",
     "dataset-types": "http://dcat-ap.de/def/datasetTypes/",
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dpi-spec-config.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dpi-spec-config.js
index 0e00848c28e26e01ac76e1e3f1655fef77436286..40c2a24c82b405c8c17fed5abf4057811529d1db 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dpi-spec-config.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/config/dpi-spec-config.js
@@ -31,7 +31,7 @@ import vocabPrefixesDCATAPDEHAPPYFLOW from './dcatapdeHappyFlow/vocab-prefixes';
 
 
 
-const config = {
+export const config = {
     dcatap: {
         pageConent: pageContent,
         inputDefinition: inputDefinition,
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/index.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fe55e12d7792db663ffad266be1491e69b68e1d4
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/index.ts
@@ -0,0 +1,82 @@
+import { App } from 'vue';
+
+export * from './composables/index'
+export { config as dpiSpecConfig } from './config/dpi-spec-config'
+
+// Import data-provider-interface components
+import AutocompleteInput from "./components/AutocompleteInput.vue";
+import ConditionalInput from "./components/ConditionalInput.vue";
+import DataFetchingComponent from "./components/DataFetchingComponent.vue";
+import Dropup from "./components/Dropup.vue";
+import FileUpload from "./components/FileUpload.vue";
+import InfoSlot from "./components/InfoSlot.vue";
+import LanguageSelector from "./components/LanguageSelector.vue";
+import Navigation from "./components/Navigation.vue";
+import UniqueIdentifierInput from "./components/UniqueIdentifierInput.vue";
+import inputDefinitions from "../form/inputDefinitions";
+
+// import data provider-interface views OverviewPage
+import CatalogueOverview from "./views/OverviewPage/CatalogueOverview.vue";
+import DatasetOverview from "./views/OverviewPage/DatasetOverview.vue";
+import DistributionOverview from "./views/OverviewPage/DistributionOverview.vue";
+import PropertyEntry from "./views/OverviewPage/PropertyEntry.vue";
+
+// import data provider-interface views
+import DistOverview from "./views/DistributionOverview.vue";
+import DraftsPage from "./views/DraftsPage.vue";
+import InputPage from "./views/InputPage.vue";
+import LinkedDataViewer from "./views/LinkedDataViewer.vue";
+import OverviewPage from "./views/OverviewPage.vue";
+import UserCataloguesPage from "./views/UserCataloguesPage.vue";
+import UserProfilePage from "./views/UserProfilePage.vue";
+
+// import data provider-interface
+import DataProviderInterface from "./DataProviderInterface.vue";
+import DpiMenu from "./DPIMenu.vue";
+
+import store from "./store/dpiStore";
+
+export function registerComponents(app: App) {
+  app.component('AutocompleteInput', AutocompleteInput);
+  app.component('ConditionalInput', ConditionalInput);
+  app.component('DataFetchingComponent', DataFetchingComponent);
+  app.component('Dropup', Dropup);
+  app.component('FileUpload', FileUpload);
+  app.component('InfoSlot', InfoSlot);
+  app.component('LanguageSelector', LanguageSelector);
+  app.component('Navigation', Navigation);
+  app.component('UniqueIdentifierInput', UniqueIdentifierInput);
+
+  app.component('CatalogueOverview', CatalogueOverview);
+  app.component('DatasetOverview', DatasetOverview);
+  app.component('DistributionOverview', DistributionOverview);
+  app.component('PropertyEntry', PropertyEntry);
+
+  app.component('DistOverview', DistOverview);
+  app.component('DraftsPage', DraftsPage);
+  app.component('InputPage', InputPage);
+  app.component('LinkedDataViewer', LinkedDataViewer);
+  app.component('OverviewPage', OverviewPage);
+  app.component('UserCataloguesPage', UserCataloguesPage);
+  app.component('UserProfilePage', UserProfilePage);
+
+  app.component('DataProviderInterface', DataProviderInterface);
+  app.component('DpiMenu', DpiMenu);
+}
+
+// export components
+export { AutocompleteInput, ConditionalInput, DataFetchingComponent, Dropup, FileUpload, InfoSlot, LanguageSelector, Navigation, UniqueIdentifierInput }
+
+// export views
+export { CatalogueOverview, DatasetOverview, DistributionOverview, PropertyEntry }
+export { DistOverview, DraftsPage, InputPage, LinkedDataViewer, OverviewPage, UserCataloguesPage, UserProfilePage }
+
+// export data provider-interface
+export { DataProviderInterface, DpiMenu }
+
+export {
+  inputDefinitions,
+  store
+}
+
+export { injectionKey as injectionKeyRuntimeConfig } from '../services/runtimeConfigurationService';
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/dpiStore.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/dpiStore.ts
index ff08d20f6ecf7bb5451ba2cc3d5b7ca60f29545a..98c25284ae2b45cc92914a980721eada14532c90 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/dpiStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/dpiStore.ts
@@ -1,14 +1,30 @@
 // @ts-nocheck
 /* eslint-disable no-param-reassign, no-shadow, no-console */
 import formModule from './modules/formSchemaStore';
-import autocompleteModule from './modules/autocompleteStore';
 import conversionModule from './modules/conversionStore';
 import navigationModule from './modules/navigationStore';
 
-const state = {};
-const getters = {};
-const actions = {};
-const mutations = {};
+const state = {
+  // DPI specification as root state to be shared between all modules
+  specification: {},
+  specificationName: '',
+};
+const getters = {
+  getSpecification: state => state.specification,
+  getSpecificationName: state => state.specificationName
+};
+const actions = {
+  setSpecification: (context, specification) => {
+    context.commit('setSpecification', specification);
+  },
+  setSpecificationname: (context, specificationName) => {
+    context.commit('setSpecificationName', specificationName);
+  }
+};
+const mutations = {
+  setSpecification: (state, specification) => (state.specification = specification),
+  setSpecificationName: (state, specificationName) => (state.specificationName = specificationName)
+};
 
 const module = {
   namespaced: true,
@@ -18,7 +34,6 @@ const module = {
   getters,
   modules: {
     formModule,
-    autocompleteModule,
     conversionModule,
     navigationModule
   }
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/autocompleteStore.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/autocompleteStore.ts
deleted file mode 100644
index 1dcafb4aa3cc5958324bd796c67e309ed7f7e38d..0000000000000000000000000000000000000000
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/autocompleteStore.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-// @ts-nocheck
-/* eslint-disable no-param-reassign, no-shadow, no-console */
-import axios from 'axios';
-import generalDpiConfig from '../../config/dpi-spec-config.js';
-
-const state = {};
-const getters = {};
-
-const actions = {
-    requestFirstEntrySuggestions({ commit }, voc, base) {
-        return new Promise((resolve, reject) => {
-            const req = `${base}search?filter=vocabulary&vocabulary=${voc}`;
-            axios.get(req)
-                .then((res) => {
-                    resolve(res);
-                })
-                .catch((err) => {
-                    reject(err);
-                });
-        });
-    },
-    requestAutocompleteSuggestions({ commit }, { voc, text, base }) {
-        // console.log(voc,text,base); 
-        return new Promise((resolve, reject) => {
-            const req = `${base}search?filter=vocabulary&vocabulary=${voc}&q=${text}`;
-            axios.get(req)
-                .then((res) => {
-                    // console.log(res);
-
-                    resolve(res);
-                })
-                .catch((err) => {
-                    reject(err);
-                });
-        });
-    },
-    async requestResourceName({ commit }, { voc, uri, envs }) {
-        try {
-           
-            
-            const specification = envs.content.dataProviderInterface.specification;
-
-            // Catching invalid URI's
-            if (voc === undefined) return
-            if (voc === "application") return
-
-            let req;
-
-            // vocabularies for spdx checksum and inana-media-types are structured differently in the backend then other vocabularies
-            if (voc === 'iana-media-types' || voc === 'spdx-checksum-algorithm')  {
-                req = `${envs.api.baseUrl}vocabularies/${voc}`;
-
-            } else {
-                const value = encodeURIComponent(uri.replace(generalDpiConfig[specification].vocabPrefixes[voc], ""));
-        
-                
-                req = `${envs.api.baseUrl}vocabularies/${voc}/${value}`;
-
-            }
-            return new Promise((resolve, reject) => {
-                axios.get(req)
-                    .then((res) => {
-                        resolve(res);
-                    })
-                    .catch((err) => {
-                        reject(err);
-
-                    });
-            });
-        } catch (error) {
-            // console.log(error);
-
-        }
-
-    },
-};
-
-const mutations = {};
-
-const autocompleteModule = {
-    state,
-    getters,
-    actions,
-    mutations
-};
-
-export default autocompleteModule;
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/conversionStore.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/conversionStore.ts
index b4ca329d6a973639eb162992cdb6079cebb5278a..726471f40425f406a68f2af9fa00d12985af75fa 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/conversionStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/conversionStore.ts
@@ -9,8 +9,6 @@ import generalHelper from '../../utils/general-helper';
 import toRDF from '../../utils/RDFconverter';
 import toInput from '../../utils/inputConverter';
 
-import generalDpiConfig from '../../config/dpi-spec-config.js';
-
 const state = {
     datasets: {},
     distributions: [],
@@ -76,8 +74,8 @@ const actions = {
      * @param param0 
      * @param param1 Object containing endpoint and token for data fetching as well as property
      */
-    async convertToInput({ commit }, { endpoint, token, property, specification }) {
-        
+    async convertToInput({ commit, rootGetters }, { endpoint, token, property }) {
+        const specification = rootGetters['dpiStore/getSpecification'];
         const fetchedData = await generalHelper.fetchLinkedData(endpoint, token).then((response) => {
             return response;
         });
@@ -98,7 +96,8 @@ const actions = {
      * @param property Object containing all values within nested objects for each page of the frontend
      * @returns Data values in RDF format
      */
-    convertToRDF({ state }, { property, specification }) {
+    convertToRDF({ state, rootGetters }, { property }) {
+        const specification = rootGetters['dpiStore/getSpecification'];
 
         // merging objects with nested objects containing the values of each page into one main object containing all values for the given property
         const data = {
@@ -168,7 +167,7 @@ const mutations = {
      */
     saveLinkedDataToStore(state, { property, data, specification }) {
 
-        const dpiConfig = generalDpiConfig[specification];
+        const dpiConfig = specification;
         toInput.convertToInput(state, property, data, dpiConfig );
 
         localStorage.setItem(`dpi_${property}`, JSON.stringify(state[property]));
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/formSchemaStore.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/formSchemaStore.ts
index 2861f1bd1d5d8c922d6127bd4b2ef424c1e465be..d2e486d8f16a84bb1cf001a35139f5c453960d69 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/formSchemaStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/formSchemaStore.ts
@@ -1,7 +1,6 @@
 // @ts-nocheck
 /* eslint-disable no-param-reassign, no-shadow, no-console */
 import { isEmpty } from 'lodash-es';
-import generalDpiConfig from '../../config/dpi-spec-config.js';
 
 // external translation method
 import translate from '../../utils/translation-helper';
@@ -11,7 +10,8 @@ const state = {
         datasets: {},
         distributions: {},
         catalogues: {}
-    }
+    },
+    usersCatalogs: {}
 };
 
 const getters = {
@@ -26,9 +26,9 @@ const actions = {
      * @param {Object} param0
      * @param {Object} param1 Object containing property (datasets/catalogues), page (step1/step2/step3) and subpage (distribution1/distribution2/distribution3) of current view
      */
-    createSchema({ commit }, { property, page, specification }) {
+    createSchema({ commit, state, rootGetters }, { property, page }) {
 
-        const dpiConfig = generalDpiConfig[specification];
+        const dpiConfig = rootGetters['dpiStore/getSpecification'];
         const pageProperties = dpiConfig.pageConent[property][page]
         const propertyDefinitions = dpiConfig.inputDefinition[property]
         commit('extractSchema', { pageProperties, propertyDefinitions, property, page });
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/navigationStore.ts b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/navigationStore.ts
index b1c30cc88b6cc71f57a2e6c4be5c21c1fbd90529..d554515e00e3c9afbcb8e3e2c85f6b093f3a7281 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/navigationStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/store/modules/navigationStore.ts
@@ -1,9 +1,6 @@
 // @ts-nocheck
 /* eslint-disable no-param-reassign, no-shadow, no-console */
 
-// config defining which properties are displayed on which page
-import generalDpiConfig from '../../config/dpi-spec-config.js';
-
 const state = {
     navigation: {
         datasets: [],
@@ -13,8 +10,8 @@ const state = {
 };
 
 const getters = {
-    getNavSteps: (state) => (specification) => {
-        const dpiConfig = generalDpiConfig[specification];
+    getNavSteps: (state, _getters, _rootState, rootGetters) => (specification) => {
+        const dpiConfig = rootGetters['dpiStore/getSpecification'];
         setConfig(dpiConfig);
        
         return state.navigation;
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/RDFconverter.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/RDFconverter.js
index 1219d577d6f3beb00fb9e0fb1639e4a0cc45bcaf..452a1ccb10efa63994102883d4f7bb036489c235 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/RDFconverter.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/RDFconverter.js
@@ -16,10 +16,7 @@ function convertToRDF(data, property, specification) {
 
     let finishedRDFdata;
 
-    let dpiConfig;
-    if (specification === undefined) {
-        dpiConfig = generalDpiConfig["dcatap"]
-    } else dpiConfig = generalDpiConfig[specification];
+    let dpiConfig = specification;
 
     // writer for adding data as quads
     const RDFdata = new N3.Writer({ prefixes: dpiConfig.prefixes, format: 'N-Triples' });
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/inputConverter.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/inputConverter.js
index b675fe4708fcfa7910581e15baa10ee09db60407..c4005d65b1b011caa7aa82a93146017975155d79 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/inputConverter.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/inputConverter.js
@@ -172,7 +172,7 @@ function convertProperties(property, state, id, data, propertyKeys, dpiConfig) {
                     for (let tempIndex = 0; tempIndex < shorts.length; tempIndex += 1) {
                         const position = resolutionValue.indexOf(shorts[tempIndex]); // position of duration letter
                         const subDuration = resolutionValue.substring(0, position); // substring until position of duration letter
-                        const value = subDuration.match(/\d+/g)[0]; // extract number
+                        const value = subDuration?.match(/\d+/g)?.[0] ?? ''; // extract number
                         resolutionValue = resolutionValue.substring(position); // overwrite resolution string with shortened version (missing the extracted part)
                         state[key][forms[tempIndex]] = value; // write to result object
                     }
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/translation-helper.js b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/translation-helper.js
index 85f8d4a46424ef8b95b9f0be6af689ccc6b250a4..4b0aefaf26dd147afc0b4e2efe98d8fd73dfe782 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/translation-helper.js
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/utils/translation-helper.js
@@ -1,5 +1,5 @@
 import { has, isObject } from 'lodash-es';
-import store from '../../store';
+import { useI18n } from 'vue-i18n';
 
 /**
  * Translation of each translatable parameter within the given structure if a translation is available
@@ -7,9 +7,8 @@ import store from '../../store';
  * @param {String} property String defining which property translation should be used
  */
 
-function translateProperty(propertyDefinition, property) {
+function translateProperty(propertyDefinition, property, t, te) {
 
-    const i18n = store.$app.config.globalProperties.i18n.global;
     if (has(propertyDefinition, 'identifier')) { // hidden fields don't need a label and have no identifier
         const translatableParameters = ['label', 'info', 'help', 'placeholder', 'add-label'];
         const propertyName = propertyDefinition.identifier;
@@ -18,15 +17,15 @@ function translateProperty(propertyDefinition, property) {
             let translation = propertyName;
             const parameter = translatableParameters[valueIndex];
 
-            const translationExsists = i18n.te(`message.dataupload.${property}.${propertyName}.${parameter}`);
-            const translationExsistsEN = i18n.te(`message.dataupload.${property}.${propertyName}.${parameter}`, 'en');
+            const translationExsists = te(`message.dataupload.${property}.${propertyName}.${parameter}`);
+            const translationExsistsEN = te(`message.dataupload.${property}.${propertyName}.${parameter}`, 'en');
 
             // Check if translation exists
             if (!has(property, parameter)) {
                 if (translationExsists) {
-                    translation = i18n.t(`message.dataupload.${property}.${propertyName}.${parameter}`);
+                    translation = t(`message.dataupload.${property}.${propertyName}.${parameter}`);
                 } else if (translationExsistsEN) {
-                    translation = i18n.t(`message.dataupload.${property}.${propertyName}.${parameter}`, 'en');
+                    translation = t(`message.dataupload.${property}.${propertyName}.${parameter}`, 'en');
                 } else {
                     translation = parameter;
                 }
@@ -61,29 +60,29 @@ function translateProperty(propertyDefinition, property) {
  * @param {Object} schema Object containing the forms schema
  * @param {String} property String defining which property translation should be used (datasets/ distribution/ catalogues)
  */
-function translate(schema, property) {
+function translate(schema, property, t, te) {
     for (let index = 0; index < schema.length; index += 1) {
         const schemaPropertyValues = schema[index];
 
         // translation of group forms and their nested properties
         if (has(schemaPropertyValues, 'children')) {
             // group attributes should be translated too
-            translateProperty(schemaPropertyValues, property);
+            translateProperty(schemaPropertyValues, property, t, te);
             // translated nested properties
-            translate(schemaPropertyValues.children, property);
+            translate(schemaPropertyValues.children, property, t, te);
             // translation of conditional forms and their nested properties
         } else if (has(schemaPropertyValues, 'data')) {
             // group attributes should be translated too
-            translateProperty(schemaPropertyValues, property);
+            translateProperty(schemaPropertyValues, property, t, te);
             // translate nested data
             const dataKeys = Object.keys(schemaPropertyValues.data);
             for (let keyIndex = 0; keyIndex < dataKeys.length; keyIndex += 1) {
                 const currentKey = dataKeys[keyIndex];
-                translate(schemaPropertyValues.data[currentKey], property);
+                translate(schemaPropertyValues.data[currentKey], property, t, te);
             }
             // translation of 'normal' singular form properties
         } else {
-            translateProperty(schemaPropertyValues, property);
+            translateProperty(schemaPropertyValues, property, t, te);
         }
     }
 }
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/DraftsPage.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/DraftsPage.vue
index c9b553df1a59c6efb04ebf2996730c6846503467..da2cd46f76e5948059ac7fe800d3020fb5fa2d43 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/DraftsPage.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/DraftsPage.vue
@@ -298,10 +298,8 @@ export default {
 }
 
 .dropDownWrap {
-  width: 175px;
+  min-width: 175px;
   position: relative;
-
-
 }
 
 .dropdown-toggle {
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/InputPage.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/InputPage.vue
index 48996b5e028c838ef098527cd9fd62c9f97f9409..b9b65554d8e850f56ba6c2b1451de3796689b8f8 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/InputPage.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/InputPage.vue
@@ -6,7 +6,7 @@
         <FormKit type="form" v-model="formValues" :actions="false" :plugins="[stepPlugin]" id="dpiForm"
           @change="saveFormValues({ property: property, page: page, distid: id, values: formValues })"
           @click="saveFormValues({ property: property, page: page, distid: id, values: formValues })" @submit.prevent=""
-          class="d-flex">
+          class="d-flex" >
 
 
           <!-- DpiV3 Stepper - make it a component! -->
@@ -125,10 +125,10 @@
                    In this new approach, every property out of the page-content-config.js gets loaded separately. 
                    This is for the substepper to work correctly -->
 
-            <div style="width: 100%" v-for="(item, innerIndex) in Object.keys(getSchema(property)[stepName]).length"
-              v-show="Object.values(getSchema(property)[stepName][innerIndex])[0] === activeSubStep.replace(/_\d+$/, '') || stepName === 'Landing'">
+            <div style="width: 100%" v-for="(item, innerIndex) in Object.keys(getSchema(property).value[stepName]).length"
+              v-show="Object.values(getSchema(property).value[stepName][innerIndex])[0] === activeSubStep.replace(/_\d+$/, '') || stepName === 'Landing'">
               <FormKitSchema v-if="stepName !== 'Distributions'" @handleNav="handleNavInput"
-                :schema="getSchema(property)[stepName][innerIndex]" :library="library">
+                :schema="getSchema(property).value[stepName][innerIndex]" :library="library">
               </FormKitSchema>
             </div>
             <div v-if="activeStep === 'Landing'" class="dpiV3_CTALanding">
@@ -257,7 +257,7 @@
 
 <script>
 /* eslint-disable no-alert,arrow-parens,no-param-reassign,no-lonely-if */
-import { defineComponent, markRaw } from "vue";
+import { defineComponent, markRaw, computed } from "vue";
 import { mapActions, mapGetters } from "vuex";
 import $ from "jquery";
 import PropertyChooser from "./PropertyChooser.vue";
@@ -288,6 +288,8 @@ import { useI18n } from "vue-i18n";
 import "../config/styles/variables.css";
 import "../config/styles/typography.css";
 import { PhCheckCircle, PhNumberCircleFive } from "@phosphor-icons/vue";
+import { plugin, defaultConfig } from '@formkit/vue'
+import { useDpiContext, useFormSchema } from '../composables';
 
 export default defineComponent({
   props: {
@@ -344,11 +346,13 @@ export default defineComponent({
     PhNumberCircleFive
   },
   computed: {
-    ...mapGetters("auth", ["getIsEditMode", "getUserCatalogIds"]),
-    ...mapGetters("dpiStore", [
-      "getSchema",
-      "getNavSteps",
-      "getDeleteDistributionInline",
+    ...mapGetters('auth', [
+      'getIsEditMode',
+      'getUserCatalogIds',
+    ]),
+    ...mapGetters('dpiStore', [
+      'getNavSteps',
+      'getDeleteDistributionInline',
     ]),
     getTitleStep() {
       return Object.keys(this.formValues).filter((key) =>
@@ -381,14 +385,14 @@ export default defineComponent({
     },
   },
   methods: {
-    ...mapActions("auth", ["setIsEditMode", "setIsDraft"]),
-    ...mapActions("dpiStore", [
-      "createSchema",
-      "translateSchema",
-      "saveFormValues",
-      "saveLocalstorageValues",
-      "addCatalogOptions",
-      "clearAll",
+    ...mapActions('auth', [
+      'setIsEditMode',
+      'setIsDraft',
+    ]),
+    ...mapActions('dpiStore', [
+      'saveFormValues',
+      'saveLocalstorageValues',
+      'clearAll',
     ]),
     update() {
       this.$forceUpdate();
@@ -472,7 +476,6 @@ export default defineComponent({
           this.activeStep = steplist[this.stepCounter]["step"];
         }
       }
-
     },
     dropdownCLick() {
       const h4Elements = document.querySelectorAll(".formkitProperty h4");
@@ -503,17 +506,21 @@ export default defineComponent({
       // no validation in edit mode
 
       // get step name where issued and modified are included
-      const initialSchema = this.getSchema(this.property);
+      const initialSchema = this.getSchema(this.property).value;
       const stepWithDates = Object.keys(initialSchema).find(
         (key) =>
           initialSchema[key].map((el) => el.name).includes("dct:issued") ||
           initialSchema[key].map((el) => el.name).includes("dct:modified")
       );
 
-      if (
-        localStorage.getItem("dpi_editmode") === "true" &&
-        stepWithDates != undefined
-      ) {
+    
+     
+      this.$formkit.setLocale('de');
+      // console.log(this.$formkit);
+      
+
+      // this.$formkit.getValidationMessages()
+      if (localStorage.getItem('dpi_editmode') === 'true' && stepWithDates != undefined) {
         initialSchema[stepWithDates].forEach((el) => {
           if (
             el["identifier"] === "issued" ||
@@ -639,18 +646,16 @@ export default defineComponent({
               }
             }
           };
-          // MutationObserver
-          const observer = new MutationObserver(attributeChangedCallback);
-          const config = { attributes: true };
-          let allMatchingElements = [];
-
-          elements.forEach((element, index) => {
-            const matchingChildren = element.querySelectorAll(".formkit-outer");
-            allMatchingElements = allMatchingElements.concat(
-              Array.from(matchingChildren)
-            );
-            observer.observe(allMatchingElements[index], config);
-          });
+          // MutationObserver 
+          // const observer = new MutationObserver(attributeChangedCallback);
+          // const config = { attributes: true };
+          // let allMatchingElements = [];
+
+          // elements.forEach((element, index) => {
+          //   const matchingChildren = element.querySelectorAll('.formkit-outer');
+          //   allMatchingElements = allMatchingElements.concat(Array.from(matchingChildren));
+          //   observer.observe(allMatchingElements[index], config);
+          // });
         });
       });
     },
@@ -711,6 +716,7 @@ export default defineComponent({
   },
   mounted() {
     this.initInputPage();
+
   },
   watch: {
     activeStep: {
@@ -719,13 +725,14 @@ export default defineComponent({
       },
     },
     getFirstTitleFromForm: {
-      handler() {
-        if (localStorage.getItem("dpi_editmode") === "false") {
-          this.setIsDraft(false);
-          this.setIsEditMode(false);
+      handler(newVal, oldVal) {
+        if (newVal === oldVal) return
+        if (localStorage.getItem('dpi_editmode') === 'false') {
+          this.setIsDraft(false)
+          this.setIsEditMode(false)
         }
         // only create id from title if the user is not editing an existing dataset with an existing datasetID
-        if (!this.getIsEditMode) {
+        if (!this.isEditMode) {
           this.createDatasetID();
         }
       },
@@ -748,7 +755,7 @@ export default defineComponent({
     });
   },
   setup() {
-    const { t } = useI18n();
+    const dpiContext = useDpiContext();
     const {
       steps,
       activeStep,
@@ -760,6 +767,9 @@ export default defineComponent({
       goToNextStep,
       goToPreviousStep,
     } = useDpiStepper();
+    const { t, te } = useI18n()
+
+    const { translateSchema, createSchema, getSchema } = useFormSchema({ t, te });
 
     const scrollToTop = () => {
       let { x, y } = useWindowScroll({ behavior: "smooth" });
@@ -775,6 +785,11 @@ export default defineComponent({
 
     const library = markRaw({ OverviewPage });
 
+    const isEditMode = computed(() => {
+      return !!dpiContext.value.edit?.enabled
+    })
+
+
     return {
       steps,
       visitedSteps,
@@ -788,9 +803,12 @@ export default defineComponent({
       goToPreviousStep,
       scrollToTop,
       library,
-      t,
-    };
-  },
+      isEditMode,
+      translateSchema,
+      createSchema,
+      getSchema,
+    }
+  }
 });
 </script>
 
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage.vue
index 18e9fd03ac1cf1c232de1bb4ec9c41a0cc92c03c..ac4fc348417333b84afbdbfb7c7e6d6738f26c61 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="col-12">
+  <div ref="overview-page" class="col-12">
     <!-- LANGUAGE SELECTOR -->
     <div class="mt-5 mb-0">
       <div class="row">
@@ -9,13 +9,67 @@
         </div>
       </div>
     </div>
-    <div class="mb-3" v-if="showDatasetsOverview">
-      <DatasetOverview :dpiLocale="dpiLocale" />
+    <div class="mb-3" v-if="showDatasetsOverview && overviewPageIsVisible">
+      <DatasetOverview :dpiLocale="dpiLocale" :key="dpiLocale" />
     </div>
-    <div class="mb-3" v-if="showCatalogsOverview">
-      <CatalogueOverview :dpiLocale="dpiLocale" />
+    <div class="mb-3" v-if="showCatalogsOverview && overviewPageIsVisible">
+      <CatalogueOverview :dpiLocale="dpiLocale" :key="dpiLocale" />
     </div>
   </div>
+<!-- Legal notice *** Checks for ANNIF to determine that this UI is DEU -->
+  <div v-if="instance.content.dataProviderInterface.annifIntegration" class="legalnotice py-5" style="width: 90%; margin: 0 auto;">
+    <div class="d-flex align-items-start">
+      <svg xmlns="http://www.w3.org/2000/svg" width="30px" height="30px" fill="currentColor"
+        class="bi bi-info-circle mx-3 mb-3 mt-1 infoboxI" viewBox="0 0 16 16">
+        <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
+        <path
+          d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0" />
+      </svg>
+      <div class="w-80">
+        <p>For <strong>European</strong>&nbsp;<strong>Commission's datasets</strong>, bear in mind that&nbsp;<a
+            class="external-link" href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32011D0833"
+            target="_blank" rel="nofollow noopener"><ins>Decision 2011/833/EU</ins></a> allows for their commercial
+          reuse
+          without prior authorisation, except for the material subject to the third party intellectual property rights.
+          This
+          Decision has been implemented under the&nbsp;<a class="external-link"
+            href="https://ec.europa.eu/transparency/documents-register/detail?ref=C(2019)1655&amp;lang=en"
+            target="_blank" rel="nofollow noopener"><ins>Decision C(2019) 1655 final</ins></a> by which Creative Commons
+          Attribution 4.0
+          International Public License (CC BY 4.0) is adopted as an open licence for the Commission's reuse policy.
+          Additionally, raw data, metadata or other documents of comparable nature may alternatively be distributed
+          under
+          the provisions of the Creative Commons Universal Public Domain Dedication deed (CC0 1.0).</p>
+        <p>The&nbsp;<strong>Council</strong>&nbsp;and the&nbsp;<strong>European Court of Auditors</strong>&nbsp;have
+          approved similar decisions on reuse. It is advisable that you check&nbsp;<strong>the reuse policy of your
+            organisation</strong>&nbsp;before publishing or submitting your dataset.</p>
+      </div>
+    </div>
+    <!-- <p>&nbsp;</p>
+     <hr />
+    <p>&nbsp;</p> -->
+
+    <div class="d-flex align-items-start mt-4">
+      <svg xmlns="http://www.w3.org/2000/svg" width="30px" height="30px" fill="currentColor"
+        class="bi bi-info-circle mx-3 mb-3 mt-1 infoboxI " viewBox="0 0 16 16">
+        <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
+        <path
+          d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0" />
+      </svg>
+      <div class="w-80">
+        <p>As owner of your dataset, you guarantee that it does not violate the copyright, other intellectual property
+          or
+          privacy rights of any third party. In particular, if third party material is included in the dataset, you must
+          ensure that all necessary permissions have been obtained and appropriate acknowledgment is given, if
+          necessary.
+        </p>
+        <p>If you need further information regarding <strong>licenses or copyright</strong> issues, please contact us
+          at&nbsp;<span class="nobr"><a class="external-link" href="mailto:op-copyright@publications.europa.eu"
+              target="_blank" rel="nofollow noopener">op-copyright@publications.europa.eu</a></span></p>
+      </div>
+    </div>
+  </div>
+
 </template>
 
 <script>
@@ -27,6 +81,10 @@ import LanguageSelector from '../components/LanguageSelector';
 import DatasetOverview from './OverviewPage/DatasetOverview.vue';
 import CatalogueOverview from './OverviewPage/CatalogueOverview.vue';
 
+import { useIntersectionObserver } from '@vueuse/core'
+import { ref, useTemplateRef } from 'vue'
+import { getCurrentInstance } from "vue";
+
 export default {
   components: {
     LanguageSelector,
@@ -43,8 +101,9 @@ export default {
   },
   data() {
     return {
-      dpiLocale: 'en',
-    };
+      instance : getCurrentInstance().appContext.app.config.globalProperties.$env,
+      dpiLocale: this.$route.query?.locale || this.$i18n.locale || this.$i18n.fallbackLocale || 'en',
+    }
   },
   computed: {
     ...mapGetters('auth', [
@@ -58,7 +117,7 @@ export default {
     },
     showCatalogsOverview() {
       return this.property === 'catalogues';
-    },
+    }
   },
   methods: {
     ...mapActions('dpiStore', [
@@ -166,6 +225,28 @@ export default {
       }
     });
   },
+  setup() {
+    const target = useTemplateRef('overview-page')
+    const overviewPageIsVisible = ref(false)
+
+    // Workaround.
+    // Ensure the individual overview pages are only mounted whenever this overview page is visible.
+    // For some reason, the form values are not reactive so on initial load, the distribution values are not displayed properly.
+    // This workaround delays the initial mount of the overview page until the overview page is visible.
+    // We use the IntersectionObserver to check if the overview page is visible, but we could also use more proper datamodels to determine this.
+    // todo: figure out why the form values are not reactive on initial load
+    useIntersectionObserver(
+      target,
+      ([{ isIntersecting }]) => {
+        overviewPageIsVisible.value = isIntersecting
+      },
+      {
+        rootMargin: '999999px 999999px 999999px 999999px'
+      }
+    )
+
+    return {overviewPageIsVisible}
+  }
 };
 </script>
 
@@ -188,4 +269,23 @@ export default {
       }
     }
   }
-}</style>
+}
+
+.legalnotice {
+  a {
+    color: blue;
+  }
+
+  padding: 1rem;
+  background-color: rgb(171, 225, 165)
+}
+
+.infoboxI {
+  width: 5%;
+}
+
+.w-80 {
+  width: 80%;
+}
+
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DatasetOverview.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DatasetOverview.vue
index b6186bd11670a1e079ab942dd5f783d083818dda..56e30fa4d0f8ea77f28e1b01119f012d0475db76 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DatasetOverview.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DatasetOverview.vue
@@ -3,12 +3,15 @@
 
         <div class="overviewHeader p-3">
             <div class="firstRow d-flex  ">
-                <div class="datasetNotation dsd-title-tag d-flex align-items-center"><span>Dataset</span></div>
-                <h1 class="dsTitle"> {{ getTitle() }}</h1>
+                <div class="datasetNotation dsd-title-tag d-flex align-items-center"><span>
+                        {{ $te('message.metadata.dataset') ? $t('message.metadata.dataset') : 'Dataset' }}
+                    </span></div>
+                <h1 class="dsTitle"> {{ getTitle }}</h1>
             </div>
             <div class="secondRow d-flex justify-content-between">
                 <div class="dsCatalogue ">
-                    <span><b>Catalog:</b></span>
+                    <span><b>{{ $te('message.metadata.catalog') ? $t('message.metadata.catalog') : 'Catalogue'
+                            }}:</b></span>
                     <a href="">
                         {{ checkIfPropertySet(getDatasets, 'dcat:catalog') }}
                     </a>
@@ -19,17 +22,18 @@
                         :dpiLocale="dpiLocale"></PropertyEntry>
                 </div>
                 <div class="dsIssued ">
-                    <span><b>Issued:</b></span>
+                    <span><b>
+                            {{ $te('message.dataupload.datasets.issued.label') ?
+                                $t('message.dataupload.datasets.issued.label') : 'Issued' }}:</b></span>
                     <a>
-                        {{ new Date(checkIfPropertyValueSet(getDatasets, 'dct:issued', '@value')).toDateString() }}
-                        <!-- {{ new Date(getDatasets['dct:modified']).toISOString().split('T')[0] }} -->
+                        {{ getDate(new Date(checkIfPropertyValueSet(getDatasets, 'dct:issued', '@value'))) }}
                     </a>
                 </div>
                 <div class="dsUpdated ">
-                    <span><b>Updated:</b></span>
+                    <span><b>{{ $te('message.dataupload.datasets.modified.label') ?
+                        $t('message.dataupload.datasets.modified.label') : 'Updated' }}:</b></span>
                     <a>
-                        {{ new Date(checkIfPropertyValueSet(getDatasets, 'dct:modified', '@value')).toDateString() }}
-                        <!-- {{ new Date(getDatasets['dct:modified']).toISOString().split('T')[0] }} -->
+                        {{ getDate(new Date(checkIfPropertyValueSet(getDatasets, 'dct:modified', '@value')))}}
                     </a>
                 </div>
             </div>
@@ -37,7 +41,7 @@
         <div class="dsMainWrap d-flex flex-column mt-3">
             <div class="">
                 <p class="dsDesc px-3">
-                    {{ getDescription() }}
+                    {{ getDescription }}
                 </p>
             </div>
             <div class="">
@@ -154,31 +158,44 @@ export default {
         },
         storeData() {
             return this.getData('datasets')
-        }
+        },
+        getTitle() {
+            return this.getDatasets['dct:title'] && this.getDatasets['dct:title'].filter(el => el['@language'] === this.dpiLocale).map(el => el['@value'])[0];
+        },
+        getDescription() {
+            return this.getDatasets['dct:description'] && this.getDatasets['dct:description'].filter(el => el['@language'] === this.dpiLocale).map(el => el['@value'])[0];
+        },
     },
     methods: {
-        ...mapActions("dpiStore", [
-            "requestFirstEntrySuggestions",
-            "requestAutocompleteSuggestions",
-        ]),
         checkIfPropertySet(data, property) {
             if (data[property] != undefined) return data[property]
             else {
-                return "No data available"
+                return '-'
+                // return "No data available"
+            }
+        },
+        getDate(date) {
+            if (!(date instanceof Date) || isNaN(date.getTime())) return '-';
+
+            let options = {};
+            if (this.dpiLocale === 'de') {
+                options = { year: 'numeric', month: 'long', day: 'numeric' };
+                return date.toLocaleDateString('de-DE', options);
+            }
+            else {
+                options = { year: 'numeric', month: 'long', day: 'numeric' };
+                return date.toLocaleDateString('en-EN', options);
             }
+
+
         },
         checkIfPropertyValueSet(data, property, value) {
             if (data[property] != undefined && data[property][value] != undefined) return data[property][value]
             else {
-                return "No data available"
+                return '-'
+                // return "No data available"
             }
         },
-        getTitle() {
-            return this.getDatasets['dct:title'] && this.getDatasets['dct:title'].filter(el => el['@language'] === this.dpiLocale).map(el => el['@value'])[0];
-        },
-        getDescription() {
-            return this.getDatasets['dct:description'] && this.getDatasets['dct:description'].filter(el => el['@language'] === this.dpiLocale).map(el => el['@value'])[0];
-        },
         async reqName(URI) {
             let nameOfProperty = URI.split('/')
             let req = `${this.$env.api.baseUrl}vocabularies/${nameOfProperty[nameOfProperty.length - 2]}/${nameOfProperty[nameOfProperty.length - 1]}`
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DistributionOverview.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DistributionOverview.vue
index 6d3863509523dc5d23bf4e5383fde5b6199afabb..7bc15795457e5664b4b7d72061a2967758f7e374 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DistributionOverview.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/DistributionOverview.vue
@@ -3,14 +3,13 @@
         <!-- DISTRIBUTIONS -->
         <div class="w-100 disDetailsWrap">
             <div class="tHeadWrap">
-                <!-- ToDo integrate Weblate -->
-                <p class="">Name of the Distribution</p>
-                <p class="">Format</p>
-                <p class="">Updated</p>
-                <p class="">Actions</p>
+                <p class="">{{ $t('message.dataupload.datasets.distribution.overview.name') }}</p>
+                <p class="">{{ $t('message.metadata.format') }}</p>
+                <p class="">{{ $t('message.metadata.updated') }}</p>
+                <p class="">{{ $t('message.metadata.issued') }}</p>
+                <p class="">{{ $t('message.dataupload.info.actions') }}</p>
             </div>
             <div v-for="( distribution, id) in distributionList" :key="'distribution' + id">
-
                 <div class="tdWrap" v-if="id % 2 == 0">
                     <p v-if="distribution['dct:title'] != undefined && distribution['dct:title'].filter(el => el['@language'] === dpiLocale).map(el =>
                         el['@value'])[0]">
@@ -18,7 +17,7 @@
                             el['@value'])[0] }}
                     </p>
                     <p v-else>
-                        No title in this language
+                        {{ $t('message.dataupload.datasets.distribution.overview.notitleinthislanguage') }}
                     </p>
                     <p v-if="distribution['dct:format'] != '' || Object.keys(distribution['dct:format']).length != 0">
                         <PropertyEntry profile="distributions" :data="distributionList[id]" property='dct:format'
@@ -26,10 +25,17 @@
                         </PropertyEntry>
                     </p>
                     <p v-else>
-                        No format provided
+                        {{ $t('message.dataupload.datasets.distribution.overview.noformatprovided') }}
+                    </p>
+                    <p v-if="new Date(distribution['dct:modified']['@value']).toLocaleDateString(dpiLocale) != 'Invalid Date'">
+                       
+                        {{ new Date(distribution['dct:modified']['@value']).toLocaleDateString(dpiLocale) }} 
+                    </p>
+                    <p v-else>
+                        -
                     </p>
-                    <p v-if="distribution['dct:modified'] != undefined && distribution['dct:modified']">
-                        {{ new Date(distribution['dct:modified']['@value']).toDateString() }}
+                    <p v-if="new Date(distribution['dct:issued']['@value']).toLocaleDateString(dpiLocale) != 'Invalid Date'">
+                        {{ new Date(distribution['dct:issued']['@value']).toLocaleDateString(dpiLocale) }}
                     </p>
                     <p v-else>
                         -
@@ -52,7 +58,7 @@
                             el['@value'])[0] }}
                     </p>
                     <p v-else>
-                        No title in this language
+                        {{ $t('message.dataupload.datasets.distribution.overview.notitleinthislanguage') }}
                     </p>
                     <p v-if="distribution['dct:format'] != undefined">
                         <PropertyEntry profile="distributions" :data="distributionList[id]" property='dct:format'
@@ -60,14 +66,22 @@
                         </PropertyEntry>
                     </p>
                     <p v-else>
-                        No format provided
-                    </p>
-                    <p v-if="distribution['dct:modified'] != undefined && distribution['dct:modified']">
-                        {{ new Date(distribution['dct:modified']['@value']).toDateString() }}
-                    </p>
-                    <p v-else>
-                        -
+                        {{ $t('message.dataupload.datasets.distribution.overview.noformatprovided') }}
                     </p>
+
+                    <p v-if="new Date(distribution['dct:modified']['@value']).toLocaleDateString(dpiLocale) != 'Invalid Date'">
+                       
+                       {{ new Date(distribution['dct:modified']['@value']).toLocaleDateString(dpiLocale) }} 
+                   </p>
+                   <p v-else>
+                       -
+                   </p>
+                   <p v-if="new Date(distribution['dct:issued']['@value']).toLocaleDateString(dpiLocale) != 'Invalid Date'">
+                       {{ new Date(distribution['dct:issued']['@value']).toLocaleDateString(dpiLocale) }}
+                   </p>
+                   <p v-else>
+                       -
+                   </p>
                     <p>
                         <a class="moreDisInfoBtn" @click="unfoldDisDetails(id)">
                             More information
@@ -93,7 +107,7 @@
                                     <!-- DISTRIBUTIONS ACCESS URL -->
                                     <table class="table table-borderless table-responsive pl-3 bg-light mb-0"
                                         v-if="showValue(distribution, 'dcat:accessURL')">
-                                        <tr v-for="( elem, index ) in  distribution['dcat:accessURL'] " :key="index">
+                                        <tr v-for="( elem, index ) in distribution['dcat:accessURL'] " :key="index">
                                             <td class="font-weight-bold w-25">
                                                 {{ $t('message.metadata.accessUrl') }}:
                                             </td>
@@ -105,7 +119,7 @@
                                         </tr>
                                     </table>
                                     <table class="table table-borderless table-responsive pl-3 bg-light">
-                                        <div v-for="( value, name, index ) in  tableProperties " :key="index">
+                                        <div v-for="( value, name, index ) in tableProperties " :key="index">
                                             <PropertyEntry profile="distributions" :data="distributionList[id]"
                                                 :property="name" :value="value" :dpiLocale="dpiLocale" :distId="id">
                                             </PropertyEntry>
@@ -280,4 +294,4 @@ export default {
     display: flex;
     align-items: center;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/MultilingualProp.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/MultilingualProp.vue
new file mode 100644
index 0000000000000000000000000000000000000000..eba5de5ac93cc0a3ea8fdeeb205017c5836e2970
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/MultilingualProp.vue
@@ -0,0 +1,22 @@
+<template>
+    <tr class="w-100">
+        <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
+
+        <td class="d-flex flex-column">
+            {{ data[property].filter(el => el['@language']).length === 0 ?
+                data[property].map(el => el['@value'])[0] :
+                data[property].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] ||
+                $t('message.catalogsAndDatasets.noDescriptionAvailable') }}
+        </td>
+    </tr>
+</template>
+<script setup>
+const props = defineProps({
+    property: Object,
+    value: Object,
+    data: Object,
+    dpiLocale: Object
+})
+
+</script>
+<style scoped></style>
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/SpecialProp.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/SpecialProp.vue
index 04118610f807eed2274e368ae0e50ea9ec9e18d8..1f15a01c8da0f99300204d3f30be9b81399ab176 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/SpecialProp.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/SpecialProp.vue
@@ -6,7 +6,7 @@
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td>
             <div v-if="showValue(data, 'rdf:type')">{{ $t('message.metadata.type') }}: {{ data['rdf:type'].split(':')[1]
-            }}
+                }}
             </div>
             <div v-if="showValue(data, 'foaf:name')">{{ $t('message.metadata.name') }}: {{ data['foaf:name'] }}</div>
             <div v-if="showValue(data, 'foaf:mbox')">{{ $t('message.metadata.email') }}: <app-link
@@ -23,12 +23,12 @@
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td class="">
             <div v-if="showValue(data, 'rdf:type')">{{ $t('message.metadata.type') }}: {{ data['rdf:type'].split(':')[1]
-            }}
+                }}
             </div>
             <div v-if="showValue(data, 'vcard:fn')">{{ $t('message.metadata.name') }}: {{ data['vcard:fn'] }}</div>
             <div v-if="showValue(data, 'vcard:hasEmail')">{{ $t('message.metadata.email') }}: <app-link
                     :to="`mailto:${data['vcard:hasEmail']}`">{{ data['vcard:hasEmail'] }}</app-link></div>
-            <div v-if="showValue(data, 'vcard:hasOrganizationName')">{{ $t('message.metadata.organizationName') }}: {{
+            <div v-if="showValue(data, 'vcard:hasOrganizationName')">{{
                 data['vcard:hasOrganizationName'] }}</div>
             <div v-if="showValue(data, 'vcard:hasTelephone')">{{ $t('message.metadata.telephone') }}: {{
                 data['vcard:hasTelephone'] }}</div>
@@ -51,7 +51,8 @@
     <tr v-if="property === 'dct:contributor' || property === 'dcatde:maintainer' || property === 'dcatde:originator'">
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td>
-            <div v-if="showValue(data, 'rdf:type')">{{ $t('message.metadata.type') }}: {{ data['rdf:type'].split(':')[1] }}
+            <div v-if="showValue(data, 'rdf:type')">{{ $t('message.metadata.type') }}: {{ data['rdf:type'].split(':')[1]
+                }}
             </div>
             <div v-if="showValue(data, 'foaf:name')">{{ $t('message.metadata.name') }}: {{ data['foaf:name'] }}</div>
             <div v-if="showValue(data, 'foaf:mbox')">{{ $t('message.metadata.email') }}: <app-link
@@ -102,23 +103,28 @@
     <div v-if="property === 'foaf:page'" class="w-100 d-flex">
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td>
-            <div v-if="showMultilingualValue(data, 'dct:title')">{{ $t('message.metadata.title') }}: {{ 
-                data['dct:title'].filter(el => el['@language']).length === 0 ? 
-                data['dct:title'].map(el => el['@value'])[0] : 
-                data['dct:title'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] }}</div>
+            <div v-if="showMultilingualValue(data, 'dct:title')">{{ $t('message.metadata.title') }}: {{
+                data['dct:title'].filter(el => el['@language']).length === 0 ?
+                    data['dct:title'].map(el => el['@value'])[0] :
+                    data['dct:title'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] ||
+                    $t('message.dataupload.datasets.distribution.overview.notitleinthislanguage')
+            }}
+            </div>
             <!-- <div v-if="showMultilingualValue(data, 'dct:title')" class="multilang">This property is available in: <span -->
             <!-- v-for="(el, index) in data['dct:title']" :key="index">({{ el['@language'] }}) </span></div> -->
-            <div v-if="showMultilingualValue(data, 'dct:description')">{{ $t('message.metadata.description') }}: {{ 
-                data['dct:description'].filter(el => el['@language']).length === 0 ? 
-                data['dct:description'].map(el => el['@value'])[0] : 
-                data['dct:description'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] }}</div>
+            <div v-if="showMultilingualValue(data, 'dct:description')">{{ $t('message.metadata.description') }}: {{
+                data['dct:description'].filter(el => el['@language']).length === 0 ?
+                    data['dct:description'].map(el => el['@value'])[0] :
+                    data['dct:description'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] ||
+                    $t('message.catalogsAndDatasets.noDescriptionAvailable') }}</div>
             <!-- <div v-if="showMultilingualValue(data, 'dct:description')" class="multilang">This property is available in: -->
             <!-- <span v-for="(el, index) in data['dct:description']" :key="index">({{ el['@language'] }}) </span></div> -->
-            <div v-if="showValue(data, 'dct:format')">{{ $t('message.metadata.format') }}: {{ data['dct:format']['name'] }}
+            <div v-if="showValue(data, 'dct:format')">{{ $t('message.metadata.format') }}: {{ data['dct:format']['name']
+                }}
             </div>
             <div v-if="showValue(data, '@id')">{{ $t('message.metadata.url') }}: <app-link :to="data['@id']">{{
                 data['@id']
-            }}</app-link></div>
+                    }}</app-link></div>
         </td>
     </div>
 
@@ -138,25 +144,31 @@
             <div>{{ convertTemporalResolution(data) }}</div>
         </td>
     </tr>
-
     <!-- DATA SERVICE -->
-    <tr v-if="showDataService()">
-
+    <tr v-if="data['rdf:type'] === 'dcat:DataService'">
+     
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td class="">
             <div v-if="showValue(data, 'dct:title')">
                 <span class="">{{ $t('message.dataupload.distributions.accessServiceTitle.label')
-                }}:</span>
+                    }}:</span>
                 {{ data['dct:title'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] }}
+                <span
+                    v-if="data['dct:title'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] === undefined"><b>{{
+                        $t('message.dataupload.datasets.distribution.overview.notitleinthislanguage') }}</b></span>
             </div>
             <div v-if="showValue(data, 'dct:description')">
                 <span class="">{{ $t('message.dataupload.distributions.accessServiceDescription.label')
-                }}:</span>
+                    }}:</span>
                 {{ data['dct:description'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] }}
+                <span
+                    v-if="data['dct:description'].filter(el => el['@language'] === dpiLocale).map(el => el['@value'])[0] === undefined"><b>{{
+                        $t('message.dataupload.datasets.distribution.overview.nodescriptioninthislanguage')
+                        }}</b></span>
             </div>
             <div v-if="showValue(data, 'dcat:endpointURL')" class="pr-1">
                 <span class="">{{ $t('message.dataupload.distributions.accessServiceEndpointURL.label')
-                }}:</span>
+                    }}:</span>
                 <app-link class="w-100" :to="data['dcat:endpointURL']">{{ data['dcat:endpointURL'] }}</app-link>
             </div>
         </td>
@@ -199,12 +211,13 @@
         </URIProp>
     </tr>
     <!-- License -->
-    
+
     <tr v-if="manualSwitch(data) === 'liMan'">
         <td class=" font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <td>
             <div v-for="item, index in Object.keys(data['dct:license']) ">
-                <div v-if="data['dct:license'][item] != null && data['dct:license'][item] != '' && item === 'dct:title'">
+                <div
+                    v-if="data['dct:license'][item] != null && data['dct:license'][item] != '' && item === 'dct:title'">
                     <span class="">{{
                         $t('message.dataupload.distributions.licenceTitle.label') }}:</span>
                     <span>{{ data['dct:license'][item] }}</span>
@@ -249,13 +262,17 @@ export default {
         AppLink,
         URIProp,
     },
+
     methods: {
-        showDataService() {
-            try {
-                return this.property === 'dcat:accessService' && Object.keys(this.data[Object.keys(this.data)[0]][0]).length > 1 && Object.keys(this.data[Object.keys(this.data)[1]][0]).length > 1;
-            } catch (error) {
-            }
-        },
+        // showDataService() {
+
+
+        //     try {
+        //         return this.property === 'dcat:accessService' && Object.keys(this.data[Object.keys(this.data)[0]][0]).length > 1 && Object.keys(this.data[Object.keys(this.data)[1]][0]).length > 1;
+
+        //     } catch (error) {
+        //     }
+        // },
         manualSwitch(propData, head) {
 
             if (propData != undefined) {
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/StringProp.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/StringProp.vue
index 99087ef155cad936278bbb04c0ef7995145092b7..03bc6534fe8fd50fc91bdf2fcc9c4cff3e6fcdbf 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/StringProp.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/StringProp.vue
@@ -1,5 +1,5 @@
 <template>
-    <td class="font-weight-bold">{{ $t(`${value.label}`) }}</td>
+    <td class="font-weight-bold">{{ $t(`${value.label}`) }}:</td>
     <div>
         <!-- MULTISTRING -->
         <td v-if="value.type === 'multiString'">
@@ -9,8 +9,9 @@
 
         <!-- SINGULAR STRING -->
         <td v-if="value.type === 'singularString'">
+            
 
-            <span v-if="data[property]['@type'] != '' && property === 'dct:rights'">{{ data[property][Object.keys(data[property])[1]] }}</span>
+            <span v-if="data[property]['@type'] != '' && property === 'dct:rights'"> {{ data[property]['rdfs:label'] }}</span>
             <span v-if="property != 'dct:rights'">
                 {{ data[property] }} <span v-if="property === 'dcat:spatialResolutionInMeters'">Meters</span>
             </span>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URIProp.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URIProp.vue
index 78d9bfbcb1289d3fc2ed863a9f1492030e9565ef..c04f2e4729e36712062165350a1e7b211a0ed42e 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URIProp.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URIProp.vue
@@ -33,6 +33,8 @@ import { mapActions } from 'vuex';
 import { getTranslationFor } from "../../../../utils/helpers";
 import generalHelper from '../../../utils/general-helper';
 import dpiConfig from '../../../config/dpi-spec-config';
+import { useDpiContext } from '../../../composables/useDpiContext';
+import { useAutocomplete } from '../../../composables/aucotomplete';
 
 export default {
   data() {
@@ -48,9 +50,6 @@ export default {
     inHeader: String
   },
   methods: {
-    ...mapActions("dpiStore", [
-      "requestResourceName",
-    ]),
     trimString(str, maxLength) {
       if (str.length > maxLength) {
         return str.slice(0, maxLength) + '...';
@@ -96,17 +95,6 @@ export default {
         return name
       }
     },
-    async getURILabel(value) {
-      // only request name if there is no name already given
-      // console.log('########',value);
-      if (generalHelper.isUrl(value.name)) {
-
-        const prefixes = dpiConfig[this.$env.content.dataProviderInterface.specification].vocabPrefixes;
-        const vocabulary = Object.keys(prefixes).find(key => value.name.includes(key));
-        return await this.requestURILabel(vocabulary, value.name);
-      }
-      else return value.name;
-    }
   },
   async created() {
 
@@ -132,6 +120,25 @@ export default {
       console.warn(e);
     }
   },
+  setup() {
+    const { requestResourceName } = useAutocomplete()
+    const dpiConfig = useDpiContext();
+
+    async function getURILabel(value) {
+      if (generalHelper.isUrl(value.name)) {
+
+        const prefixes = dpiConfig.value.specification.vocabPrefixes;
+        const vocabulary = Object.keys(prefixes).find(key => value.name.includes(key));
+        return await this.requestURILabel(vocabulary, value.name);
+      }
+      else return value.name;
+    }
+
+    return {
+      requestResourceName,
+      getURILabel,
+    }
+  }
 }
 
 </script>
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URLProp.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URLProp.vue
index 1cd73804374bdb123988edc81ba1244e0dcee9ed..51876a86fca9ce4b7e82ddbeda89df2200f127c0 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URLProp.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/Properties/URLProp.vue
@@ -1,6 +1,6 @@
 <template>
   
-        <td class="font-weight-bold">{{ $t(`${value.label}`) }}</td>
+        <td class="font-weight-bold">{{ $t(`${value.label}`) }}:</td>
         <!-- SINGULAR URL -->
         <td v-if="value.type === 'singularURL'">
           
@@ -19,23 +19,31 @@
             <div v-else>
              
                 <div v-for="(el, index) in data[property]" :key="index">
-                    <!-- regular multiple URLs -->
+     
+                    <!-- regular multiple URLs wit ID Notation-->
                     <app-link v-if="showValue(el, '@id')" :to="el['@id']">
                         {{ el['@id'] }}
                     </app-link>
+                   
                     <!-- IS USED BY -->
                     <app-link v-if="showValue(el, 'dext:isUsedBy')" :to="el['dext:isUsedBy']">
                         {{ el['dext:isUsedBy'] }}
                     </app-link>
+                        <!-- regular multiple URLs as an array -->
+                    <app-link v-if="typeof el === 'string'" :to="el" >
+                        {{ el }} 
+                    </app-link>
 
                 </div>
             </div>
             <!-- <div class="infoI" @click="editProp(property)"></div> -->
         </td>
+   
     
 </template>
 
 <script>
+import { string } from "zod";
 import AppLink from "../../../../widgets/AppLink.vue";
 import { has, isNil, isEmpty } from 'lodash-es';
 
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/PropertyEntry.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/PropertyEntry.vue
index 63abf0a4888bc18d5eb7d88cc06d525679d5602d..03d5a55adc119f3698129e4ff401b94720e383f2 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/PropertyEntry.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/OverviewPage/PropertyEntry.vue
@@ -1,16 +1,17 @@
 <template>
     <div>
-       
+
         <tr class="align-items-center" v-if="isSet">
             <!-- <td class=" font-weight-bold" v-if="value.type !== 'special'">{{ $t(`${value.label}`) }}:</td> -->
             <URIProp v-if="value.type === 'singularURI' || value.type === 'multiURI' || value.type === 'singularURI'"
                 :property="property" :value="value" :data="data" :inHeader="inHeader">
             </URIProp>
-            <URLProp v-if="value.type === 'singularURL' || value.type === 'multiURL'" :property="property" :value="value"
-                :data="data"></URLProp>
+            <URLProp v-if="value.type === 'singularURL' || value.type === 'multiURL'" :property="property"
+                :value="value" :data="data"></URLProp>
             <StringProp v-if="value.type === 'singularString' || value.type === 'multiString'" :property="property"
                 :value="value" :data="data" :dpiLocale="dpiLocale"></StringProp>
-
+            <MultilingualProp v-if="value.type === 'multiLingual' " :property="property"
+                :value="value" :data="data" :dpiLocale="dpiLocale"></MultilingualProp>
 
             <!-- SPECIAL -->
             <div class="w-100" v-if="value.type === 'special'">
@@ -20,7 +21,8 @@
                 <div
                     v-else-if="property != 'dct:creator' && property != 'dcat:temporalResolution' && property != 'spdx:checksum'">
                     <div v-for="(elem, index) in data[property]" :key="index">
-                        <SpecialProp :property="property" :value="value" :data="elem" :dpiLocale="dpiLocale"></SpecialProp>
+                        <SpecialProp :property="property" :value="value" :data="elem" :dpiLocale="dpiLocale">
+                        </SpecialProp>
                     </div>
                 </div>
                 <div v-else>
@@ -39,6 +41,7 @@ import URIProp from './Properties/URIProp.vue';
 import URLProp from './Properties/URLProp.vue';
 import StringProp from './Properties/StringProp.vue';
 import SpecialProp from './Properties/SpecialProp.vue';
+import MultilingualProp from './Properties/MultilingualProp.vue';
 import generalHelper from '../../utils/general-helper';
 
 import { has, isNil, isEmpty } from 'lodash';
@@ -49,6 +52,7 @@ export default {
         URLProp,
         StringProp,
         SpecialProp,
+        MultilingualProp
     },
     props: {
         profile: String,
@@ -58,7 +62,7 @@ export default {
         dpiLocale: String,
         distId: Number,
         type: String,
-        inHeader:String
+        inHeader: String
     },
     computed: {
         isSet() {
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserCataloguesPage.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserCataloguesPage.vue
index b019246d5e4fd8930ef2d8984319fc7e753225c6..a7d9a5d896b6817891391d82f82434b20184f81c 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserCataloguesPage.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserCataloguesPage.vue
@@ -3,12 +3,17 @@ import { useStore } from 'vuex';
 import { ref, computed, onMounted, } from 'vue';
 import AppLink from "../../widgets/AppLink.vue";
 import axios from 'axios'
+import { useRouter, useRoute } from 'vue-router';
 import { getCurrentInstance } from "vue";
+
 import {
   has,
   isNil,
 } from 'lodash-es';
 
+const router = useRouter();
+const route = useRoute();
+
 let env = getCurrentInstance().appContext.app.config.globalProperties.$env;
 const store = useStore();
 let filteredCatalogs = ref([])
@@ -30,6 +35,17 @@ let filterCatList = async () => {
   filteredCatalogs.value = filteredCatalogs.value
     .filter(item => userCatIDList.value.includes(item.id))
     .map(item => ({ id: item.id, name: item.title }));
+}
+const handleMQA = (cat) => {
+
+  router.push({
+    name: 'DataProviderInterface-MQASettings',
+    params: { id: cat.id },
+    query: { locale: route.query.locale }
+  }).catch(() => { });
+}
+const handleEdit = () => {
+
 }
 onMounted(async () => {
   filterCatList()
@@ -40,27 +56,88 @@ onMounted(async () => {
     <div class="d-flex flex-column bg-transparent container-fluid justify-content-between content ">
       <h1 class="small-headline">{{ $t('message.dataupload.info.userCatalogues') }}</h1>
       <p class="m-0 ">{{ $t('message.dataupload.info.userCatDescription') }}</p>
-      <div class="catWrap">
+      <!-- <div class="catWrap">
         <div v-for="(catalog, index) in filteredCatalogs" :key="index" class="annifItems ">
           <app-link
             :to="{ name: 'CatalogueDetails', query: { locale: $route.query.locale }, params: { ctlg_id: catalog.id } }">{{
               catalog.name }}</app-link>
         </div>
-        <div v-if="filteredCatalogs.length === 0" v-for="(catalog, index) in userCatIDList" :key="index" class="annifItems ">
+        <div v-if="filteredCatalogs.length === 0" v-for="(catalog, index) in userCatIDList" :key="index"
+          class="annifItems ">
           <app-link
             :to="{ name: 'CatalogueDetails', query: { locale: $route.query.locale }, params: { ctlg_id: catalog } }">{{
               catalog }}</app-link>
         </div>
-      </div>
-    </div>
+      </div> -->
+
+
+  
+
+
+    
+
+    <table>
+    <thead>
+      <tr>
+        <th>{{ $t('message.metadata.catalog') }} - ID</th>
+        <th>{{ $t('message.metadata.description') }}</th>
+        <th>{{ $t('message.dataupload.menu.actions') }}</th>
+      </tr>
+    </thead>
+
+    <tr v-for="(catalog, index) in filteredCatalogs" :key="index">
+      <td>
+
+        <app-link
+          :to="{ name: 'CatalogueDetails', query: { locale: $route.query.locale }, params: { ctlg_id: catalog.id } }">{{
+            catalog.id }}</app-link>
+
+      </td>
+      <td>
+        <span>{{ catalog.name }}</span>
+         
+      </td>
+      <td>
+        <!-- <button type="button" class="btn btn-secondary" @click="handleEdit(id, catalog)">{{
+          $t('message.metadata.linkedData') }}</button>
+        <button type="button" class="btn btn-secondary" @click="handleEdit(id, catalog)">{{
+          $t('message.dataupload.menu.edit') }}</button> -->
+
+        <button type="button" class="btn btn-action" @click="handleMQA(catalog)">Configure MQA report
+
+        </button>
+
+      </td>
+    </tr>
+
+
+   
+  </table>
+
+</div>
   </div>
 
 </template>
-<style>
+<style scoped>
+
+table {
+margin-top: 50px !important;
+margin-left: 0px !important;
+}
 .catOverview {
   min-height: 60vh;
 }
 
+.btn-action {
+  border: solid 1px #3f3f3f;
+}
+
+.btn-action:hover {
+  border: solid 1px #3f3f3f;
+  background-color: #3f3f3f;
+  color: #fff;
+}
+
 .catWrap {
   display: flex;
   flex-wrap: wrap;
@@ -81,4 +158,20 @@ onMounted(async () => {
   color: lightgray;
 
 }
+
+
+th,
+td {
+  padding: 1rem;
+
+}
+
+tr {
+  padding: 1rem;
+  border-bottom: 1px solid lightgray;
+}
+
+thead {
+  border-bottom: 1px solid lightgray;
+}
 </style>
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserProfilePage.vue b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserProfilePage.vue
index a5d8408294598aa258864ba44fe0faa6f0b0dcf7..25ed382c908deafde642cee70466916b99a3c5ac 100644
--- a/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserProfilePage.vue
+++ b/packages/piveau-hub-ui-modules/lib/data-provider-interface/views/UserProfilePage.vue
@@ -1,26 +1,50 @@
 <template>
   <div class="d-flex flex-column bg-transparent container-fluid justify-content-between content">
-    <h1 class="small-headline">My Profile</h1>
+    <h1 class="small-headline dataset-details-title">My Profile</h1>
     <div class="panel-body inf-content">
       <div class="row">
         <div class="col-md-12">
-          <strong class="table-header">User Information</strong><br>
+          <!-- <strong class="table-header">User Information</strong><br> -->
           <div class="table-responsive">
-          <table class="table table-user-information">
-            <tbody>
-              <tr>
-                <td>
-                  <strong>
-                    <span class="glyphicon glyphicon-user text-primary"></span>
-                    Name:
-                  </strong>
-                </td>
-                <td class="text-primary">
-                  {{ getUserName }}
-                </td>
-              </tr>
-            </tbody>
-          </table>
+            <table class="table table-user-information">
+              <tbody>
+                <tr>
+                  <td class="label-column">
+                    <strong>
+                      <span class="glyphicon glyphicon-user text-primary"></span>
+                      User ID:
+                    </strong>
+                  </td>
+                  <td class="text-primary value-column">
+                    {{ getUserName }}
+                  </td>
+                </tr>
+                <tr>
+                  <td class="label-column">
+                    <strong>
+                      <span class="glyphicon glyphicon-user text-primary"></span>
+                      Roles:
+                    </strong>
+                  </td>
+                  <td class="text-primary value-column">
+                    <p v-for="i in getUserData['roles'].filter(role => !role.startsWith('default-roles') && !['offline_access', 'uma_authorization'].includes(role))" :key="i">
+                      {{ i }}
+                    </p>
+                  </td>
+                </tr>
+                <tr v-if="userProfileDashboardUrl">
+                  <td class="label-column">
+                    <strong>
+                      <span class="glyphicon glyphicon-user text-primary"></span>
+                      User Profile:
+                    </strong>
+                  </td>
+                  <td class="text-primary value-column">
+                    <a :href="userProfileDashboardUrl" target="_blank" class="btn btn-link">Edit Profile</a>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
           </div>
         </div>
       </div>
@@ -30,35 +54,126 @@
 
 <script>
 import { mapGetters } from 'vuex';
+import { getCurrentInstance } from "vue";
+
+// let instance = getCurrentInstance().appContext.app.config.globalProperties.$env
+
+
 
 export default {
   name: 'DataProviderInterface-UserProfile',
-  props: [],
+  // props: [],
+  // data() {
+  //   return {
+  //     values: {},
+  //   };
+  // },
+
   data() {
     return {
-      values: {},
+      // Need to assign the URL for userProfileDashboardUrl in the config files. 
+      userProfileDashboardUrl: getCurrentInstance().appContext.app.config.globalProperties.$env.content.dataProviderInterface.userProfileDashboardUrl || '',
     };
   },
   computed: {
     ...mapGetters('auth', [
       'getUserName',
+      'getUserData'
     ]),
   },
-  methods: {},
-  created() {},
+  // methods: {},
+  // created() { },
 };
 </script>
 
 <style scoped>
-.inf-content{
-  border:1px solid #DDDDDD;
-  -webkit-border-radius:10px;
-  -moz-border-radius:10px;
-  border-radius:10px;
-  box-shadow: 7px 7px 7px rgba(0, 0, 0, 0.3);
+.inf-content {
+  /* border: 1px solid #DDDDDD;
+  -webkit-border-radius: 10px;
+  -moz-border-radius: 10px;
+  border-radius: 10px;
+  box-shadow: 7px 7px 7px rgba(0, 0, 0, 0.3); */
+  padding: 10px;
 }
 
-.table-header {
+/* .table-header {
   padding: 0.75rem;
+} */
+
+.table td {
+  padding: 15px;
+  vertical-align: middle;
+  border-bottom: 1px solid #DDDDDD; /* Ensures the horizontal lines span full width */
+}
+
+.table th {
+  text-align: left;
+}
+
+h1.small-headline {
+  margin-bottom: 20px;
+}
+
+p {
+  margin: 0; /* Ensure proper line breaks */
+}
+/* Added space at the bottom of the page */
+.content {
+  padding-bottom: 60px;
+}
+
+.table {
+  width: 100%;
+  border-collapse: collapse; /* Ensures the borders are merged properly */
 }
+
+.label-column {
+  width: 10%; /* Adjust as needed */
+  text-align: left;
+  padding-right: 10px;
+  min-width: 200px;
+}
+
+.value-column {
+  width: 100%; /* Adjust as needed */
+}
+
+.value-column .btn {
+  padding: 0;
+  /* text-decoration: none;
+  color: #5bc0de; */
+}
+
+.table tr:last-child td {
+  border-bottom: none;
+}
+
+/* .dataset-details-title {
+  font-size: 1.4rem;
+  margin-bottom: 0.5rem;
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.2;
+  color: inherit;
+} */
+
+.dataset-details-title {
+  display: flex;
+  align-items: center; /* Aligns the text and line in the center */
+  font-size: 1.4rem;
+  margin-bottom: 0.5rem;
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.2;
+  color: inherit;
+}
+
+.dataset-details-title::after {
+  content: ""; /* Creates the line after the text */
+  flex-grow: 1; /* Makes the line span the remaining width */
+  height: 1px; /* Thickness of the line */
+  background-color: #ccc; /* Line color */
+  margin-left: 10px; /* Space between the text and the line */
+}
+
 </style>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetails.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetails.vue
index 8f65d7761c0cd17fa623936a5c89036c6636af39..ea4bc5a7bcc6d2c1ec8f1f38f6780c92e2820f41 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetails.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetails.vue
@@ -3,13 +3,14 @@
     class="d-flex flex-column p-0 bg-transparent"
     :data-cy="getRepresentativeLocaleOf(getTitle, $route.query.locale, getLanguages)
     && `dataset@${getRepresentativeLocaleOf(getTitle, $route.query.locale, getLanguages)}`"
-  >
+  > 
+  <router-view name="test" ></router-view>
     <dataset-details-navigation v-if="topTitle" :dataset-id="getID"/>
     <div class="container-fluid mb-5 pt-1 content dsd-content">
       <dataset-details-header />
       <dataset-details-navigation v-if="!topTitle" :dataset-id="getID"/>
       <hr v-if="topTitle" />
-      <router-view name="datasetDetailsSubpages"></router-view>
+      <router-view name="datasetDetailsSubpages" ></router-view>
     </div>
   </div>
 </template>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetailsDataset.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetailsDataset.vue
index b4a0b5707d6e4f336b1b3dbeb154481d8dc75dc7..328f87ddc7266a354c56ff0788f0b0b328021056 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetailsDataset.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/DatasetDetailsDataset.vue
@@ -58,7 +58,6 @@
         :showPublisher="showPublisher"
         :embed="embed"
       />
-
       <dataset-details-features
         :getKeywords="getKeywords"
         :pages="pages"
@@ -70,10 +69,12 @@
         :showArray="showArray"
         :showObject="showObject"
       />
-
-      <dataset-details-properties
-        v-if="showDatasetProperties"
-      />
+      <dataset-details-properties v-if="showDatasetProperties">
+        <template #property-header><slot name="property-header"></slot></template>
+        <template #property-table-before><slot name="property-table-before"></slot></template>
+        <template #property-table><slot name="property-table"></slot></template>
+        <template #property-table-after><slot name="property-table-after"></slot></template>
+      </dataset-details-properties>
     </div>
   </div>
 </template>
@@ -207,7 +208,7 @@
       'getReleaseDate',
       'getSpatial',
       'getTranslationMetaData',
-      'getTitle',
+      'getTitle'
       ]),
       dateIncorrect() {
         return this.getDateIncorrect;
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distribution.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distribution.vue
index f59d445b6eb29ba7dd76c75d7cbd8e3311248c08..1b8f3974443bbce5ce48108aeebfcffd07715e4b 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distribution.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distribution.vue
@@ -1,60 +1,36 @@
 <template>
-  <div class="position-relative" @click="selectForPreview">
+  <div class="position-relative">
     <div class="mb-3 d-flex flex-row flex-wrap flex-md-nowrap distributions__item">
-      <distribution-format
-        :distribution="distribution"
-        :getDistributionFormat="getDistributionFormat"
-        :distributionFormatTruncated="distributionFormatTruncated"
-        :embed="embed"
-      />
-      <distribution-details
-        :getDistributionTitle="getDistributionTitle"
-        :distribution="distribution"
-        :distributions="distributions"
-        :distributionDescriptionIsExpanded="distributionDescriptionIsExpanded"
+      <distribution-format :distribution="distribution" :getDistributionFormat="getDistributionFormat"
+        :distributionFormatTruncated="distributionFormatTruncated" :embed="embed" />
+      <distribution-details :getDistributionTitle="getDistributionTitle" :distribution="distribution"
+        :distributions="distributions" :distributionDescriptionIsExpanded="distributionDescriptionIsExpanded"
         :getDistributionDescription="getDistributionDescription"
         :toggleDistributionDescription="toggleDistributionDescription"
         :distributionDescriptionIsExpandable="distributionDescriptionIsExpandable"
         :distributionVisibleContent="distributionVisibleContent"
-        :distributionExpandedContent="distributionExpandedContent"
-        :distributionIsExpanded="distributionIsExpanded"
-        :showLicensingAssistant="showLicensingAssistant"
-        :showLicence="showLicence"
-        :filterDateFormatEU="filterDateFormatEU"
-        :showArray="showArray"
-        :showNumber="showNumber"
-        :showObject="showObject"
-        :showObjectArray="showObjectArray"
-        :appendCurrentLocaleToURL="appendCurrentLocaleToURL"
-        :toggleDistribution="toggleDistribution"
-      />
-      <distribution-added
-        :date="updatedDate"
-      />
-      <distribution-actions
-        :distribution="distribution"
-        :distributions="distributions"
-        :isUrlInvalid="isUrlInvalid"
-        :getVisualisationLink="getVisualisationLink"
-        :showTooltipVisualiseButton="showTooltipVisualiseButton"
-        :previewLinkCallback="previewLinkCallback"
-        :openIfValidUrl="openIfValidUrl"
-        :showDownloadDropdown="showDownloadDropdown"
-        :getDownloadUrl="getDownloadUrl"
-        :showAccessUrls="showAccessUrls"
-        :isOnlyOneUrl="isOnlyOneUrl"
-        :trackGoto="trackGoto"
-        :getDistributionFormat="getDistributionFormat"
-        :replaceHttp="replaceHttp"
-      />
+        :distributionExpandedContent="distributionExpandedContent" :distributionIsExpanded="distributionIsExpanded"
+        :showLicensingAssistant="showLicensingAssistant" :showLicence="showLicence"
+        :filterDateFormatEU="filterDateFormatEU" :showArray="showArray" :showNumber="showNumber"
+        :showObject="showObject" :showObjectArray="showObjectArray" :appendCurrentLocaleToURL="appendCurrentLocaleToURL"
+        :toggleDistribution="toggleDistribution" />
+      <distribution-added :date="updatedDate" />
+
+      <div class="actions-container">
+        <distribution-actions @display-visualisation="selectForPreview" :distribution="distribution" :distributions="distributions" :isUrlInvalid="isUrlInvalid"
+          :getVisualisationLink="getVisualisationLink" :showTooltipVisualiseButton="showTooltipVisualiseButton"
+          :previewLinkCallback="previewLinkCallback" :openIfValidUrl="openIfValidUrl"
+          :showDownloadDropdown="showDownloadDropdown" :getDownloadUrl="getDownloadUrl" :showAccessUrls="showAccessUrls"
+          :isOnlyOneUrl="isOnlyOneUrl" :trackGoto="trackGoto" :getDistributionFormat="getDistributionFormat"
+          :replaceHttp="replaceHttp" />
+        <slot name="additional-actions"></slot>
+      </div>
+
     </div>
-    <fading-distribution-overlay
-      v-if="fading"
-      :distributions="distributions"
+    <fading-distribution-overlay v-if="fading" :distributions="distributions"
       :setDistributionsDisplayCount="setDistributionsDisplayCount"
       :increaseNumDisplayedDistributions="increaseNumDisplayedDistributions"
-      :nonOverflowingIncrementsForDistributions="nonOverflowingIncrementsForDistributions"
-    />
+      :nonOverflowingIncrementsForDistributions="nonOverflowingIncrementsForDistributions" />
   </div>
 </template>
 
@@ -131,7 +107,7 @@ export default {
   },
   computed: {
     updatedDate() {
-       if (this.has(this.distribution, 'modificationDate') && !this.isNil(this.distribution.modificationDate)) {
+      if (this.has(this.distribution, 'modificationDate') && !this.isNil(this.distribution.modificationDate)) {
         return this.filterDateFormatEU(this.distribution.modificationDate);
       } else {
         return this.filterDateFormatEU(this.distribution.releaseDate);
@@ -142,8 +118,9 @@ export default {
     has,
     isNil,
     truncate,
-    selectForPreview(){
-      this.$emit('selectForPreview', this.getDistributionTitle(this.distribution))
+    selectForPreview() {
+      const accessUrl = this.distribution.downloadUrls && this.distribution.downloadUrls.length ? this.distribution.downloadUrls[0] : this.distribution.accessUrl[0]
+      this.$emit('selectForPreview', {'title': this.getDistributionTitle(this.distribution),'url': accessUrl, 'format': this.distribution.format.id.toLowerCase()})
     }
   }
 };
@@ -151,7 +128,6 @@ export default {
 
 
 <style lang="scss" scoped>
-
 .text-break {
   word-break: break-word;
 }
@@ -164,9 +140,11 @@ td {
 
 /*** BOOTSTRAP ***/
 button:focus {
-  outline:0;
+  outline: 0;
 }
-.options, .download {
+
+.options,
+.download {
   .dropdown-menu {
     .dropdown-item {
       &:hover {
@@ -185,6 +163,4 @@ button:focus {
   //position: relative;
   border-bottom: 1px solid rgba(0, 0, 0, 0.1);
 }
-
-
 </style>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distributions.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distributions.vue
index 6be52cf823a9e00b4571648f42ff6fbe1afe1880..9dc9a7ca5884abb4814e5c57683cebaa8f183a97 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distributions.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/Distributions.vue
@@ -69,27 +69,29 @@
       </div>
       <download-as-modal />
       <!-- <distribution-visualization v-if="showDistibutionVisualisation" class="mb-4"></distribution-visualization> -->
-      <distribution-visualisation-slot v-if="showDistibutionVisualisation" class="mb-4"></distribution-visualisation-slot>
+      <distribution-visualisation-slot
+        v-if="showDistibutionVisualisation && showVisualisation"
+        ref="visualisationComponent"
+        :key="componentKey"
+        class="mb-4"
+        :title="previewedDistTitle"
+        :downloadUrl="previewedDistDownloadUrl"
+        :format="previewedDistFormat"
+      ></distribution-visualisation-slot>
     </div>
 </template>
 
 <script>
 
-// import Distribution from './Distribution.vue';
-import DownloadAllDistributions from "../../datasetDetails/distributions/DownloadAllDistributions";
 import {has, isNil} from "lodash";
 import {getTranslationFor} from "../../utils/helpers";
 import { mapGetters } from "vuex";
 import DownloadAsModal from "../../datasetDetails/distributions/DistributionDownloadAsModal";
-// import DistributionVisualisation from "./distributionPreview/DistributionVisualisation.vue";
 
 export default {
   name: 'Distributions',
   components: {
-    DownloadAllDistributions,
-    // Distribution,
-    DownloadAsModal,
-    // DistributionVisualisation,
+    DownloadAsModal
   },
   props: {
     openModal: Function,
@@ -137,9 +139,16 @@ export default {
   },
   data() {
     return {
+      componentKey: 0,
       downloadAllTop: this.$env.content.datasetDetails.bulkDownload.buttonPosition === "top",
       // previewedDistributionTitle: this.getDistributionTitle(this.displayedDistributions[0]),
-      showDistibutionVisualisation: this.$env.content.datasetDetails.distributions.showVisualisation,
+      showDistibutionVisualisation: false,
+      previewedDistributionTitle: "",
+      previewedDistDownloadUrl: "",
+      previewedDistFormat: "",
+      selectedDistribution: null,
+      showVisualisation: this.$env.content.datasetDetails.distributions.showVisualisation,
+
     };
   },
   computed: {
@@ -152,13 +161,22 @@ export default {
     getDistributionDescription(distribution) {
       return (has(distribution, 'description') && !isNil(distribution.description)) ? getTranslationFor(distribution.description, this.$route.query.locale, this.getLanguages) : '-';
     },
-    selectDistribution(distribution) {
-      this.previewedDistributionTitle = distribution;
-    }
+    selectDistribution(dist) {
+      this.previewedDistTitle = dist.title;
+      this.previewedDistDownloadUrl = dist.url;
+      this.previewedDistFormat = dist.format;
+      this.showDistibutionVisualisation = true;
+      this.componentKey += 1;  // kill and rerender with new values
+
+      // scroll to visualisation component
+      this.$nextTick(() => {
+        const visualisationComponent = this.$refs.visualisationComponent;
+        if (visualisationComponent) {
+          visualisationComponent.$el.scrollIntoView({ behavior: 'smooth' });
+        }
+      });
+    },
   },
-  // created() {
-  //   this.showDistibutionVisualisation = this.$env.content.datasetDetails.distributions.showVisualisation
-  // }
 };
 </script>
 
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DistributionsHeader.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DistributionsHeader.vue
index 1792a94e1fe2c4aef42d53080b236778322cad7f..69b48cbc979f3ae584d52486cf88f67571c774ed 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DistributionsHeader.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DistributionsHeader.vue
@@ -1,6 +1,7 @@
 <template>
   <div class="distributions-header-container w-100">
-  <div class="distributions-header-title-container dsd-item d-flex justify-content-between align-items-center">
+    <!-- Adjusting the container for correct alignment -->
+    <div class="distributions-header-title-container dsd-item d-flex flex-column align-items-start" style="position: relative; left: -15px;">
       <div class="distributions-header-title">
         <h2 :title="$t('message.tooltip.datasetDetails.distribution')"
             data-toggle="tooltip"
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DownloadAllDistributions.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DownloadAllDistributions.vue
index 1efe6346332acfcf754fd4ec67d8ba188971c25f..f25120e9d2c7dc39a86b7b1e70a35a0aff01ea8b 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DownloadAllDistributions.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/DownloadAllDistributions.vue
@@ -2,21 +2,21 @@
   <div v-if="getDistributions.length > 1 && getCatalog.is_part_of  !== 'erpd'" class="dsd-download-all-distributions-button">
     <pv-button v-if="isLoadingAllDistributionFiles" :small="small" :rounded="true" :primary="primary" :download="true"
             class="download-all-btn"
-            data-toggle="modal" data-target="#downloadAllModal"
     >
       <div class="loading-spinner"></div>
+      {{ $t('message.datasetDetails.datasets.downloadAll') }}
     </pv-button>
-    <pv-button v-else class="download-all-btn" :small="small" :rounded="true" :primary="primary" :download="true" :action="() => openModal(trackAndDownloadAllDistributions, true)">
+    <pv-button v-else class="download-all-btn" :small="small" :rounded="true" :primary="primary" :download="true" :action="openRessourceAccessPopup">
       {{ $t('message.datasetDetails.datasets.downloadAll') }}
     </pv-button>
-    <div class="modal fade" id="downloadAllModal" tabindex="-1" role="dialog" aria-labelledby="download progress" aria-hidden="true">
+    <div class="modal fade" data-backdrop="static" data-keyboard="false" id="downloadAllModal" ref="downloadAllModal" tabindex="-1" role="dialog" aria-labelledby="download progress" aria-hidden="true">
       <div class="modal-dialog" role="document">
         <div class="modal-content">
           <div class="modal-header">
             <h3 class="modal-title">{{ $t('message.datasetDetails.datasets.modal.downloadProgress') }}</h3>
-            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-              <span aria-hidden="true">&times;</span>
-            </button>
+<!--            <button type="button" class="close" data-dismiss="modal" aria-label="Close">-->
+<!--              <span aria-hidden="true">&times;</span>-->
+<!--            </button>-->
           </div>
           <div class="modal-body">
             <div class="progress">
@@ -44,11 +44,11 @@
             </div>
           </div>
           <div class="modal-footer">
-            <button type="button" class="btn btn-secondary" data-dismiss="modal">{{ $t('message.datasetDetails.datasets.modal.close') }}</button>
+<!--            <button type="button" class="btn btn-secondary" data-dismiss="modal">{{ $t('message.datasetDetails.datasets.modal.close') }}</button>-->
             <button v-if="!downloadAllSuccess && !downloadAllError" type="button" class="btn btn-danger" data-dismiss="modal" @click="cancelDownloadAll(cancelDownloadAllAxiosRequestSource)">
               {{ $t('message.datasetDetails.datasets.modal.cancel') }}
             </button>
-            <button v-else-if="downloadAllError" type="button" class="btn btn-danger" @click="trackAndDownloadAllDistributions()">{{ $t('message.datasetDetails.datasets.modal.error') }}</button>
+            <button v-if="downloadAllError" type="button" class="btn btn-danger" @click="trackAndDownloadAllDistributions()">{{ $t('message.datasetDetails.datasets.modal.error') }}</button>
             <button v-else-if="downloadAllSuccess" type="button" class="btn btn-success" data-dismiss="modal">{{ $t('message.datasetDetails.datasets.modal.okay') }}</button>
           </div>
         </div>
@@ -273,6 +273,7 @@ export default {
       return await this.downloadAllDistributions();
     },
     async downloadAllDistributions() {
+      $('#downloadAllModal').modal('show');
       this.downloadedFilesCounter = 0;
       this.downloadProgress = 0;
       this.failedDownloads = 0;
@@ -303,17 +304,39 @@ export default {
         // Chrome requires returnValue to be set
         e.returnValue = ''; // eslint-disable-line
       }
+    },
+    openRessourceAccessPopup() {
+      // const modal = this.$refs.downloadAllModal;
+      // const modal = document.getElementById('externalAccess');
+      // console.log("openRessourceAccessPopup", modal)
+      // modal.addEventListener('shown.bs.modal', function() {
+      //   console.log("CLOSING");
+      // });
+      this.openModal(this.trackAndDownloadAllDistributions, true);
+    },
+    onClose(e) {
+      console.log("CLOSING");
     }
   },
   created() {
     window.addEventListener('beforeunload', this.beforeWindowUnload);
   },
+  // mounted() {
+  //   setTimeout(() => {
+  //     const modal = document.getElementById('externalAccess');
+  //     modal.addEventListener('click', function() {
+  //       console.log("CLOSING");
+  //     });
+  //   })
+  // },
   beforeUnmount() {
     window.removeEventListener('beforeunload', this.beforeWindowUnload);
+    // const modal = this.$refs.downloadAllModal.$el;
+    // modal.removeEventListener('hide.bs.modal', this.onClose);
   },
   setup() {
     const router = useRouter();
-    
+
     onUnmounted(() => {
       router.beforeEach((to, from, next) => {
         if (this.isLoadingAllDistributionFiles && !this.isDownloadAllDistributionsCanceled) {
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionActions.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionActions.vue
index 025378304515f7c66e2837fb545923a339c68ad4..2ae9ea39a6a254cabb2127c6811b8e6020bb61e1 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionActions.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionActions.vue
@@ -1,13 +1,17 @@
 <template>
   <div class="d-flex flex-sm-row flex-md-column flex-lg-row justify-content-start
     justify-content-lg-end mt-2 text-md-right col text-left distribution-actions">
-    <distribution-preview v-if="!hidePreviewButton" :isUrlInvalid="isUrlInvalid"
+    <!-- button of new visualization tool -->
+    <distribution-visualize-button v-if="showVisualisationButton" class="distribution-action btn btn-sm visualise-btn pt-0" @displayVisualisation="$emit('displayVisualisation', getDownloadUrl)" :isUrlInvalid="isUrlInvalid"
+    :getVisualisationLink="getVisualisationLink" :distribution="distribution" :openIfValidUrl="openIfValidUrl">{{ $t('message.datasetDetails.preview') }}</distribution-visualize-button>
+    <!-- TODO: remove distribution-preview button once the new visualisation service is online -->
+    <distribution-preview v-if="!hidePreviewButton &&  getCatalog.is_part_of  !== 'erpd' && !showVisualisationButton" :isUrlInvalid="isUrlInvalid"
       :getVisualisationLink="getVisualisationLink" :distribution="distribution" :openIfValidUrl="openIfValidUrl"
       :previewLinkCallback="previewLinkCallback" class="distribution-action" />
     <distribution-download v-if="showDownloadDropdown(distribution)" :getDownloadUrl="getDownloadUrl"
       :showAccessUrls="showAccessUrls" :isOnlyOneUrl="isOnlyOneUrl" :trackGoto="trackGoto"
       :getDistributionFormat="getDistributionFormat" :replaceHttp="replaceHttp" :distribution="distribution"
-      class="distribution-action" />
+      class="distribution-action distribution-download" />
     <linked-data-buttons-dropdown :distributions="distributions" :distribution="distribution"
       class="distribution-action" />
     <div>
@@ -21,13 +25,17 @@
 
 <script>
 import AppLink from "../../../widgets/AppLink";
+import DistributionVisualizeButton from "../../../datasetDetails/distributions/distributionActions/DistributionVisualizeButton";
 import DistributionPreview from "../../../datasetDetails/distributions/distributionActions/DistributionPreview";
 import DistributionDownload from "../../../datasetDetails/distributions/distributionActions/DistributionDownload";
 import LinkedDataButtonsDropdown
   from "../../../datasetDetails/distributions/distributionActions/LinkedDataButtonsDropdown";
+import {mapGetters} from "vuex";
+import {has, isNil} from "lodash";
+
 export default {
   name: "DistributionActions",
-  components: { AppLink, LinkedDataButtonsDropdown, DistributionDownload, DistributionPreview },
+  components: { AppLink, LinkedDataButtonsDropdown, DistributionDownload, DistributionPreview, DistributionVisualizeButton },
   props: {
     distribution: Object,
     distributions: Object,
@@ -44,7 +52,22 @@ export default {
     getDistributionFormat: Function,
     replaceHttp: Function,
   },
+  data() {
+    return {
+      showVisualisationButton: this.$env.content.datasetDetails.distributions.showVisualisation,
+      visualisationLinkFormats: [
+        'csv',
+        'tsv',
+        'ods',
+        'xlsx',
+        'xls',
+      ],
+    }
+  },
   computed: {
+    ...mapGetters('datasetDetails', [
+      'getCatalog',
+    ]),
     showValidateButton() {
       return this.$env?.content?.datasetDetails?.distributions?.showValidationButton;
     },
@@ -52,6 +75,14 @@ export default {
       // only returns true if the config variable hidePreviewButton exists and is set to true
       return this.$env?.content?.datasetDetails?.distributions?.hidePreviewButton;
     }
+  },
+  methods: {
+    showVisualisationLink(distribution) {
+      if (!has(distribution, 'format.label') || isNil(distribution?.format?.label)
+        || (isNil(distribution?.downloadUrls[0]) && isNil(distribution?.accessUrl[0]))) return false;
+      const f = distribution?.format?.id?.toLowerCase();
+      return f && this.visualisationLinkFormats.includes(f);
+    }
   }
 }
 </script>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDownload.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDownload.vue
index d00877d2268325c947259409c049c1f3d7c7497b..b6ddd69acae4242d2baeeca08f4a2e3542ee130d 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDownload.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDownload.vue
@@ -1,12 +1,14 @@
 <template>
   <distribution-dropdown-download :distribution="distribution"
-    :title="$t('message.tooltip.datasetDetails.distributions.download')" :message="$t('message.datasetDetails.download')"
-    :isOnlyOneUrl="isOnlyOneUrl(distribution)" :getDownloadUrl="getDownloadUrl" @trackGoto="trackGoto" bgLight="true">
+                                  :title="$t('message.tooltip.datasetDetails.distributions.download')"
+                                  :message="$t('message.datasetDetails.download')"
+                                  :isOnlyOneUrl="isOnlyOneUrl(distribution)" :getDownloadUrl="getDownloadUrl"
+                                  @trackGoto="trackGoto" bgLight="true">
 
     <span class="dropdown-item px-3 d-flex align-items-center d-block" v-if="showAccessUrls(distribution)">
       <app-link class="text-decoration-none d-flex justify-content-between access-uri-link"
-        :to="replaceHttp(distribution.accessUrl[0])" target="_blank" rel="dcat:distribution noopener"
-        :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
+                :to="replaceHttp(distribution.accessUrl[0])" target="_blank" rel="dcat:distribution noopener"
+                :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
         <span>
           <i class="material-icons align-bottom">open_in_new</i>
           <!-- <i class=" copy-text material-icons align-bottom" @click="setClipboard(distribution.accessUrl[0])">file_copy</i> copy -->
@@ -22,11 +24,12 @@
       </span>
 
       <app-link class="text-decoration-none d-flex justify-content-between access-uri-link"
-        :to="replaceHttp(distribution.accessUrl[0])" target="_blank" rel="dcat:distribution noopener"
-        :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
+                :to="replaceHttp(distribution.accessUrl[0])" target="_blank" rel="dcat:distribution noopener"
+                :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
         <span>
           <small class="px-2" property="dcat:mediaType" :content="getDistributionFormat">{{
-            $t('message.metadata.accessUrl') }}</small>
+              $t('message.metadata.accessUrl')
+            }}</small>
         </span>
       </app-link>
       <!-- <i class="material-icons help-icon ml-3" data-toggle="tooltip" data-placement="bottom" :title="$t('message.datasetDetails.accessURLTooltip')">help_outline</i> -->
@@ -37,11 +40,12 @@
     </span>
 
     <span class="dropdown-item d-block px-3 d-flex align-items-center"
-      v-for="(downloadURL, i) in distribution.downloadUrls" :key="i">
-      <app-link class="text-decoration-none d-flex justify-content-between" :to="replaceHttp(downloadURL)" target="_blank"
-        :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
+          v-for="(downloadURL, i) in distribution.downloadUrls" :key="i">
+      <app-link class="text-decoration-none d-flex justify-content-between" :to="replaceHttp(downloadURL)"
+                target="_blank"
+                :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
         <span>
-          <i class="material-icons align-bottom">open_in_new</i>
+          <i class="open_in_new material-icons align-bottom" >open_in_new</i>
           <!-- <i class=" copy-text material-icons align-bottom" @click="setClipboard(downloadURL)">file_copy</i> -->
         </span>
         <!-- <span>
@@ -52,18 +56,23 @@
         <!-- <i class="material-icons align-bottom">open_in_new</i> -->
         <i class="copy-text material-icons align-bottom" @click="setClipboard(downloadURL)">file_copy</i>
       </span>
+       <app-link class="text-decoration-none d-flex justify-content-between" :to="replaceHttp(downloadURL)"
+                 target="_blank"
+                 :matomo-track-download="{ format: distribution?.format?.id }" @after-click="$emit('trackGoto')">
       <span>
         <small class="px-2" property="dcat:mediaType">{{ $t('message.metadata.downloadUrl') }}</small>
       </span>
+          </app-link>
       <!-- <i class="material-icons help-icon ml-3" data-toggle="tooltip" data-placement="bottom" :title="$t('message.datasetDetails.downloadURLTooltip')">help_outline</i> -->
     </span>
 
-    <distribution-download-as v-if="this.$env.content.datasetDetails.downloadAs.enable" :distribution="distribution" />
+    <distribution-download-as v-if="this.$env.content.datasetDetails.downloadAs.enable" :distribution="distribution"/>
   </distribution-dropdown-download>
 </template>
 
 <script>
-import DistributionDropdownDownload from "../../../datasetDetails/distributions/distributionActions/DistributionDropdownDownload";
+import DistributionDropdownDownload
+  from "../../../datasetDetails/distributions/distributionActions/DistributionDropdownDownload";
 import DistributionDownloadAs from "../../../datasetDetails/distributions/distributionActions/DistributionDownloadAs";
 import AppLink from "../../../widgets/AppLink";
 
@@ -119,6 +128,9 @@ export default {
 
 .dropdown-item {
   .access-uri-link,
+  .open_in_new {
+    color: #0e47cb;
+  }
   .copy-text {
     color: #0e47cb;
   }
@@ -148,4 +160,6 @@ export default {
 .copy-url-popup.hide {
   display: none;
 }
+
+
 </style>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDropdownDownload.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDropdownDownload.vue
index 2ac90d1a612750fab29f14ba8d7d2993c146e4f9..00b791e2dd71bf120af7e826b077370677dbe332 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDropdownDownload.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionDropdownDownload.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="position-relative d-inline-block ml-1 mb-1">
-    <button @click="openDropdown" class="dsd-action-button btn btn-sm btn-primary p-0 pl-2 w-100 rounded-lg btn-color dropdown-button d-flex justify-content-between"
+    <button @click="openDropdown" class="distribution-download dsd-action-button btn btn-sm btn-primary p-0 pl-2 w-100 rounded-lg btn-color dropdown-button d-flex justify-content-between"
       type="button"
       aria-haspopup="true"
       aria-expanded="false">
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionVisualizeButton.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionVisualizeButton.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4711ea9fa406be0c63105a78c43e0faa1dd3177b
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionActions/DistributionVisualizeButton.vue
@@ -0,0 +1,115 @@
+<template>
+    <div class="position-relative d-inline-block ml-1 mb-1">
+      <div v-if="showVisualisationButton && showVisualisationLink(distribution)" class="distribution-action btn btn-sm visualise-btn pt-0" @click="$emit('displayVisualisation', getDownloadUrl)">{{ $t('message.datasetDetails.preview') }}</div>
+      <a @click="$emit('track-link', getGeoLink, 'link')"
+          v-else-if="showGeoLink(distribution)"
+          :href="getGeoLink"
+          target="_blank"
+          class="d-flex justify-content-between btn btn-sm btn-primary p-0 pl-2 pr-2 w-100 rounded-lg btn-color dropdown-button">
+            {{ $t('message.datasetDetails.preview') }}
+      </a>
+      <span v-else class="d-flex justify-content-between p-0 pl-2 pr-2 w-100 rounded-lg btn-color dropdown-button text-opacity-0">{{ $t('message.datasetDetails.preview') }}</span>
+    </div>
+  </template>
+  <script>
+  import AppLink from "../../../widgets/AppLink";
+  import {has, isNil} from "lodash";
+  import {mapGetters} from "vuex";
+  
+  export default {
+    name: "DistributionVisualizeButton",
+    components: {
+      AppLink,
+    },
+    props: [
+      'showTooltipVisualiseButton',
+      'isUrlInvalid',
+      'getVisualisationLink',
+      'distribution',
+      'openIfValidUrl',
+      'previewLinkCallback'
+    ],
+    data() {
+      return {
+        showVisualisationButton: this.$env.content.datasetDetails.distributions?.showVisualisation,
+        visualisationLinkFormats: [
+          'csv',
+          'tsv',
+          'ods',
+          'xlsx',
+          'xls',
+        ],
+        geoLinkFormats: {
+          wms: 'WMS',
+          geojson: 'GeoJSON',
+          fiware_cb: 'fiware_cb',
+          'fiware-cb': 'fiware_cb',
+        },
+        geoLink: this.$env?.datasetDetails?.distributions?.geoLink,
+      };
+    },
+    computed: {
+      ...mapGetters('datasetDetails', [
+        'getCatalog',
+        'getID'
+      ]),
+      getGeoLink() {
+        const format = this.distribution.format.label;
+        let f = format.toLowerCase();
+        // Use correct Case Sensitive strings
+        f = this.geoLinkFormats[f];
+        if (this.geoLink) {
+          const geoLinkVariables = {
+            catalog: this.getCatalog.id,
+            dataset: this.getID,
+            distribution: this.distribution.id,
+            type: f,
+            lang: this.$route.query.locale,
+            accessUrl: this.distribution?.accessUrl[0],
+          }
+          // Inject variables into geo link
+          for (let linkVariable in geoLinkVariables) {
+            this.geoLink = this.geoLink.replace(`{${linkVariable}}`, geoLinkVariables[linkVariable]);
+          }
+          // Return Geo Visualisation Link
+          return this.geoLink;
+          // return `/geo-viewer/?dataset=${distributionID}&type=${f}&lang=${this.$route.query.locale}`;
+        }
+        // Return default Geo Visualisation Link if no link in user-config provided
+        return `/geo-viewer/?catalog=${this.getCatalog.id}&dataset=${this.getID}&distribution=${this.distribution.id}&type=${f}&lang=${this.$route.query.locale}`;
+      }
+    },
+    methods: {
+      showGeoLink(distribution) {
+        if (!has(distribution, 'format.label') || isNil(distribution.format.label) || !has(distribution, 'id') || isNil(distribution.id) || !has(distribution, 'accessUrl[0]')) return false;
+        const f = distribution.format.label.toLowerCase();
+        return Object.keys(this.geoLinkFormats).includes(f);
+      },
+      showVisualisationLink(distribution) {
+        if (!has(distribution, 'format.label') || isNil(distribution?.format?.label)
+          || (isNil(distribution?.downloadUrls[0]) && isNil(distribution?.accessUrl[0]))) return false;
+        const f = distribution?.format?.id?.toLowerCase();
+        return f && this.visualisationLinkFormats.includes(f);
+      }
+    }
+  }
+  </script>
+  <style scoped lang="scss">
+    .disabled {
+      cursor: not-allowed;
+      pointer-events: none;
+      text-decoration: none;
+      color: gray;
+    }
+    .text-opacity-0 {
+      opacity: 0;
+      cursor: default!important;
+    }
+
+    .visualise-btn {
+      color: #0e47cb;
+      vertical-align: text-bottom;
+      text-decoration: none;
+    }
+  </style>
+  
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionContent.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionContent.vue
index da0601b03554bc631c84a959b8eb81bd7ca76fc3..e42a9822cf070ec87e023bb730219f45e0b5a662 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionContent.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionContent.vue
@@ -1,5 +1,5 @@
 <template>
-  <table class="col-12 table table-borderless table-responsive small pl-0 mt-2 mb-1 distribution-details-table">
+  <table class="col-12 table table-borderless table-responsive small pl-0 mt-2 mb-1 distribution-details-table" style="margin-left: -10px;">
     <template v-for="item in contentList">
 
       <tr class="distribution-license-tr distribution-content-tr" v-if="item === 'license'">
@@ -263,15 +263,15 @@
         </td>
       </tr>
 
-      <tr class="distribution-spatialResolutionInMeters-tr distribution-content-tr" v-if="item === 'spatialResolutionInMeters' && has(distribution, 'spatialResolutionInMeters') && showArray(distribution.spatialResolutionInMeters)">
+      <tr class="distribution-spatialResolutionInMeters-tr distribution-content-tr" v-if="item === 'spatialResolutionInMeters' && has(distribution, 'spatialResolutionInMeters') ">
         <td class="w-25 font-weight-bold">
           <tooltip :title="$t('message.tooltip.datasetDetails.spatialResolutionInMeters')">
             {{ $t('message.metadata.spatialResolutionInMeters.label') }}
           </tooltip>
         </td>
         <td>
-          <div v-if="showNumber(distribution.spatialResolutionInMeters[0])">
-            {{ $t('message.metadata.spatialResolutionInMeters.value', {number: distribution.spatialResolutionInMeters[0]}) }}
+          <div v-if="showNumber(distribution.spatialResolutionInMeters)">
+            {{ $t('message.metadata.spatialResolutionInMeters.value', {number: distribution.spatialResolutionInMeters}) }}
           </div>
         </td>
       </tr>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionDetails.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionDetails.vue
index 1dc18e302b263651d1ffce7481bd0a69bbae026e..d3a8fc0f68e4880a72bd2afa0171c55b3af8cc60 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionDetails.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionDetails/DistributionDetails.vue
@@ -122,7 +122,8 @@ export default {
           case 'packageFormat': return accu || (has(distribution, 'packageFormat') && this.showObject(distribution.packageFormat))
           case 'hasPolicy': return accu || (has(distribution, 'hasPolicy') && !isNil(distribution.hasPolicy))
           case 'conformsTo': return accu || (has(distribution, 'conformsTo') && this.showObjectArray(distribution.conformsTo))
-          case 'spatialResolutionInMeters': return accu || (has(distribution, 'spatialResolutionInMeters') && this.showArray(distribution.spatialResolutionInMeters))
+          //case 'spatialResolutionInMeters': return accu || (has(distribution, 'spatialResolutionInMeters') && this.showArray(distribution.spatialResolutionInMeters))
+          case 'spatialResolutionInMeters': return accu || (has(distribution, 'spatialResolutionInMeters') && !isNil(distribution.spatialResolutionInMeters))
           case 'temporalResolution': return accu || (has(distribution, 'temporalResolution') && this.showArray(distribution.temporalResolution))
           default: return accu
         }
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualisationSlot.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualisationSlot.vue
index 1c080303583c67d8d9b11624006ba8823a7bf7fc..3badfaacccde0c6b9dc7894dfc72cdc28f4a1aee 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualisationSlot.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualisationSlot.vue
@@ -4,11 +4,17 @@
     Visualisation tool there 
 -->
 <template>
-    <div></div>
+    <div>
+    </div>
 </template>
 
 <script>
 export default {
     name: "DistributionVisualisationSlot",
+    props: {
+        title: String,
+        downloadUrl: String,
+        format: String,
+    }
 }
 </script>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualization.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualization.vue
deleted file mode 100644
index a8115150d99e1f086486f9a0daa257d3bfa9f268..0000000000000000000000000000000000000000
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/distributions/distributionPreview/DistributionVisualization.vue
+++ /dev/null
@@ -1,650 +0,0 @@
-<template>
-    <div class="dsd-item preview-container">
-        <h2 class=" mb-lg-4 mt-lg-4"
-            data-toggle="tooltip"
-            data-placement="top"
-            data-cy="dataset-distribution-preview"
-        >
-        <!-- TODO: translate! -->
-            Preview 
-        </h2>
-        <!-- Card -->
-        <div v-if="this.jsonData" class="dv-card card text-center">
-            <div class="dv-card-header card-header">
-                <ul class="dv-nav-tabs nav nav-tabs card-header-tabs">
-                    <li class="nav-item" role="tab" :aria-controls="'numerical-chart'"
-                    :aria-selected="activeTab === 'numerical'" aria-label="Numerical chart tab">
-                        <a class="nav-link" :class="{active: activeTab === 'numerical'}" href="#" @click.prevent="showTab('numerical')">Numerical Data</a>
-                    </li>
-                    <li class="nav-item" role="tab" :aria-controls="'categorical-chart'"
-                    :aria-selected="activeTab === 'categorical'" aria-label="Categorical chart tab">
-                        <a class="nav-link" :class="{active: activeTab === 'categorical'}" href="#" @click.prevent="showTab('categorical')">Categorical Data</a>
-                    </li>
-                    <li class="nav-item" role="tab" :aria-controls="'table-view'"
-                    :aria-selected="activeTab === 'table-view'" aria-label="Table view tab">
-                        <a class="nav-link" :class="{active: activeTab === 'table-view'}" href="#" @click.prevent="showTab('table-view')">Table View</a>
-                    </li>
-                </ul>
-            </div>
-            <div class="card-body">
-                {{ addData() }}
-                <!-- Tab for Numerical Charts -->
-                <div v-if="activeTab == 'numerical'" role="tabpanel" id="numerical-chart">
-                    <div v-if="showNumTabContent">
-                        <div> 
-                            <div class="d-flex justify-content-between">
-                                <div class="mb-2 d-flex">
-
-                                    <div class="mr-3 d-flex flex-column align-items-start">                                        
-                                        <distribution-preview-select-header title="Labels" :tooltip-text="' '" :labels="categoricalLabels" :defaultLabel="xPicked" @updatePicked="(label) => this.xPicked = label"></distribution-preview-select-header>
-                                    </div>
-                                    <div class="d-flex flex-column align-items-start">
-                                        <distribution-preview-select-header title="Values" :tooltip-text="' '" :labels="numericalLabels" :multiSelect="true" :defaultLabel="yPicked" @updatePicked="updateYPicked"></distribution-preview-select-header>
-                                    </div>
-                                    <!-- <button class="btn dv-add-btn" type="button" @click="toggleDropdown">+ add multiple values</button> -->
-
-                                </div>                            
-                                <div class="d-flex flex-column align-items-start">
-                                    <distribution-preview-select-header title="Chart type" :tooltip-text="' '" :labels="viewOptions.map(e => e.label)" :defaultLabel="viewType" @updatePicked="(label) => {this.viewType = label}"></distribution-preview-select-header>
-                                </div>
-                            </div>
-                            <div class="d-flex justify-content-start">
-                                <!-- <span>
-                                    <small>Add chart: </small>
-                                    <select v-model="yNewPicked" ref="yNewPicked" class="form-select" aria-label="select Y coerdinator">
-                                        <option disabled value="">select chart to add</option>
-                                        <option v-for="(value, index) in numericalLabels" :key="index" :value="value">{{ value }}</option>
-                                    </select>
-                                </span>
-                                <button :disabled="!yNewPicked"
-                                        :class="{disabled: !yNewPicked}"
-                                        class="btn btn-light btn-sm"
-                                        @click="addSelectedChart" 
-                                        >
-                                        add chart
-                                </button> -->
-                                <!-- <button v-if="this.datasets.length > 1"
-                                        class="btn btn-light btn-sm"
-                                        @click="removeLastChart" 
-                                        >
-                                        remove chart
-                                </button> -->
-                                <!-- <button
-                                    class="btn btn-light btn-sm"
-                                    @click="hideXLabels = !hideXLabels" 
-                                    >
-                                    {{  hideXLabels ? 'show labels' : 'hide labels' }}
-                                </button> --> 
-                            </div>
-                        </div>
-                        <!-- <bar-chart v-if="viewType.toLowerCase() === 'bar'" :chartData="this.datacollection" :chartOptions="this.options"></bar-chart>
-                        <line-chart v-else-if="viewType.toLowerCase() === 'line'" :chartData="this.datacollection" :chartOptions="this.options" @remove-chart="removeChart"></line-chart>
-                        <pie-chart v-else-if="viewType.toLowerCase() === 'pie'" :chartData="this.datacollection" :chartOptions="this.options"></pie-chart>
-                        <doughnut-chart v-else-if="viewType.toLowerCase() === 'doughnut'" :chartData="this.datacollection" :chartOptions="this.options"></doughnut-chart> -->
-                    </div>
-                    <div v-else class="m-5">No numerical data to show.</div>
-                </div>
-                <!-- Tab for Categorical Charts -->
-                <div v-else-if="activeTab == 'categorical'" role="tabpanel" id="categorical-chart">
-                    <div v-if="showCatTabContent">
-                        <div > 
-                            <div class="d-flex justify-content-between mb-2">
-                                <distribution-preview-select-header title="Labels" :tooltip-text="' '" :labels="categoricalLabels" :defaultLabel="catYPicked" @updatePicked="(label) => this.catYPicked = label"></distribution-preview-select-header>
-                                <distribution-preview-select-header title="Chart type" :tooltip-text="' '" :labels="catViewOptions.map(e => e.label)" :defaultLabel="catViewType" @updatePicked="(label) => {this.catViewType = label}"></distribution-preview-select-header>
-                            </div>
-
-                            <!-- <span>Chart type: </span>
-                            <select v-model="catViewType" class="form-select" aria-label="Default select example">
-                                <option v-for="viewOption in catViewOptions" :value="viewOption.value" :key="viewOption.value">{{ viewOption.label }} </option>
-                            </select>
-                            <br>
-                            <small>Labels: </small>
-                            <select v-model="catYPicked" class="" aria-label="select a view option">
-                                <option v-for="(value, index) in categoricalLabels" :key="index" :value="value">{{ value }}</option>
-                            </select> -->
-                            
-                        </div>
-                        <!-- <bar-chart v-if="catViewType.toLowerCase() === 'bar'" :chartData="this.catDatacollection" :chartOptions="this.options"></bar-chart>
-                        <line-chart v-else-if="catViewType.toLowerCase() === 'line'" :chartData="this.catDatacollection" :chartOptions="this.options" @remove-chart="removeChart"></line-chart>
-                        <pie-chart v-else-if="catViewType.toLowerCase() === 'pie'" :chartData="this.catDatacollection" :chartOptions="this.options"></pie-chart>
-                        <doughnut-chart v-else-if="catViewType.toLowerCase() === 'doughnut'" :chartData="this.catDatacollection" :chartOptions="this.options"></doughnut-chart> -->
-                    </div>
-                    <div v-else>
-                        No categorical data to show.
-                    </div>
-                </div>
-                <!-- Tab for Table View -->
-                <div v-show="activeTab == 'table-view'" role="tabpanel" id="table-view">
-                    <!-- <div class="table-wrapper">
-                        <v-table 
-                                class="dist-table"
-                                :data="dataRows"
-                                :currentPage.sync="currentPage"
-                                :pageSize="11"
-                                @totalPagesChanged="totalPages = $event">
-                            <thead slot="head">
-                                <v-th v-for="(label, index) in allLabels" :key="index" :sortKey="label">{{ label }}</v-th>
-                            </thead>
-                            <tbody slot="body" slot-scope="{displayData}">
-                                <tr v-for="row in displayData" :key="row.id">
-                                <td v-for="(rowValue, index) in Object.values(row)" :key="row.id + '-' + index" > {{ rowValue }} </td>
-                                </tr>
-                            </tbody>
-                        </v-table>
-                    </div>
-                    <smart-pagination
-                        :currentPage.sync="currentPage"
-                        :totalPages="totalPages"
-                        :maxPageLinks="10"
-                        :boundaryLinks="true"
-                    /> -->
-                </div>  
-            </div>
-        </div>
-        
-        <!-- Feedback Tool -->
-        <br> 
-        <div class="d-flex justify-content-between align-items-center">
-            <small class="text-muted">
-                Don't like the default view? suggest a better one <span @click="showFeedbackTool = !showFeedbackTool" class="text-primary pointer" type="button">here</span> 
-            </small>
-            
-            <!-- Records range bar -->
-            <div class="dv-records-range-container text-center">
-                <small class="dv-records-range-container-record-number mr-1">{{ this.dataRows.length }} Records</small>
-                <small v-if="activeTab === 'numerical'">
-                    <label for="from">show records from</label>
-                    <input @change="updateRange" type="number" id="from" v-model.number="fromIndex" min="1">
-                    <label for="to">-</label>
-                    <input @change="updateRange" type="number" id="to" v-model.number="toIndex" :min="fromIndex" :max="this.dataRows.length">
-                </small>
-            </div>
-        </div>
-
-        <div v-if="showFeedbackTool" class="feedback-tool-wrapper">
-            <form v-if="showFeedbackForm" action="" class="feedback-tool-form" @submit.prevent>
-                <span>Suggest a Chart type and/or Labels and Values to be set as default: </span>
-
-                <div class="d-flex dv-fb-options py-3">
-                    <distribution-preview-select-header title="Chart type" :labels="allChartOptions"  :updatePicked="() => {console.log('todo')}"></distribution-preview-select-header>
-                    <distribution-preview-select-header title="Labels" :labels="allLabels" :updatePicked="() => {console.log('todo')}"></distribution-preview-select-header>
-                    <distribution-preview-select-header title="Values" :labels="allLabels" :updatePicked="() => {console.log('todo')}"></distribution-preview-select-header>
-                </div>
-                <!-- <br><br>
-                <label for="view-type">View type:</label>
-                <select id="view-type" class="form-select" v-model="suggestedViewType" aria-label="select a view option" required>
-                    <option disabled value="">Please select type</option>
-                    <option value="num-view">Numerical View</option>
-                    <option value="cat-view">Categorical View</option>
-                    <option value="tabular-view">Tabular View</option>
-                </select>
-                <br>
-                <div v-if="suggestedViewType == 'num-view'">
-                    <label for="x-label">Label for X-axis:</label>
-                    <select id="x-label" v-model="suggestedX" aria-label="select X coerdinator">
-                        <option disabled value="">select default X-axis</option>
-                        <option v-for="(value, index) in allLabels" :key="index" :value="value">{{ value }}</option>
-                    </select>
-                    <br>
-                    <label for="y-label">Label for Y-axis:</label>
-                    <select id="y-label" v-model="suggestedY" aria-label="select Y coerdinator">
-                        <option disabled value="">select default Y-axis</option>
-                        <option v-for="(value, index) in allLabels" :key="index" :value="value">{{ value }}</option>
-                    </select>
-                </div>
-                <div v-else-if="suggestedViewType == 'cat-view'">
-                    <label for="cat-label">Label for Categorical View:</label>
-                    <select id="cat-label" v-model="suggestedX" aria-label="select X coerdinator">
-                        <option disabled value="">select default categorical label</option>
-                        <option v-for="(value, index) in categoricalLabels" :key="index" :value="value">{{ value }}</option>
-                    </select>
-                </div> -->
-                <br>
-                <input @click="showFeedbackTool = false" class="btn btn-outline-dark mr-2 mb-1" type="button" value="Cancel">
-                <input @click="submitFeedbackInput" class="btn btn-primary mb-1" type="button" value="Submit">
-            </form>
-            <div v-else class="text-center m-5">
-                Thank you for your feedback!
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-
-    // import BarChart from "../../../charts/BarChart";
-    // import LineChart from '../../../charts/LineChart.vue';
-    // import DoughnutChart from '../../../charts/DoughnutChart.vue';
-    // import PieChart from '../../../charts/PieChart.vue';
-    import DistributionPreviewSelectHeader from './DistributionPreviewSelectHeader.vue';
-
-    export default {
-        name: "DistributionVisualisation",
-        components: {
-            // BarChart,
-            // LineChart,
-            // DoughnutChart,
-            // PieChart,
-            DistributionPreviewSelectHeader,
-        },
-        data() {
-            return {
-                // print: false,
-                jsonData: null,
-                activeTab: '',
-                xLabel: null,
-                allLabels: [],
-                categoricalLabels: [],
-                numericalLabels: [],
-                xList: [],
-                yList: [],
-                fromIndex: 1,
-                toIndex: null,
-                viewOptions: [
-                    { value: "Bar", label:"Bar" },
-                    { value: "Line", label:"Line" },
-                ],
-                showNumTabContent: true,
-                chartValues: [],
-                chartLabels: [],
-                viewType: '',
-                xPicked: '',
-                yPicked: '',
-                yNewPicked: '',
-                yNewValues: [],
-                xLabels: [],
-                yValues: [],
-                datacollection: {},
-                datasets: [],  // dataRows, label, backgroundColor
-                dataRows: [],  // only the data arrays
-                hideXLabels: false,
-
-                catViewOptions: [
-                    { value: "Bar", label:"Bar" },
-                    // { value: "Pie", label:"Pie" },
-                    // { value: "Line", label:"Line" },
-                    { value: "Doughnut", label:"Doughnut" }
-                ], 
-                showCatTabContent: true,
-                nCatToShow: 100, // 
-                catChartValues: [],
-                catYValues: [],
-                catViewType: '',
-                catYPicked: '', // only Y, because X will be automatically generated from the categories of Y
-                catDatacollection: {},
-                catDatasets: [],  // dataRows, label, backgroundColor
-
-                categorizedData: [],
-                skipFactor: 1,
-                currentPage: 1,
-                totalPages: 0,
-                showFeedbackTool: false,
-                showFeedbackForm: true,
-                showAlert: false,
-                options: {
-                    responsive: true,
-                    maintainAspectRatio: true,
-                    scales: {
-                        yAxes: {
-                            beginAtZero: false
-                        },
-                        x: {
-                            ticks: {
-                                maxTicksLimit: 20,
-                            }
-                        }
-                    },
-                    plugins: {
-                        legend: {
-                            onClick: (e, legendItem) => {
-                                // this.removeChart(legendItem.text)
-                            },
-                            display: true,
-                            labels: {
-                                borderRadius: 10,
-                                useBorderRadius: true,
-                                pointStyle: 'circle',
-                                usePointStyle: true,
-                                padding: 20,
-                            }
-                        }
-                    }
-                },
-                // Feedback tool
-                allChartOptions: ['Line', 'Bar', 'Pie', 'Doughnut'],
-                suggestedViewType: '',
-                suggestedX: '',
-                suggestedY: '',
-            }
-        },
-        // props: {
-        //     distributionTitle: String
-        // },
-        mounted() {
-        // Einlesen
-        fetch("/test_json_6.json")
-        .then(response => {
-                const reader = response.body.getReader();
-                return new ReadableStream({
-                    start(controller) {
-                        function push() {
-                            reader.read().then(({ done, value }) => {
-                                if (done) {
-                                    controller.close();
-                                    return;
-                                }
-                                controller.enqueue(value);
-                                push();
-                            });
-                        }
-                        push();
-                    }
-                });
-            })
-            .then(stream => new Response(stream))
-            .then(res => res.json())
-            .then(data => (this.jsonData = data))
-            .catch(err => console.log(err.message));
-        },
-        methods: {
-            showTab(tabName) {
-                this.activeTab = tabName;
-            },
-            // Once the JSON record is fetched, this method is called to fill all the data() fields with the necessary data
-            addData() {
-                this.activeTab = this.activeTab ? this.activeTab : this.jsonData.default_view_options.default_view;
-                this.allLabels = this.jsonData.labels.all_labels;
-                this.numericalLabels = this.jsonData.labels.numerical_labels;
-                if (this.numericalLabels.length == 0) this.showNumTabContent = false;
-                this.categoricalLabels = this.jsonData.labels.categorical_labels;
-                if (this.categoricalLabels.length == 0) {
-                    this.showCatTabContent = false;
-                    // this.showXLabels = false;
-                }
-                this.xList = this.jsonData.labels.categorical_labels;
-                this.yList = this.jsonData.labels.numerical_labels;
-                // this.xPicked = this.xPicked ? this.xPicked : ( localStorage.xPicked ? localStorage.xPicked : this.jsonData.default_axes.x );
-                // this.yPicked = this.yPicked ? this.yPicked : ( localStorage.yPicked ? localStorage.yPicked : this.jsonData.default_axes.y );
-                // this.viewType = this.viewType ? this.viewType : ( localStorage.viewType ? localStorage.viewType : this.jsonData.default_chart_type );
-                this.viewType = this.viewType ? this.viewType : this.jsonData.default_view_options.default_numerical_view;
-                this.xPicked = this.xPicked ? this.xPicked : this.jsonData.default_view_options.default_axes.numerical_chart.x;
-                this.yPicked = this.yPicked ? this.yPicked : this.jsonData.default_view_options.default_axes.numerical_chart.y;
-
-                this.catViewType = this.catViewType ? this.catViewType : this.jsonData.default_view_options.default_categorical_view;
-                this.catYPicked = this.catYPicked ? this.catYPicked : this.jsonData.default_view_options.default_axes.categorical_chart;
-                this.dataRows = this.jsonData.data; // this line can take time
-                if (!this.toIndex) this.toIndex = this.dataRows.length < 100 ? this.dataRows.length : 100;
-                this.categorizedData = this.jsonData.categorized;
-                this.skipFactor = this.calculateSkipFactor(this.dataRows.length, this.desiredPoints);
-            },
-            fillNumPlotData() {
-                // In case there are no assigned lables, create empty lables (chart.js needs an array of lables, otherwise empty chart will display)
-                if (this.xLabels.length === 0 || this.hideXLabels) {
-                    let emptyValues = Array(this.datasets[0].data.length).fill('');
-                
-                    this.datacollection = {
-                        labels: emptyValues,
-                        datasets: structuredClone(this.datasets),
-                };
-                }
-
-                else {
-                    this.datacollection = {
-                            labels: this.xLabels,
-                            datasets: structuredClone(this.datasets),
-                    };
-                }
-
-            },
-            fillCatPlotData() {
-                this.catChartValues = Object.keys(this.categorizedData.find(e => e.column === this.catYPicked).categories).slice(0, this.nCatToShow) // get array of all category names of yPicked
-                this.catYValues = Object.values(this.categorizedData.find(e => e.column === this.catYPicked).categories).slice(0, this.nCatToShow) // get array of all category counts of yPicked
-                this.catDatasets[0] =
-                    {
-                        label: this.catYPicked,
-                        data: this.catYValues,
-                        backgroundColor: this.catYValues.map(() => this.randomColor()), 
-                    },
-                this.catDatacollection = {
-                        labels: this.catChartValues,
-                        datasets: structuredClone(this.catDatasets).slice(0, this.nCatToShow),
-                };
-            },
-            updateRange() {
-                // console.log('firing updateRange()')
-                this.datasets[0].data = this.yValues.slice(this.fromIndex-1, this.toIndex);
-                // for (const dataset of this.datasets) {
-                //     dataset.data = this.yValues.slice(this.fromIndex-1, this.toIndex);
-                // }
-                this.xLabels = this.chartLabels.slice(this.fromIndex-1, this.toIndex);
-                // console.log(this.chartLabels)
-                this.fillNumPlotData();
-            },
-            updateYPicked(label){
-                // this.yPicked = label
-                console.log(this.datasets.map(e => e.label))
-                if (this.datasets.map(e => e.label).includes(label)) {
-                    console.log('label exists already')
-                    this.removeChart(label)
-                }
-                else {
-                    console.log('label doesnt exist')
-                    this.yNewPicked = label
-                    this.addSelectedChart()
-                }
-            },
-            // TODO: fix bug: changing range after adding a new chart doesn't update data (.slice() will not be rendered)
-            addSelectedChart() {
-                // this.chartValues = this.dataRows.map(e => e[this.yNewPicked])
-                this.chartValues = this.dataRows.map(e => e[this.yNewPicked])
-                this.yNewValues = this.chartValues;
-                const randomColor = this.randomColor();
-                this.datasets.push(
-                    {
-                        label: this.yNewPicked,
-                        data: this.yNewValues.slice(this.fromIndex-1, this.toIndex),
-                        backgroundColor: randomColor, 
-                        borderColor: randomColor,
-                        borderWidth: 1,
-                    },
-                )
-                this.fillNumPlotData();
-            },
-            removeChart(label){
-                console.log(label)
-                this.datasets = this.datasets.filter(o => o.label !== label)
-                console.log('datasets after', this.datasets)
-                this.fillNumPlotData();
-            },
-            randomColor() {
-            const letters = '0123456789ABCDEF';
-            let color = '#';
-            for (let i = 0; i < 6; i++) {
-                color += letters[Math.floor(Math.random() * 16)];
-            }
-            return color;
-            },
-            submitFeedbackInput() {
-                // TODO implement feedback-tool logic
-                // if(this.suggestedViewType) localStorage.viewType = this.suggestedViewType;
-                // if(this.suggestedX) localStorage.xPicked = this.suggestedX;
-                // if(this.suggestedY) localStorage.yPicked = this.suggestedY;
-                localStorage.viewType = '';
-                localStorage.xPicked = '';
-                localStorage.yPicked = '';
-                console.log('Selected View Type: ', this.suggestedViewType);
-                this.showFeedbackForm = false;
-
-                // TODO: only if successful
-                // this.showAlert = true;
-            },
-            calculateSkipFactor(totalPoints) {
-                const desiredPoints = 50;
-                if (totalPoints <= desiredPoints) {
-                    return 1; // No downsampling needed
-                }
-
-                const skipFactor = Math.ceil(totalPoints / desiredPoints);
-                return skipFactor;
-            },
-            // downsampleData(data, skipFactor) {
-            //     return data.filter((point, index) => index % skipFactor === 0);
-            // },
-            // testLogger(smth) {
-            //     console.log("something: ", smth)
-            // }
-        },
-        watch: {
-            chartData() {
-            this.$data._chart.update();
-            },
-            xPicked() {
-                this.$emit("input", this.xPicked);
-                this.chartLabels = this.dataRows.map(e => e[this.xPicked]).slice(this.fromIndex-1, this.toIndex)
-                this.xLabels = this.chartLabels;
-                this.fillNumPlotData();
-            },
-            yPicked() {
-                this.$emit("input", this.yPicked);
-                this.chartValues = this.dataRows.map(e => e[this.yPicked]).slice(this.fromIndex-1, this.toIndex)
-                this.yValues = this.chartValues;
-                const randomColor = this.randomColor();
-                this.datasets[0] =
-                    {
-                        label: this.yPicked,
-                        data: this.yValues,
-                        backgroundColor: randomColor, 
-                        borderColor: randomColor,
-                        borderWidth: 1,
-                    },
-                
-                this.fillNumPlotData();
-            },
-            hideXLabels() {
-                this.fillNumPlotData();
-            },
-            catViewType() {
-                if (this.catViewType === 'Pie') this.nCatToShow = 20;
-                else if (this.catViewType === 'Bar') this.nCatToShow = 50;
-                else if (this.catViewType === 'Line') this.nCatToShow = 100;
-                // this.$emit("input", this.catYPicked);
-                this.fillCatPlotData();
-            },
-            catYPicked() {
-                this.$emit("input", this.catYPicked);
-                this.fillCatPlotData();
-            },
-        }
-    }
-
-</script>
-
-<style lang="scss" scoped>
-
-    .preview-container {
-        /* padding: 3px; */
-        /* border-bottom: 1px solid gray;
-        border-top: 1px solid gray; */
-        max-width: 100%;
-        overflow: auto;
-    }
-
-    .preview-container .card-header {
-        background-color: transparent;
-    }
-
-    .preview-container .card {
-        border: none;
-    }
-
-    .dv-nav-tabs li .nav-link{
-        color: inherit;
-        &.active {
-            // background-color: oldlace;
-            font-weight: bold;
-            color: var(--primary-light);
-            border-top: 4px solid var(--primary-light);
-        }
-        &:hover:not(.active) {
-            border-color: transparent;
-        }
-    }
-
-    .dv-add-btn {
-        height: 48px;
-        align-self: end;
-        background-color: var(--primary-light);
-        color: white;
-
-        &:hover {
-            color: white;
-        }
-    }
-
-    .dv-records-range-container input {
-        text-align: center;
-        width: 50px;
-    }
-
-    .dv-records-range-container-record-number {
-        background-color: #f0efed;
-        border-radius: 5px;
-        padding: 10px 15px;
-        font-weight: 650;
-    }
-
-    .dv-records-range-container small label {
-        padding: 0 5px;
-    }
-
-    select {
-        margin: 5px 2px;
-        width: 200px
-    }
-
-    .table-wrapper {
-        overflow-x: auto;
-    }
-
-    .dist-table {
-        margin: 15px 0;
-        /* margin-right: 15px; */
-    }
-
-    td, th {
-        border: 1px solid #dfe2e5;
-        padding: 0.6em 1em;
-    }
-
-    tr:nth-child(2n) {
-        background-color: #f6f8fa;
-    }
-
-    .vt-sort:before{
-        font-family: FontAwesome;
-        padding-right: 0.5em;
-        width: 1.28571429em;
-        display: inline-block;
-        text-align: center;
-    }
-
-    .vt-sortable:before{
-        content: "\f0dc";
-    }
-
-    .vt-asc:before{
-        content: "\f160";
-    }
-
-    .vt-desc:before{
-        content: "\f161";
-    }
-
-    .feedback-tool-wrapper {
-        padding: 5px 15px;
-        margin: 15px 0;
-        background-color: #f6f8fa;
-        border: 1px solid #f6f8fa;
-        border-radius: 5px;
-    }
-</style>
\ No newline at end of file
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/features/DatasetDetailsSubject.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/features/DatasetDetailsSubject.vue
index 70ae3fd8c2cd91bada730b391035a574b98415c8..0df1073896c54fba26fcfb8ed297e8098176c61b 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/features/DatasetDetailsSubject.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/features/DatasetDetailsSubject.vue
@@ -1,172 +1,153 @@
 <template>
-  <div class="row mt-4 flex-column dsd-item dsd-keywords">
-    <span v-if="showTitle" class="mb-4 h-4 font-weight-bold">Subjects ({{ displayedSubjects.length }})</span>
-    <div class="keywords__item row">
-
-    
+  <div class="mt-2 flex-column dsd-feature">
+    <div>
+      <dataset-details-feature-header
+        :title="`EuroVoc Descriptors (${
+          getSubject ? getSubject.length.toLocaleString('fi') : 0
+        })`"
+        :arrowDown="!expanded"
+        tag="keywords-toggle"
+        :onClick="toggleExpanded"
+        class="ml-0"
+      />
+    </div>
+    <div v-if="expanded" class="keywords__item row mt-4">
       <span
-        v-for='(subject, i) in displayedSubjects'
+        v-for="(subject, i) in displayedSubjects"
         :key="i"
         class="col-6 col-sm-3 col-md-2 mt-md-0 mt-3 mb-2 mx-0 px-1"
       >
-
-     
-      
-      <app-link :to="getSubjectLink(subject)">
-        <small v-if="typeof subject.title === 'object'" class="d-inline-block w-100 py-2 rounded-pill text-center text-white subject">
-          <span v-for="(value, key) in subject.title" :key="key">
-            
-            <tooltip :title="value"  data-placement="top">
-              {{ truncate(value, maxSubjectLength, false) }}
-            </tooltip>
-        
-          </span>
-        </small>
-      
-        <small v-else-if="typeof subject.title === 'string'" class="d-inline-block w-100 py-2 rounded-pill text-center text-white subject">
-          <span>
-            <tooltip :title="subject.title"  data-placement="top">
-              {{ truncate(subject.title, maxSubjectLength, false) }}
-            </tooltip>
-          </span>
-        </small>
-      </app-link>
+        <app-link :to="getSubjectLink(subject)">
+          <small
+            v-if="typeof subject.title === 'object'"
+            class="d-inline-block w-100 py-2 rounded-pill text-center text-white subject"
+          >
+            <span v-for="(value, key) in subject.title" :key="key">
+              <tooltip :title="value" data-placement="top">
+                {{ truncate(value, maxSubjectLength, false) }}
+              </tooltip>
+            </span>
+          </small>
+          <small
+            v-else-if="typeof subject.title === 'string'"
+            class="d-inline-block w-100 py-2 rounded-pill text-center text-white subject"
+          >
+            <span>
+              <tooltip :title="subject.title" data-placement="top">
+                {{ truncate(subject.title, maxSubjectLength, false) }}
+              </tooltip>
+            </span>
+          </small>
+        </app-link>
       </span>
     </div>
-    <div>
+    <div v-if="expanded && displayedSubjects.length > defaultDisplayCount">
       <pv-show-more
-        v-if="displayedSubjects.length > defaultDisplayCount"
-        :label="isSubjectAllDisplayed? $t('message.metadata.showLess') : $t('message.metadata.showMore')"
+        :label="isSubjectAllDisplayed ? $t('message.metadata.showLess') : $t('message.metadata.showMore')"
         :upArrow="isSubjectAllDisplayed"
         :action="toggleDisplayCount"
         class="row text-primary"
       />
     </div>
-<!--    <div>-->
-<!--      <div-->
-<!--        v-if="!subject.displayAll && !isSubjectAllDisplayed"-->
-<!--        class="keywords__item"-->
-<!--      >-->
-<!--        <div-->
-<!--          class="keywords__actions pb-md-3"-->
-<!--        >-->
-<!--          <button-->
-<!--            v-for="increment in subject.incrementSteps.filter(nonOverflowingIncrementsForSubject)"-->
-<!--            :key="increment"-->
-<!--            class="btn btn-sm btn-secondary mr-1"-->
-<!--            @click="increaseNumDisplayedSubject(increment)"-->
-<!--          >-->
-<!--            <i class="fas fa-chevron-down"/> {{ $t('message.metadata.showXMore', { increment }) }}-->
-<!--          </button>-->
-<!--          <button-->
-<!--            class="btn btn-sm btn-primary"-->
-<!--            @click="subject.displayCount = getSubject.length"-->
-<!--          >-->
-<!--            <i class="fas fa-eye"/> {{ $t('message.metadata.showAll') }} {{ getSubject.length.toLocaleString('fi') }}-->
-<!--          </button>-->
-<!--        </div>-->
-<!--      </div>-->
-<!--    </div>-->
   </div>
 </template>
 
 <script>
-import {truncate} from "../../utils/helpers";
-import {has} from "lodash";
-import {mapGetters} from "vuex";
+import { truncate } from "../../utils/helpers";
+import { has } from "lodash";
+import { mapGetters } from "vuex";
 import Tooltip from "../../widgets/Tooltip";
 import AppLink from "../../widgets/AppLink";
-import {sortAlphabetically} from "./utils/sortAlphabetically";
+import { sortAlphabetically } from "./utils/sortAlphabetically";
+import $ from "jquery";
 
 export default {
   name: "DatasetDetailsSubject",
-  components: {Tooltip, AppLink},
+  components: { Tooltip, AppLink },
   data() {
     return {
       showTitle: this.$env.content.datasetDetails.keywords.showTitle,
       maxSubjectLength: this.$env.content.datasets.maxKeywordLength,
       defaultDisplayCount: 24,
       followSubjectLinks: this.$env.content.datasets.followSubjectLinks,
+      expanded: false, // Toggle state
       subject: {
         displayAll: false,
-        displayCount: 24, // Should never exceed number of subjects
+        displayCount: 24,
         incrementSteps: [12, 60],
-      }
+      },
     };
   },
   computed: {
-    ...mapGetters('datasetDetails', [
-      'getSubject'
-    ]),
+    ...mapGetters("datasetDetails", ["getSubject"]),
     displayedSubjects() {
       const subjects = this.subject.displayAll
         ? Object.freeze(this.sortedSubject)
         : Object.freeze(this.sortedSubject.slice(0, this.subject.displayCount));
-      return subjects.filter(subject => subject.title);
+      return subjects.filter((subject) => subject.title);
     },
     isSubjectAllDisplayed() {
       return this.subject.displayCount >= this.displayedSubjects.length;
     },
     sortedSubject() {
-      let selected = [], fallback = [], other = {}, without = []; // eslint-disable-line
+      let selected = [];
       const selectedLanguage = this.$route.query.locale;
 
-      // Sort by language
       this.getSubject.forEach((element) => {
-        const e = element;
-        if (has(element, 'title') && element.title !== null) {
-          if (typeof element.title === 'object') {
+        if (has(element, "title") && element.title !== null) {
+          if (typeof element.title === "object") {
             Object.keys(element.title).forEach((key) => {
               if (key !== selectedLanguage) {
-                delete e.title[key];
+                delete element.title[key];
               }
             });
           }
           selected.push(element);
         }
       });
-      this.sortAlphabetically(selected, 'title', selectedLanguage);
+      this.sortAlphabetically(selected, "title", selectedLanguage);
       return selected;
-    }
+    },
   },
   methods: {
     truncate,
     sortAlphabetically,
-    increaseNumDisplayedSubject(increment) {
-      this.subject.displayCount = this.clamp(this.subject.displayCount
-        + increment, 0, this.getSubject.length);
-    },
-    nonOverflowingIncrementsForSubject(incrementStep) {
-      return this.subject.displayCount + incrementStep <= this.getSubject.length;
+    toggleDisplayCount() {
+      $('body').tooltip({ selector: '[data-toggle="tooltip"]' });
+      if (this.subject.displayCount < this.getSubject.length) {
+        this.subject.displayCount = this.getSubject.length;
+      } else {
+        this.subject.displayCount = this.defaultDisplayCount;
+      }
+      this.subject.displayAll = !this.subject.displayAll;
     },
-    clamp(n, min, max) {
-      return Math.min(Math.max(n, min), max);
+    toggleExpanded() {
+      this.expanded = !this.expanded; // Toggle visibility
     },
     getSubjectLink(subject) {
-      const urlResource = subject.id
-    
-      
-        return {
+      const urlResource = subject.id;
+      return {
         path: `/datasets`,
-        query: Object.assign({}, { locale: this.$route.query.locale, subject:urlResource }),
+        query: {
+          locale: this.$route.query.locale,
+          subject: urlResource,
+        },
       };
-      
-      
-      
     },
-    toggleDisplayCount() {
-      if (this.keywords.displayCount < this.displayedSubjects.length) {
-        this.keywords.displayCount = this.displayedSubjects.length;
-      } else {
-        this.keywords.displayCount = this.defaultDisplayCount;
-      }
-    }
-  }
-}
+  },
+};
 </script>
 
 <style scoped lang="scss">
 .subject {
   background-color: #196fd2;
 }
+
+.keywords-header {
+  justify-content: flex-start; /* Aligned header to the left */
+}
+
+.keywords-header .keywords-toggle {
+  margin-left: 0; /* The toggle header is on the left */
+}
 </style>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/header/DatasetDetailsHeaderTitle.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/header/DatasetDetailsHeaderTitle.vue
index 5cf085ebd6f9c515290c817cd16ea68fcda3dc35..006ac736ee805dda03f0cca0e4bc835bcf80ba54 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/header/DatasetDetailsHeaderTitle.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/header/DatasetDetailsHeaderTitle.vue
@@ -9,7 +9,7 @@
       </span>
     </div>
     <h1 v-if="getTitle && !embed" class="d-none d-lg-block dataset-details-title" data-cy="dataset-title">{{ getTranslationFor(getTitle, $route.query.locale, getLanguages) }}</h1>
-    <h1 v-if="getTitle && embed" class="d-lg-block dataset-details-title" data-cy="dataset-title">{{ getTranslationFor(getTitle, $route.query.locale, getLanguages) }} </h1>
+    <h1 v-else-if="getTitle && embed" class="d-lg-block dataset-details-title" data-cy="dataset-title">{{ getTranslationFor(getTitle, $route.query.locale, getLanguages) }} </h1>
     <h1 v-else class="d-none d-lg-block dataset-details-title" data-cy="dataset-title">{{ getID }}</h1>
   </div>
 </template>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/navigation/DatasetDetailsNavigationLinks.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/navigation/DatasetDetailsNavigationLinks.vue
index 67508ca64c80b19a5700de33350a07f0bea38329..347f5aa1e7b36f5f720059a9e6d9da9e64e11747 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/navigation/DatasetDetailsNavigationLinks.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/navigation/DatasetDetailsNavigationLinks.vue
@@ -16,52 +16,35 @@
           <dataset-details-share-button class="dropdown-item" :to="`https://www.linkedin.com/shareArticle?mini=true&url=${url}`" :icon="{ prefix: 'fab', iconName: 'linkedin-in' }"></dataset-details-share-button>
         </div>
       </div>
-      <div class="d-inline dsd-link-feed">
-        <app-link class="nav-item nav-link text-nowrap"
-                  :to="getFeedLink()"
-                  target="_blank"
-                  matomo-track-page-view
-                  role="button">
-          <span :title="$t('message.tooltip.datasetDetails.datasetFeed')" data-toggle="tooltip"  data-placement="top"> {{ $t('message.datasetDetails.datasetFeed') }}
+
+      <!-- API link with True/False-->
+      <div v-if="this.$env.content.datasetDetails.embed.enable" class="d-inline dropdown dsd-link-cite">
+        <button
+         @click="openApiCall()"
+          class="nav-item nav-link text-nowrap api-button"
+          :class="{
+            'disabled': getLoading,
+          }"
+          fragment="#"
+          role="button"
+          id="citationDropdown"
+          data-toggle="dropdown"
+          aria-haspopup="true"
+          aria-expanded="false"
+          data-cy="citation-dropdown-expand">
+        
+          <span class="api-link" title="Open API request of this Dataset." data-toggle="tooltip" data-placement="top"> 
+            API 
+            <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16">
+            <path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/>
+            <path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/>
+          </svg>
           </span>
-        </app-link>
-      </div>
-      <div class="d-inline dropdown dsd-link-linked-data">
-        <app-link class="nav-item nav-link dropdown-toggle text-nowrap" fragment="#" role="button" id="linkedDataDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-          <!--<i class="material-icons small-icon align-bottom text-dark">***FIND A LINKED DATA ICON***</i>-->
-          <span :title="$t('message.tooltip.datasetDetails.linkedData')"
-                data-toggle="tooltip"
-                data-placement="top">
-                    {{ $t('message.metadata.linkedData') }}
-              </span>
-        </app-link>
-        <div class="dropdown-menu" aria-labelledby="linkedDataDropdownMenuLink">
-          <resource-details-linked-data-button class="dropdown-item" format="rdf" text="RDF/XML" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
-          <resource-details-linked-data-button class="dropdown-item" format="ttl" text="Turtle" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
-          <resource-details-linked-data-button class="dropdown-item" format="n3" text="Notation3" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
-          <resource-details-linked-data-button class="dropdown-item" format="nt" text="N-Triples" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
-          <resource-details-linked-data-button class="dropdown-item" format="jsonld" text="JSON-LD" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
-        </div>
-      </div>
-      <div class="d-inline dropdown dsd-link-dqv" v-if="showDQV">
-        <app-link class="nav-item nav-link dropdown-toggle text-nowrap" 
-          :class="{'disabled': !(getIsDQVDataRDFAvailable || getIsDQVDataTTLAvailable || getIsDQVDataN3Available || getIsDQVDataNTAvailable || getIsDQVDataJSONLDAvailable)}"
-          fragment="#" role="button" id="metaDataDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-          <!--<i class="material-icons small-icon align-bottom text-dark">***FIND A LINKED DATA ICON***</i>-->
-          <span :title="$t('message.tooltip.datasetDetails.dqvData')"
-                data-toggle="tooltip"
-                data-placement="top">
-                     DQV Data
-              </span>
-        </app-link>
-        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="metaDataDropdownMenuLink">
-          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataRDFAvailable}" format="rdf" text="RDF/XML" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
-          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataTTLAvailable}" format="ttl" text="Turtle" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
-          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataN3Available}" format="n3" text="Notation3" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
-          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataNTAvailable}" format="nt" text="N-Triples" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
-          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataJSONLDAvailable}" format="jsonld" text="JSON-LD" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
-        </div>
+        </button>
+       
       </div>
+
+       <!-- Cite link -->
       <div class="d-inline dropdown dsd-link-cite">
         <app-link
           class="nav-item nav-link dropdown-toggle text-nowrap"
@@ -96,9 +79,30 @@
           </button>
         </div>
       </div>
+
+       <!-- Linked Data link-->
+      <div class="d-inline dropdown dsd-link-linked-data">
+        <app-link class="nav-item nav-link dropdown-toggle text-nowrap" fragment="#" role="button" id="linkedDataDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+          <!--<i class="material-icons small-icon align-bottom text-dark">***FIND A LINKED DATA ICON***</i>-->
+          <span :title="$t('message.tooltip.datasetDetails.linkedData')"
+                data-toggle="tooltip"
+                data-placement="top">
+                    {{ $t('message.metadata.linkedData') }}
+              </span>
+        </app-link>
+        <div class="dropdown-menu" aria-labelledby="linkedDataDropdownMenuLink">
+          <resource-details-linked-data-button class="dropdown-item" format="rdf" text="RDF/XML" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
+          <resource-details-linked-data-button class="dropdown-item" format="ttl" text="Turtle" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
+          <resource-details-linked-data-button class="dropdown-item" format="n3" text="Notation3" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
+          <resource-details-linked-data-button class="dropdown-item" format="nt" text="N-Triples" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
+          <resource-details-linked-data-button class="dropdown-item" format="jsonld" text="JSON-LD" resources="datasets" v-bind:resources-id="datasetId"></resource-details-linked-data-button>
+        </div>
+      </div>
+
+       <!-- Embed link with True/False-->
       <div v-if="this.$env.content.datasetDetails.embed.enable" class="d-inline dropdown dsd-link-cite">
         <button type="button" data-toggle="modal" data-target="#embedModal" class="nav-item nav-link text-nowrap bg-none border-0" fragment="#" role="button" id="" style="background:none;">
-          <span title="Embed"
+          <span title="Copy link to embed the dataset in other pages"
                 data-toggle="tooltip"
                 data-placement="top"
                 >
@@ -106,6 +110,39 @@
               </span>
         </button>
       </div>
+
+      <!-- DQV link with True/False-->
+      <div class="d-inline dropdown dsd-link-dqv" v-if="showDQV">
+        <app-link class="nav-item nav-link dropdown-toggle text-nowrap" 
+          :class="{'disabled': !(getIsDQVDataRDFAvailable || getIsDQVDataTTLAvailable || getIsDQVDataN3Available || getIsDQVDataNTAvailable || getIsDQVDataJSONLDAvailable)}"
+          fragment="#" role="button" id="metaDataDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+          <!--<i class="material-icons small-icon align-bottom text-dark">***FIND A LINKED DATA ICON***</i>-->
+          <span :title="$t('message.tooltip.datasetDetails.dqvData')"
+                data-toggle="tooltip"
+                data-placement="top">
+                     DQV Data
+              </span>
+        </app-link>
+        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="metaDataDropdownMenuLink">
+          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataRDFAvailable}" format="rdf" text="RDF/XML" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
+          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataTTLAvailable}" format="ttl" text="Turtle" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
+          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataN3Available}" format="n3" text="Notation3" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
+          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataNTAvailable}" format="nt" text="N-Triples" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
+          <dataset-details-linked-metrics-button class="dropdown-item" :class="{'disabled': !getIsDQVDataJSONLDAvailable}" format="jsonld" text="JSON-LD" v-bind:dataset-id="datasetId"></dataset-details-linked-metrics-button>
+        </div>
+      </div>
+     
+      <!-- Dataset Feed link -->
+      <div class="d-inline dsd-link-feed">
+        <app-link class="nav-item nav-link text-nowrap"
+                  :to="getFeedLink()"
+                  target="_blank"
+                  matomo-track-page-view
+                  role="button">
+          <span :title="$t('message.tooltip.datasetDetails.datasetFeed')" data-toggle="tooltip"  data-placement="top"> {{ $t('message.datasetDetails.datasetFeed') }}
+          </span>
+        </app-link>
+      </div>
       <hr />
     </ul>
     <dataset-citation-modal
@@ -191,6 +228,9 @@ export default {
     modal() {
       $('#citationModal').modal({ show: true });
     },
+    openApiCall() {
+      window.open(this.baseUrl + "datasets/" + this.getID, "_blank");
+    }
   },
   mounted() {},
   setup() {
@@ -209,4 +249,19 @@ export default {
 .nav-link {
   text-decoration: underline;
 }
+
+.api-link svg {
+  margin-bottom: 4px;
+}
+
+.api-button {
+  all: unset;           
+  cursor: pointer;  
+  padding: 0px;
+  margin-top: 8px;
+}
+
+.menu .nav-link:focus {
+  border: none !important;
+}
 </style>
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperties.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperties.vue
index 994ef3614e2ebf2cfa8a5a6a7a556852f2a0fc4f..6deeee4ef995650036b0b63c4505eccb8502ee29 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperties.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperties.vue
@@ -1,28 +1,34 @@
 <template>
   <div class="mt-5 dsd-properties">
     <div class="col-12 mb-2 p-0 dsd-properties-list">
-      <dataset-details-feature-header
-        :title="$t('message.datasetDetails.additionalInfo')"
-        :arrowDown="!infoVisible"
-        tag="additional-information-toggle"
-        :onClick="toggleInfo"
-      />
+      <slot name="property-header">
+        <dataset-details-feature-header
+          :title="$t('message.datasetDetails.additionalInfo')"
+          :arrowDown="!infoVisible"
+          tag="additional-information-toggle"
+          :onClick="toggleInfo"
+        />
+      </slot>
       <div class="position-relative dsd-item additional-information"
            data-cy="additional-information"
            v-show="infoVisible">
-        <table class="table table-borderless table-responsive" ref="dsdProperties" role="tablist" id="myTab">
-            <dataset-details-property v-for='(name, index) in fieldsArray'
-              :name="name"
-              :translate="fieldSchema[name]?.translate"
-              :type="fieldSchema[name]?.type"
-              :propertyFields="fieldSchema[name]?.fields"
-              :track="fieldSchema[name]?.track"
-              :itemstyles="fieldSchema[name]?.itemstyles"
-              :preTransform="fieldSchema[name]?.preTransform"
-              :transform="fieldSchema[name]?.transform"
-              :key="index"/>
-        </table>
+        <slot name="property-table-before"></slot>
+        <slot name="property-table">
+          <table class="table table-borderless table-responsive" ref="dsdProperties" role="tablist" id="myTab">
+              <dataset-details-property v-for='(name, index) in fieldsArray'
+                :name="name"
+                :translate="fieldSchema[name]?.translate"
+                :type="fieldSchema[name]?.type"
+                :propertyFields="fieldSchema[name]?.fields"
+                :track="fieldSchema[name]?.track"
+                :itemstyles="fieldSchema[name]?.itemstyles"
+                :preTransform="fieldSchema[name]?.preTransform"
+                :transform="fieldSchema[name]?.transform"
+                :key="index"/>
+          </table>
+        </slot>
         <div class="additional-information-overlay" ref="overlay" v-show="showMoreVisible && !expanded"></div>
+        <slot name="property-table-after"></slot>
       </div>
     </div>
     <pv-show-more
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperty.vue b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperty.vue
index 26cff6a90fb9a3f791593769832020b7855ffc29..19f632134f9d08e8e080c34cf85a0b2d3a1d6c4d 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperty.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/DatasetDetailsProperty.vue
@@ -5,7 +5,7 @@
         {{ labelDisplay[1] }}
       </tooltip>
     </td>
-    <td v-if="['string', 'date', 'first:number', 'translation'].includes(type)">{{ value }}</td>
+    <td v-if="['string', 'date', 'number', 'first:number', 'translation'].includes(type)">{{ value }}</td>
     <td v-if="type==='uri'"><a :href='value'>{{ value }}</a></td>
     <td v-if="type==='links'">
       <div v-for="(v, i) of value" :key="i">
diff --git a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/specification.ts b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/specification.ts
index 06d572bf4f76793fcf8a511b787d42b7684320cd..9a3634db5d2cbad8a16638c0e4262cf0fbebe97a 100644
--- a/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/specification.ts
+++ b/packages/piveau-hub-ui-modules/lib/datasetDetails/properties/specification.ts
@@ -66,7 +66,7 @@ export const dcatSchema = (t) => ({
     sources: {type: 'links', translate:',sources'},
     languages: {type: 'links', translate: 'language,languages'},
     publisher: {type: 'object', fields: 'name,email,homepage'},
-    contactPoints: {type: 'objects', translate:"/message.tooltip.contactPoints,contactPoints", fields: "name::/message.datasetDetails.contactPoints.organizationName,email,telephone,address,url::'URL'"},
+    contactPoints: {type: 'objects', translate:"/message.tooltip.contactPoints,contactPoints", fields: "name::/message.metadata.name,organisation_name::/message.datasetDetails.contactPoints.organizationName, email,telephone,address,url:link"},
     catalogRecord: {type: 'object', translate:"/message.tooltip.catalogRecord,catalogRecord", fields: "issued:date:addedToDataEuropaEU,modified:date:updatedOnDataEuropaEU,homepage"},
     spatial: {type: 'objects', fields: "coordinates,type"},
     spatialResource: {type: 'objects', translate:",spatialResource", fields: "resource:link"},
@@ -75,7 +75,7 @@ export const dcatSchema = (t) => ({
     // relatedResources: {type: 'links', translate: 'relatedResource,relatedResources'},
     identifiers: {type: 'links', translate: 'identifier,identifiers'},
     otherIdentifiers: {type: 'objects', translate: 'otherIdentifier,otherIdentifiers', fields:"identifier:link,resource:link:identifier,scheme:link"},
-    resource: {type: 'uri', translate: ",'uriRef'"},
+    resource: {type: 'uri', translate: ",'uriRef:'"},
     frequency: {type: 'object', fields:"title,resource:link"},
     accessRights: {type: 'object', translate:"/message.tooltip.datasetDetails.distributions.rights,accessRights", fields:"label::"},
     accrualPeriodicity: {type: 'object', translate:"frequency,accrualPeriodicity", fields:"label::"},
@@ -96,8 +96,8 @@ export const dcatSchema = (t) => ({
     qualifiedRelations: {type: 'objects', translate: "qualifiedRelation", fields: "relation:link,had_role:link:role"},
     sample: {type: 'links'},
     spatialResolutionInMeters: {
-        type: 'first:number', translate: "spatialResolutionInMeters,spatialResolutionInMeters.label",
-            transform: value => t('message.metadata.spatialResolutionInMeters.value', {number: value[0]})
+        type: 'number', translate: "spatialResolutionInMeters,spatialResolutionInMeters.label",
+            transform: value => t('message.metadata.spatialResolutionInMeters.value', {number: value})
     },
     type: {type: 'object', fields: "label,resource:link"},
     temporalResolution: {type: 'string'}
diff --git a/packages/piveau-hub-ui-modules/lib/datasets/Datasets.vue b/packages/piveau-hub-ui-modules/lib/datasets/Datasets.vue
index 2ab32a7709391d18c0cb92bbbf2819f40631d362..80e86e3f40e7e2c782412a63220bec7ebe012423 100644
--- a/packages/piveau-hub-ui-modules/lib/datasets/Datasets.vue
+++ b/packages/piveau-hub-ui-modules/lib/datasets/Datasets.vue
@@ -27,7 +27,6 @@
             <button class="btn btn-primary mb-3 text-right text-white" data-toggle="collapse"
                     data-target="#datasetFacets" data-cy="btn-filter-toggle"
                     @click="filterCollapsed = !filterCollapsed">
-              {{ $t('message.datasetFacets.title') }}
               <i class="material-icons small-icon align-bottom" v-if="filterCollapsed">arrow_drop_up</i>
               <i class="material-icons small-icon align-bottom" v-else>arrow_drop_down</i>
             </button>
@@ -38,6 +37,12 @@
             :dataScope="dataScope"
             :available-facets="getAllAvailableFacets"
           ></datasets-facets>
+<!--          <facets-->
+<!--              :facetsConfig="getAllAvailableFacets"-->
+<!--              :facetsIds="$env.content.datasets.facets.defaultFacetOrder"-->
+<!--              class="col-md-3 col-12 mb-3 mb-md-0 px-0 collapse"-->
+<!--              id="datasetFacets">-->
+<!--          </facets>-->
           <section class="col-md-9 col-12">
             <slot name="datasets-filters">
               <datasets-filters/>
@@ -117,7 +122,6 @@
   } from 'lodash-es';
   import $ from 'jquery';
   import fileTypes from '../utils/fileTypes';
-  import DatasetsFacets from './datasetsFacets/DatasetsFacets.vue';
   import Pagination from '../widgets/Pagination.vue';
   import SelectedFacetsOverview from '../facets/SelectedFacetsOverview';
   import AppLink from '../widgets/AppLink.vue';
@@ -126,7 +130,8 @@
   import DatasetsFilters from "../datasets/DatasetsFilters.vue";
   import DatasetList from './DatasetList.vue'
   import { useDatasetsHead } from '../composables/head'
-
+  // import Facets from "../facets_2.0/Facets.vue"
+  import DatasetsFacets from './datasetsFacets/DatasetsFacets.vue';
 export default {
   name: 'Datasets',
   components: {
@@ -137,6 +142,7 @@ export default {
     datasetsFacets: DatasetsFacets,
     pagination: Pagination,
     DatasetList,
+    // Facets
   },
   props: {
     infiniteScrolling: {
@@ -223,7 +229,6 @@ export default {
         return facetObjWithMaybeDefaultSuperCatalog;
     },
 
-
     getAllAvailableFacets() {
       return this.showCatalogDetails
         ? this.getAllAvailableFacetsOriginal.filter(facet => facet.id !== 'catalog')
diff --git a/packages/piveau-hub-ui-modules/lib/embed/DatasetEmbedModal.vue b/packages/piveau-hub-ui-modules/lib/embed/DatasetEmbedModal.vue
index 827759fbc823a65b0b667ffd99bb71cab4aded8f..e2772ca1e50ddbd17d349e87f62257d11d6e9375 100644
--- a/packages/piveau-hub-ui-modules/lib/embed/DatasetEmbedModal.vue
+++ b/packages/piveau-hub-ui-modules/lib/embed/DatasetEmbedModal.vue
@@ -19,7 +19,8 @@
                      <div class="input-wrapper">
                         <label for="iframeWidth">{{ $t('message.datasetDetails.datasets.modal.width') }}</label><br>
                         <div class="input-with-px">
-                           <input
+                           <input v-if="!isResponsive"
+                         
                               type="number"
                               id="iframeWidth"
                               v-model="iframeWidth"
@@ -27,6 +28,16 @@
                               :min="minRange"
                               :max="maxRange"
                               />
+
+                              <input   v-if="isResponsive"
+                              class="disable-width"
+                              type="text"
+                              id="iframeWidth"
+                              v-model="iframeWidth"
+                              @input="updateEmbedCode"
+                              :min="minRange"
+                              :max="maxRange"
+                              />
                         </div>
                      </div>
                      <div class="input-wrapper height" style="padding-left: 3.3rem">
@@ -44,10 +55,18 @@
                      </div>
                   </div>
                </div>
+             
+               <div class="form-check mb-4">
+               <input class="form-check-input" type="checkbox" v-model="isResponsive" @change="updateEmbedCode">
+               <label class="form-check-label" for="responsive">
+                  Responsive
+               </label>
+            </div>
+
                <div class="ecl-form-group">
                   <label class="ecl-form-label" for="ebmedTextarea" style="font-size:18px; font-weight: 400; color: #000000;">{{ $t('message.datasetDetails.datasets.modal.code')}}</label>
                   <textarea id="ebmedTextarea" style="width: 100%; resize: none; padding: 20px 25px 0px 20px; overflow: hidden; font-size:18px; line-height: 1.1; color:#888888; margin-top: 1.375rem; word-break: break-all;float: left!important;"
-                     class="ecl-text-area ecl-text-area--m" rows="4" :value="embedCode" readonly></textarea>
+                     class="ecl-text-area ecl-text-area--m" rows="4" :value="embedCode"  @click="selectAll" ></textarea>
                </div>
             </div>
 
@@ -62,10 +81,11 @@
                <label class="form-check-label" for="exampleRadios2">
                   Snippet Dataset
                </label>
-            </div>
-            <div class="modal-footer justify-content-start">
+            </div>  
+            <div class="modal-footer justify-content-start"> 
                <button @click="copy" class="ecl-button ecl-button--secondary px-4 py-3" style="float: left!important;" type="button">{{ $t('message.datasetDetails.datasets.modal.copy')}}</button>
                <span v-show="copied" class="copied">
+                  <label class="form-check-label">
                   <svg width="20" height="23" viewBox="0 0 20 23" fill="none" xmlns="http://www.w3.org/2000/svg">
                      <g clip-path="url(#clip0_13_474)">
                         <path d="M14.2857 20.125V21.9219C14.2857 22.5173 13.806 23 13.2143 23H1.07143C0.479688 23 0 22.5173 0 21.9219V5.39062C0 4.79519 0.479688 4.3125 1.07143 4.3125H4.28571V17.6094C4.28571 18.9965 5.40719 20.125 6.78571 20.125H14.2857ZM14.2857 4.67188V0H6.78571C6.19397 0 5.71429 0.482686 5.71429 1.07812V17.6094C5.71429 18.2048 6.19397 18.6875 6.78571 18.6875H18.9286C19.5203 18.6875 20 18.2048 20 17.6094V5.75H15.3571C14.7679 5.75 14.2857 5.26484 14.2857 4.67188ZM19.6862 3.27799L16.7424 0.315756C16.5414 0.113582 16.2689 1.49498e-06 15.9848 0L15.7143 0V4.3125H20V4.04032C20 3.75439 19.8871 3.48018 19.6862 3.27799Z" fill="#464646"/>
@@ -76,7 +96,10 @@
                         </clipPath>
                      </defs>
                   </svg>
-                  {{ $t('message.datasetDetails.datasets.modal.copied') }}
+                 
+                     {{ $t('message.datasetDetails.datasets.modal.copied') }}
+               </label>
+                
                </span>
             </div>
          </div>
@@ -96,13 +119,22 @@ export default {
       minRange: this.$env.content.datasetDetails.embed.minRange,
       maxRange: this.$env.content.datasetDetails.embed.maxRange,
       embedType: 'embed', // default to 'embed'
+      isResponsive: false
     };
   },
   methods: {
+   selectAll(event) {
+      event.target.select()
+    },
     updateEmbedCode() {
       // Ensure the input values are within the specified range
+      if(this.isResponsive){
+      this.iframeWidth = '100%';
+      } else {
+      this.iframeWidth = 900;
       this.iframeWidth = Math.min(Math.max(this.iframeWidth, this.minRange), this.maxRange);
       this.iframeHeight = Math.min(Math.max(this.iframeHeight, this.minRange), this.maxRange);
+      }
 
       // Generate the embed code
       const currentURL = window.location.href.replace(/\?.*$/, '') + '/' + this.embedType;
@@ -144,6 +176,13 @@ export default {
   // line-height: 24px;
   color: #000000;
 }
+
+.disable-width {
+   background: #d8d8d8;
+   border-radius: 10px;
+   border: 1px solid #cecece !important;
+   width: 140px;
+}
 .modal-head {
   border-bottom: none;
   padding: 0;
@@ -161,6 +200,7 @@ export default {
    padding: 2.438rem 0 0 0;
    font-size: 16px;
 }
+
 .close {
   font-size: 14px;
   color: #1C3D66;
@@ -183,7 +223,7 @@ export default {
   color: #000000!important;
 }
 .iframeSettings {
-    padding: 1.875rem 0 2.438rem 0;
+    padding: 1.875rem 0 1.438rem 0;
     font-size: 18px;
 
     input {
@@ -197,13 +237,13 @@ export default {
 }
 
 .input-with-px input {
-  padding: 15px 50px 15px 50px;
-  border: 1px solid #A5A5A5;
+  padding: 15px 30px 15px 50px;
+  border: 1px solid #cbcbcb;
 }
 
 /* Style the "px" text */
 .input-with-px::after {
-  content: "px";
+//  content: "px";
   position: absolute;
   right: 30%;
   top: 54%;
diff --git a/packages/piveau-hub-ui-modules/lib/embed/EmbedDataset.vue b/packages/piveau-hub-ui-modules/lib/embed/EmbedDataset.vue
index 8cc5965360af6fd003ef1c293bc1ca42920e831d..41a4808924fb5b3cc333c1f2ad8316f4130c35c0 100644
--- a/packages/piveau-hub-ui-modules/lib/embed/EmbedDataset.vue
+++ b/packages/piveau-hub-ui-modules/lib/embed/EmbedDataset.vue
@@ -12,10 +12,11 @@
            <p class="px-5 py-3 m-0">data.europa.eu  - The official portal for European data</p>
        </div>
        <div class="p-5">
-            <dataset-details-header-title 
+        <button @click="openUrl" class="btn-title"> 
+          <dataset-details-header-title 
               titleFontSize="0.75rem"
               :embed="true"
-            />
+            /> </button>
             <div  class="mb-5">
                 <dataset-details-header-catalogue 
                     :disableLink="true"
@@ -69,8 +70,16 @@ export default {
   background-color: white; /* Semi-transparent background */
   display: flex;
   color: black;
-  z-index: 99; /* Ensure it's above other content */
+  z-index: 999999; /* Ensure it's above other content */
 }
+
+.btn-title {
+  border: none;
+  background: none;
+  text-align: left;
+  width: 100%;
+}
+
 .logo {
     width: 290px;
     height: 70px;
diff --git a/packages/piveau-hub-ui-modules/lib/embed/EmbedDatasetSnippet.vue b/packages/piveau-hub-ui-modules/lib/embed/EmbedDatasetSnippet.vue
index 4ac2bbed8c7352cfbc8a713ab67c85f1136a98ef..48ed177978db0f5826a5dec125e2811993cdc804 100644
--- a/packages/piveau-hub-ui-modules/lib/embed/EmbedDatasetSnippet.vue
+++ b/packages/piveau-hub-ui-modules/lib/embed/EmbedDatasetSnippet.vue
@@ -4,7 +4,7 @@
       :embed-snippet="true" class="d-none" />
 
     <div class="p-5 content-snipp">
-      <dataset-details-header-title :embed="true" class="mr-2" />
+     <button @click="openUrl" class="btn-title"> <dataset-details-header-title :embed="true" class="mr-2" /></button>
 
       <dataset-details-description class="snip-desc"></dataset-details-description>
 
@@ -64,13 +64,14 @@ export default {
 </script>
 
 <style scoped>
+
 .embed-dataset-snipp {
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
-  background-color: white;
+  background-color: #fff;
   /* Semi-transparent background */
   display: flex;
   color: black;
@@ -80,6 +81,13 @@ export default {
   /* This hides the scrollbar */
   overflow-y: scroll;
   /* This allows vertical scrolling but hides the scrollbar */
+  z-index: 99999;
+}
+.btn-title {
+  border: none;
+  background: none;
+  text-align: left;
+  width: 100%;
 }
 
 .embed-dataset-snipp::-webkit-scrollbar {
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/Facets.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/Facets.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3b77a8b5984196bba100fc074644108a4dc188e9
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/Facets.vue
@@ -0,0 +1,36 @@
+<template>
+  <div style="width:25%">
+    <h1>{{ nonZeroConfig.length }}</h1>
+    <div v-for="item in nonZeroConfig" class="mb-3">
+      <component
+          :is="getFacet(item.id)"
+          :config="item"
+          @facet-clicked="facetClicked"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { getFacet } from "./getFacet"
+  import {FacetsConfig} from "./types";
+  import {useFacets} from "./useFacets";
+  import {computed, toRef} from "vue";
+  import {useRoute, useRouter} from "vue-router";
+  import {toggleQueryParam} from "./toggleQueryParam";
+
+  const props = defineProps<{
+    facetsConfig: FacetsConfig
+    facetsIds: [String]
+  }>();
+
+  const route = useRoute();
+  const router = useRouter();
+  const facetsConfig = toRef(props, 'facetsConfig');
+  const config = useFacets(facetsConfig, props.facetsIds, route);
+  const nonZeroConfig = computed(() =>
+      config.value.filter(element => element.items.length));
+  const facetClicked = (facetId, item) => {
+    toggleQueryParam(facetId, item.id, router, route);
+  }
+</script>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/CatalogFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/CatalogFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..99bd3362792291f87f72150f6013d9e321b1465e
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/CatalogFacet.vue
@@ -0,0 +1,17 @@
+<template>
+  <div>
+    <h2>HI I AM SPECIAL!!!!</h2>
+  </div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+  h2 {
+    border-radius: .75rem;
+    background-color: cornflowerblue;
+    padding: 0.75rem;
+  }
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/DataServicesFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/DataServicesFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2215a6b53cf773adde9993cd42bd9d2fe03b12aa
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/DataServicesFacet.vue
@@ -0,0 +1,52 @@
+<template>
+  <RadioFacet
+      :config="config"
+      :property="property"
+      :optionIds="['true', 'false']"
+      :optionLabels="[yes, no]"
+      :change="changeDataServices"
+      :initialOption="getDataServices"
+  />
+</template>
+
+<script>
+import {mapActions, mapGetters} from "vuex";
+import RadioFacet from "./RadioFacet.vue";
+
+export default {
+  name: "DataServicesFacet",
+  props: {
+    config: Object
+  },
+  components: {
+    RadioFacet
+  },
+  data() {
+    return {
+      yes: this.i18n.global.t('message.metadata.yes'),
+      no: this.i18n.global.t('message.metadata.no'),
+      property: this.i18n.global.t('message.datasetFacets.facets.dataServices.dataServicesOnly'),
+      title: this.i18n.global.t('message.metadata.dataServices'),
+      toolTipTitle: this.i18n.global.t('message.helpIcon.dataServices')
+    };
+  },
+  computed: {
+    ...mapGetters('datasets', ['getDataServices'])
+  },
+  methods: {
+    ...mapActions('datasets', ['setDataServices']),
+    changeDataServices(dataServices) {
+      this.setDataServices(dataServices);
+      const query = Object.assign({}, this.$route.query, { dataServices, page: 1 });
+      if (dataServices === 'false') {
+        delete query.dataServices;
+      }
+      this.$router.replace({ query });
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/ExpandableSelectFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/ExpandableSelectFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f7e86082ef81db67a0c521db7bda83d12f054bd1
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/ExpandableSelectFacet.vue
@@ -0,0 +1,183 @@
+<template>
+  <!-- Component for a collapsible facet -->
+  <div class="list-group col pr-0" role="group" :aria-labelledby="myTitleId" >
+    <template v-if="header">
+      <facet-title
+        :title="header"
+        :tooltip="toolTipTitle"
+        :title-id="myTitleId"
+      />
+      <a
+        class="facet-title-mobile d-flex d-md-none list-group-item justify-content-between align-items-baseline"
+        data-toggle="collapse"
+        :data-target="`#${myListId}`"
+        @click="isExpanded = !isExpanded"
+      >
+        <h2 class="h5 mb-0">{{ header }}</h2>
+        <button class="btn">
+          <i class="material-icons small-icon expand-more animated" v-if="!isExpanded">expand_more</i>
+          <i class="material-icons small-icon expand-less animated" v-else>expand_less</i>
+        </button>
+      </a>
+    </template>
+
+    <div
+      :id="myListId"
+      class="collapse dont-collapse-sm">
+      <template v-if="items && items.length > 0">
+        <div
+          class="list-item-container"
+          v-for="(item, index) in items.slice(0, numItemsAllowed)"
+          :key="`field@${index}`"
+        >
+          <select-facets-item
+            class="d-flex facet list-group-item list-group-item-action justify-content-between align-items-center"
+            :title="getFacetTranslation(fieldId, item.id, $route.query.locale, item.title)"
+            :count="getFacetCount(item)"
+            :hide-count="fieldId === 'dataScope'"
+            :class="{active: facetIsSelected(fieldId, item)}"
+            @click.native="$emit('facet-clicked', fieldId, item)"
+          />
+        </div>
+        <button
+          v-if="items.length > minItems"
+          class="d-block btn btn-primary btn-color w-100 facet-expand-button"
+          @click="handleGrowToggle"
+        >
+          <i class="material-icons align-bottom expand-more animated">{{ isGrown ? 'expand_less' : 'expand_more' }}</i>
+        </button>
+      </template>
+    </div>
+  </div>
+</template>
+
+<script>
+import { defineComponent } from 'vue';
+import SelectFacetsItem from "./SelectFacetsItem.vue";
+import FacetTitle from "./FacetTitle.vue";
+import { getFacetTranslation } from '../../utils/helpers';
+
+export default defineComponent({
+  name: 'ExpandableSelectFacet',
+  inheritAttrs: false,
+  components: {FacetTitle, SelectFacetsItem},
+  props: {
+    config: {
+      type: Object
+      // type: {title: String, id: String, items: [], query: Object}
+    },
+    multiSelect: {
+      type: Boolean,
+      default: true
+    },
+    // facetIsSelected: {
+    //   type: Function,
+    //   default: (fieldId, item) => {
+    //     // console.log("facetIsSelected", fieldId, item);
+    //     const queryParams = this.$route.query[fieldId];
+    //     return queryParams === item || queryParams.includes(item)
+    //   }
+    // },
+    // facetClicked: {
+    //   type: Function,
+    //   default: (fieldId, item) => {
+    //     console.log("facetClicked", fieldId, item);
+    //   }
+    // }
+  },
+  emits: ['facet-clicked'],
+  data() {
+    return {
+      isExpanded: false,
+      isGrown: false,
+      numItemsAllowed: this.$env.content.datasets.facets.MIN_FACET_LIMIT || 5,
+      minItems: this.$env.content.datasets.facets.MIN_FACET_LIMIT || 5,
+      maxItems: this.$env.content.datasets.facets.MAX_FACET_LIMIT || 50,
+      header: this.i18n.global.t(`message.datasetFacets.facets.${this.config.id.toLowerCase()}`),
+      fieldId: this.config.id,
+      toolTipTitle: this.i18n.global.t(`message.helpIcon.${this.config.id.toLowerCase()}`),
+    };
+  },
+  computed: {
+    items() { // sorting by count
+      return this.config.items.slice().sort((a, b) => {
+        const n = b.count - a.count;
+        if (n !== 0) return b.count - a.count;
+        if (a.name < b.name) return -1;
+        return 1;
+      });
+    },
+    myId() {
+      // Use Vue generated uid to set give each facet a unique id
+      return `facet-${this.fieldId}`;
+    },
+    myListId() {
+      // Use Vue generated uid to set give each facet a unique id
+      return `facet-list-${this.fieldId}`;
+    },
+    myTitleId() {
+      // Use Vue generated uid to set give each facet a unique id
+      return `facet-title-${this.fieldId}`;
+    },
+  },
+  methods: {
+    getFacetTranslation,
+    handleGrowToggle() {
+      this.isGrown = !this.isGrown;
+      this.numItemsAllowed = this.isGrown
+        ? this.maxItems
+        : this.minItems;
+    },
+    getFacetCount(facet) {
+      if (this.fieldId === 'scoring') return '';
+      return facet.count;
+    },
+    facetIsSelected(fieldId, item) {
+        const queryParams = this.$route.query[fieldId];
+        return queryParams && (queryParams === item.id || queryParams.includes(item.id));
+    }
+  }
+});
+
+</script>
+
+<style lang="scss" scoped>
+.facet-header {
+  // background-color: #fffade;
+  // background-color: rgba(255, 204, 0, 0.1);
+  background-color: rgba(0, 29, 133,0.05);
+  // background-color: #cddbe8;
+
+  // background-color: #001d85;
+  // color: white !important;
+}
+.tooltip-icon {
+  font-size: 15px;
+}
+
+@media (min-width: 768px) {
+  .collapse.dont-collapse-sm {
+    display: block;
+    height: auto !important;
+    visibility: visible;
+  }
+}
+
+.list-item-container {
+  margin-bottom: -1px;
+}
+
+.btn-color {
+  background-color: var(--primary);
+  border-color: var(--primary);
+
+  &:hover {
+    background-color: #196fd2;
+    border-color: #196fd2;
+  }
+}
+.active {
+  background-color: var(--primary);
+  border-color: var(--primary);
+}
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/FacetTitle.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/FacetTitle.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f8b12e9e359f1acf328fecd3404edb5a4a3d9814
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/FacetTitle.vue
@@ -0,0 +1,39 @@
+<template>
+  <div class="d-none d-md-block list-group-item facet-title">
+    <h2 class="h5 mb-0 float-left" :id="titleId">{{ title }}</h2>
+    <i v-if="tooltip"
+       class="tooltip-icon material-icons small-icon align-right text-dark pl-1"
+       ref="tooltip-icon"
+       data-toggle="tooltip"
+       data-placement="right"
+       :title="tooltip">
+      help_outline
+    </i>
+  </div>
+</template>
+
+<script>
+
+
+export default {
+  name: "FacetTitle",
+  props: {
+    title: String,
+    tooltip: String,
+    titleId: {
+      type: String,
+      default: null,
+    },
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.facet-title {
+  background-color: rgba(0, 29, 133,0.05);
+}
+
+.tooltip-icon {
+  font-size: 15px;
+}
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/InfoFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/InfoFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..946476b225ada210e3fcd16ba1503e000aeae337
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/InfoFacet.vue
@@ -0,0 +1,21 @@
+<template>
+  <div>
+    <h2>{{ config.title }}</h2>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import {FacetsConfigItem} from "../types";
+  defineProps<{
+    config: FacetsConfigItem
+  }>();
+</script>
+
+<style scoped>
+  h2 {
+    border-radius: .5rem;
+    background-color: lightsalmon;
+    padding: .75rem;
+    margin: .5rem 0;
+  }
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/PublisherFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/PublisherFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..9cf0670d48f6e3565b6ca4997e949538093be790
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/PublisherFacet.vue
@@ -0,0 +1,17 @@
+<template>
+  <div>
+    <h2>Publisher!!!!</h2>
+  </div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+  h2 {
+    border-radius: .75rem;
+    background-color: gold;
+    padding: 0.75rem;
+  }
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/RadioFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/RadioFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ba7dfbea029945f7770794cd92a1a3a89c9a4942
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/RadioFacet.vue
@@ -0,0 +1,75 @@
+<template>
+  <div class="list-group w-100 radio-facet" role="group" :aria-labelledby="myTitleId">
+    <facet-title
+      :title="header"
+      :tooltip="toolTipTitle"
+      :title-id="myTitleId"
+    />
+    <div class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
+      {{ property }}
+      <span class="ml-2 d-flex flex-wrap">
+        <div class="custom-control custom-radio" v-for="(id, index) in optionIds">
+          <input type="radio" :id="`${header}_${id}`" :value="id" :name="header" class="custom-control-input" @click="onChange(id)" :checked="option === id">
+          <label class="custom-control-label" :for="`${header}_${id}`">{{ optionLabels[index] }}</label>
+        </div>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import FacetTitle from "../facets/FacetTitle.vue";
+export default {
+  name: "RadioFacet",
+  components: {FacetTitle},
+  props: {
+    config: Object,
+    property: String,
+    optionIds: {
+      type: Array,
+      default: ['true', 'false']
+    },
+    optionLabels: {
+      type: Array
+    },
+    initialOption: String,
+    change: Function
+  },
+  data() {
+    return {
+      id: '',
+      option: this.initialOption,
+      header: this.i18n.global.t(`message.datasetFacets.facets.${this.config.id.toLowerCase()}`),
+      toolTipTitle: this.i18n.global.t(`message.helpIcon.${this.config.id.toLowerCase()}`),
+      yes: this.i18n.global.t('message.metadata.yes'),
+      no: this.i18n.global.t('message.metadata.no')
+    };
+  },
+  computed: {
+    myId() {
+      // Use Vue generated uid to give each facet a unique id
+      return `facet-${this.id}`;
+    },
+    myTitleId() {
+      // Use Vue generated uid to give each facet a unique id
+      return `facet-title-${this.id}`;
+    }
+  },
+  methods: {
+    onChange(id) {
+      this.option = id;
+      console.log("onChange", id)
+      this.change(id);
+    }
+  },
+  watch: {
+    initialOption(value) {
+      this.option = value;
+    }
+  },
+  mounted() {
+    this.id = this._uid; // eslint-disable-line
+  },
+}
+</script>
+
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacet.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacet.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fcb979055a5d1d55f36ebc9f457403f4c78def51
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacet.vue
@@ -0,0 +1,21 @@
+<template>
+  <div>
+    <h2>{{ config.title }}</h2>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import {FacetsConfigItem} from "../types";
+
+  defineProps<{
+    config: FacetsConfigItem
+  }>();
+</script>
+
+<style scoped>
+  h2 {
+    border-radius: .75rem;
+    background-color: lightsalmon;
+    padding: 0.75rem;
+  }
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacetsItem.vue b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacetsItem.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fba6dd03da4a7943b73a4112ddd44ab3b1a83ac0
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/facets/SelectFacetsItem.vue
@@ -0,0 +1,40 @@
+<template>
+  <button
+    :title="tooltip"
+    >
+      <span ref="facetBtn" class="text-truncate">{{ title }}</span>
+      <span v-if="!hideCount" class="facet-count badge">{{ count.toLocaleString('fi') }}</span>
+  </button>
+</template>
+
+<script>
+
+export default {
+  name: 'DatasetsFacetsItem',
+  data() {
+    return {
+      tooltip: '',
+    };
+  },
+  props: {
+    title: {
+      type: String,
+      default: '',
+    },
+    count: {
+      type: [Number, String],
+      default: 0,
+    },
+    hideCount: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  mounted() {
+    // Sets tooltip text to title when title itself is rendered truncated
+    this.tooltip = this.$refs.facetBtn.offsetWidth < this.$refs.facetBtn.scrollWidth
+      ? this.title
+      : '';
+  },
+};
+</script>
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/getFacet.ts b/packages/piveau-hub-ui-modules/lib/facets_2.0/getFacet.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b042f4de079a036947808ee872c00c386e0489a5
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/getFacet.ts
@@ -0,0 +1,19 @@
+import {Component} from "vue";
+import {extras} from "../configurations/configureModules";
+import ExpandableSelectFacet from "./facets/ExpandableSelectFacet.vue";
+import DataServicesFacet from "./facets/DataServicesFacet.vue";
+import RadioFacet from "./facets/RadioFacet.vue";
+
+export const getFacet = (id: string): Component => {
+    const custom = extras.customFacets;
+    if (custom && custom[id]) { // custom
+        return custom[id];
+    } else { // defaults
+        switch (id) {
+            case "dataServices": return DataServicesFacet;
+            case "superCatalog": return RadioFacet;
+            // case "dataServices":case "superCatalog": return InfoFacet;
+        }
+        return ExpandableSelectFacet;
+    }
+}
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/toggleQueryParam.ts b/packages/piveau-hub-ui-modules/lib/facets_2.0/toggleQueryParam.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1dbdd01d5f3dab0cc656a02195b10403b769f9e0
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/toggleQueryParam.ts
@@ -0,0 +1,31 @@
+/**
+ * Uses the vue router to perform the action of selecting a query param key-value pair.
+ * If it already exists in the route it is removed, else it is added.
+ * @param key
+ * @param value
+ * @param router
+ * @param route
+ */
+export function toggleQueryParam(key, value, router, route) {
+    let query: any = route.query[key];
+    console.log("QUERY", query, typeof query)
+    if ( ! query) {
+        query = value;
+    } else if (typeof query === 'string') {
+        if (query === value) {
+            query = undefined;
+        } else {
+            query = [query, value];
+        }
+    } else if (Array.isArray(query)) {
+        if (query.includes(value)) {
+            query = query.filter(element => element !== value);
+        } else {
+            query = [...query, value];
+        }
+    }
+    router.push({
+        path: route.path,
+        query: {...route.query, [key]: query}
+    });
+}
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/types.d.ts b/packages/piveau-hub-ui-modules/lib/facets_2.0/types.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..934d27ec005ca98be34b733fd60010a76a8d3034
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/types.d.ts
@@ -0,0 +1,8 @@
+import {Ref} from "vue";
+import {LocationQueryValue} from "vue-router";
+
+export type FacetsConfigItem = {title: String, id: String, items: [], selected: string | null | LocationQueryValue[]};
+export type FacetsConfig = [FacetsConfigItem];
+
+export type FacetState = {config:FacetsConfigItem, selection:unknown};
+export type FacetsState = [FacetState];
diff --git a/packages/piveau-hub-ui-modules/lib/facets_2.0/useFacets.ts b/packages/piveau-hub-ui-modules/lib/facets_2.0/useFacets.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f2c1471c604cb563641a9dc4302257438114b1ef
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/facets_2.0/useFacets.ts
@@ -0,0 +1,19 @@
+import {FacetsConfig, FacetsConfigItem} from "./types";
+import {Ref, ref, toValue, watchEffect} from "vue";
+import {RouteLocationNormalizedLoadedGeneric} from "vue-router";
+
+export function useFacets(facetsConfig: Ref<FacetsConfig>, facetsIds, route: RouteLocationNormalizedLoadedGeneric) {
+    const facets = ref(null);
+    const currentFacets = () => {
+        facets.value = (facetsIds || []).reduce((acc, curr) => {
+            const configItem: FacetsConfigItem = toValue(facetsConfig).find(c => c.id === curr);
+            if (configItem) {
+                // configItem.selected = route.query[configItem.id];
+                acc.push(configItem);
+            }
+            return acc;
+        }, []);
+    };
+    watchEffect(currentFacets);
+    return facets;
+}
diff --git a/packages/piveau-hub-ui-modules/lib/form/FormKitGroup.vue b/packages/piveau-hub-ui-modules/lib/form/FormKitGroup.vue
index 4edbd325a9796e25c77fa051e5e4ca47b26d102c..790ad6b65c3c59704891ed04b912768b5381943a 100644
--- a/packages/piveau-hub-ui-modules/lib/form/FormKitGroup.vue
+++ b/packages/piveau-hub-ui-modules/lib/form/FormKitGroup.vue
@@ -132,7 +132,7 @@
     }
   }
   
-  button {
+  .dpi button {
     align-self: flex-start;
   }
   </style>
diff --git a/packages/piveau-hub-ui-modules/lib/form/Repeatable.vue b/packages/piveau-hub-ui-modules/lib/form/Repeatable.vue
index 439d53b26b0580f26b624f1df12641bf7d7fc9be..eff9c9c1a374655e081d6452c55d559c4d0995e8 100644
--- a/packages/piveau-hub-ui-modules/lib/form/Repeatable.vue
+++ b/packages/piveau-hub-ui-modules/lib/form/Repeatable.vue
@@ -1,9 +1,9 @@
 <template>
-  <div class="repeatable formkitProperty" :class="[props.context.attrs.identifier]"
-    v-for="key, repeatableIndex in counter" :key="key">
-    <h4 v-if="props.context.attrs.class != undefined && props.context.attrs.class.includes('inDistribution')">{{
-      $t('message.dataupload.distributions.' + props.context.attrs.identifier + '.label') }}</h4>
-    <h4 v-else>{{ $t('message.dataupload.datasets.' + props.context.attrs.identifier + '.label') }}</h4>
+  <div class="repeatable formkitProperty" :class="[props.context?.attrs.identifier]"
+    v-for="({ item: key, nonce }, repeatableIndex) in counter" :key="`${nonce}`">
+    <h4 v-if="!!props.context?.attrs.class && props.context.attrs.class.includes('inDistribution')">
+      {{ $t('message.dataupload.distributions.' + props.context.attrs.identifier + '.label') }}</h4>
+    <h4 v-else>{{ $t('message.dataupload.datasets.' + props.context?.attrs.identifier + '.label') }}</h4>
     <div class="horizontal-wrapper">
       <div class="repeatableWrap">
         <div class="interactionHeaderRepeatable my-1">
@@ -13,7 +13,7 @@
             </template>
             <template v-slot:remove>
 
-              <a class="remove" :class="{ disabledRemove: props.context.value.length === 1 }"
+              <a class="remove" :class="{ disabledRemove: props.context?.value.length === 1 }"
                 @click="removeItem(repeatableIndex, counter.length)" :data-key="key">- {{
                   $t('message.dataupload.info.remove') }}</a>
             </template>
@@ -28,36 +28,40 @@
     </div>
   </div>
 </template>
-<script setup>
-import { ref } from 'vue';
+<script setup lang="ts">
+import { whenever } from '@vueuse/core';
+import { computed, ref } from 'vue';
 
 const props = defineProps({
   context: Object
 })
 
-const counter = ref([])
+const counter = ref<any[]>([{ value: 'init', nonce: 0 }])
+const nonce = ref(0)
 
-// Need to handle the data like this. The values seem to take their time while loading into the DOM.
-setTimeout(() => {
-  if (props.context.value.length === 0) {
-    counter.value.push('init')
+whenever(() => props.context?.value, (newValue, oldValue) => {
+  // Workaround to prevent infinite recursive loop
+  if (JSON.stringify(newValue) === JSON.stringify(oldValue)) {
+    return
   }
-  else {
-    for (let index = 0; index < props.context.value.length; index++) {
-      if (props.context.value[index] != null) {
-        counter.value.push(props.context.value[index]['@value'])
-      }
-    }
+  if (!newValue || newValue.length === 0) {
+    counter.value = [{ value: 'init', nonce: 0 }];
+  } else {
+    counter.value = newValue.filter(Boolean).map((item: any, idx: number) => ({ value: item['@value'] ?? item.name ?? item, nonce: idx }));
   }
+
+  nonce.value = counter.value.length
+}, {
+  immediate: false,
 });
 
 // Pushing a blank to the context object and refreshing the counter
-const addItem = (index) => {
-  counter.value.push(props.context.value[index]['@value'])
-
+const addItem = (index: number) => {
+  counter.value.push({ item: props.context?.value[index]['@value'], nonce: nonce.value })
+  nonce.value += 1
 }
 // remove Item - ToDo need to make sure the localhost notices the splice
-const removeItem = (index, counterLength) => {
+const removeItem = (index: number, counterLength: number) => {
 
   if (counterLength != 1) {
     counter.value.splice(index, 1)
diff --git a/packages/piveau-hub-ui-modules/lib/index.ts b/packages/piveau-hub-ui-modules/lib/index.ts
index aaccf9784ef84d7ccc1156c3cf58fae461640c54..300f4dd99ffdfe6b6c971c440c577e3b78650ebe 100644
--- a/packages/piveau-hub-ui-modules/lib/index.ts
+++ b/packages/piveau-hub-ui-modules/lib/index.ts
@@ -11,6 +11,7 @@ import runtimeConfigurationService from "./services/runtimeConfigurationService"
 import datasetService from "./services/datasetService";
 import catalogService from "./services/catalogService";
 import gazetteerService from "./services/gazetteerService";
+import { getResponseData } from "./services/datasetService";
 
 
 // Import Stores
@@ -57,6 +58,7 @@ import DatasetCitationTable from "./citation/DatasetCitationTable";
 import AutocompleteInput from "./data-provider-interface/components/AutocompleteInput";
 import ConditionalInput from "./data-provider-interface/components/ConditionalInput";
 import DataFetchingComponent from "./data-provider-interface/components/DataFetchingComponent";
+import CatalogueMQA from "./data-provider-interface/CatalogueMQA";
 import Dropup from "./data-provider-interface/components/Dropup";
 import FileUpload from "./data-provider-interface/components/FileUpload";
 import InfoSlot from "./data-provider-interface/components/InfoSlot";
@@ -164,6 +166,8 @@ import DatasetsFilters from "./datasets/DatasetsFilters";
 import DatasetsFiltersTabs from "./datasets/DatasetsFiltersTabs";
 import DatasetsTopControls from "./datasets/DatasetsTopControls";
 
+import Search from "./search/Search.vue";
+
 // Import datasetsFacets
 import CatalogDetailsFacet from "./facets/CatalogDetailsFacet";
 import DatasetsFacets from "./datasets/datasetsFacets/DatasetsFacets";
@@ -222,6 +226,8 @@ import Tooltip from "./widgets/Tooltip";
 
 import {configSchema} from "./configurations/config-schema";
 export {
+  Search,
+
   inputDefinitions,
   configSchema,
   vueKeycloak,
@@ -233,6 +239,8 @@ export {
   catalogService,
   gazetteerService,
 
+  getResponseData,
+
   store,
 
   decode,
@@ -260,7 +268,7 @@ export {
   DatasetCitationTable,
 
   AutocompleteInput,
- 
+
   ConditionalInput,
   DataFetchingComponent,
   Dropup,
@@ -281,6 +289,7 @@ export {
   LinkedDataViewer,
   OverviewPage,
   UserCataloguesPage,
+  CatalogueMQA,
   UserProfilePage,
   DataProviderInterface,
   DpiMenu,
@@ -399,4 +408,6 @@ export * as helpers from "./utils/helpers";
 export { defineUserConfig, type Config, type ResolvedConfig } from "./configurations/config-schema";
 
 export { useRuntimeEnv } from './composables/useRuntimeEnv';
-export * as head from './composables/head';
\ No newline at end of file
+export * as head from './composables/head';
+
+export * as dpi from './data-provider-interface';
diff --git a/packages/piveau-hub-ui-modules/lib/modal/AppConfirmationDialog.vue b/packages/piveau-hub-ui-modules/lib/modal/AppConfirmationDialog.vue
index 606825b9802b6944e7210ea616288a00f700cc51..e02e4cd42ff29b1b9e836554e2581587a2bd1b88 100644
--- a/packages/piveau-hub-ui-modules/lib/modal/AppConfirmationDialog.vue
+++ b/packages/piveau-hub-ui-modules/lib/modal/AppConfirmationDialog.vue
@@ -35,7 +35,8 @@
 </template>
 
 <script>
-import { defineComponent } from 'vue'
+import { computed, defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n';
 import $ from 'jquery';
 
 export default defineComponent({
@@ -51,21 +52,17 @@ export default defineComponent({
       default: false,
     },
   },
-  data() {
-    return {
-      resolvedConfirm: this.confirm,
-    };
-  },
   methods:{
     handleHeader(){
       $('#navbar-toggle').css("z-index", "99")
     }
-  }, created() {
-    if (this.confirm === 'Confirm') { // Überprüfe den Default-Wert
-      this.$i18n.locale = this.$route.query.locale
-      this.resolvedConfirm = this.$t('message.dataupload.modal.confirmModal');     
-    }
   },
+  setup(props) {
+    const { t, te } = useI18n();
+    const resolvedConfirm = computed(() => props.confirm === 'Confirm' && te('message.dataupload.modal.confirmModal') ? t('message.dataupload.modal.confirmModal') : props.confirm);
+
+    return { resolvedConfirm };
+  }
 });
 </script>
 
diff --git a/packages/piveau-hub-ui-modules/lib/scss/_dpi-style.scss b/packages/piveau-hub-ui-modules/lib/scss/_dpi-style.scss
index c61d9bb7a538f0e5146c27aab1e5ab7594e052e8..c8e222e7f1ea6c7b9d89f9217930e068d298eaea 100644
--- a/packages/piveau-hub-ui-modules/lib/scss/_dpi-style.scss
+++ b/packages/piveau-hub-ui-modules/lib/scss/_dpi-style.scss
@@ -711,7 +711,7 @@
     transition: all ease-in-out 200ms;
 
     &:hover {
-        background-color: #bababa;
+        background-color: lightcoral;
     }
 
     &:hover:before {
@@ -807,10 +807,11 @@
     border-radius: 15px;
     transition: all 100ms ease-in-out;
     display: flex;
+    color: green;
 
-    &:hover {
-        color: #196fd2;
-    }
+    // &:hover {
+    //     color: lightcoral;
+    // }
 
     .removeX {
         margin-right: 0;
diff --git a/packages/piveau-hub-ui-modules/lib/search/Datasets.vue b/packages/piveau-hub-ui-modules/lib/search/Datasets.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2dd905f2ac067879eaf0851c76cda3604ff9b90d
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/search/Datasets.vue
@@ -0,0 +1,11 @@
+<template>
+
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/search/Search.vue b/packages/piveau-hub-ui-modules/lib/search/Search.vue
new file mode 100644
index 0000000000000000000000000000000000000000..91505fe8f38315765af1bef50174d86cf46b92da
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/search/Search.vue
@@ -0,0 +1,25 @@
+<template>
+  <div id="search-container">
+    <datasets-top-controls
+        :getPage="getPage"
+        :getLimit="getLimit"
+        class="datasets-top-controls"
+    />
+    <h1>New Search Page</h1>
+<!--    <facets-->
+<!--        :facetsConfig="getAllAvailableFacets"-->
+<!--        :facetsIds="$env.content.datasets.facets.defaultFacetOrder"-->
+<!--        class="col-md-3 col-12 mb-3 mb-md-0 px-0 collapse"-->
+<!--        id="datasetFacets">-->
+
+<!--    </facets>-->
+  </div>
+</template>
+
+<script setup>
+  import DatasetsTopControls from "../datasets/DatasetsTopControls.vue";
+</script>
+
+<style scoped>
+
+</style>
diff --git a/packages/piveau-hub-ui-modules/lib/search/TopControls.vue b/packages/piveau-hub-ui-modules/lib/search/TopControls.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e83f5195b4703c1eb7b109e8046cd3c843b27a42
--- /dev/null
+++ b/packages/piveau-hub-ui-modules/lib/search/TopControls.vue
@@ -0,0 +1,79 @@
+<template>
+  <sub-navigation>
+    <div class="container-fluid justify-content-between">
+      <div class="navbar-datasets-feed navbar-nav align-items-center justify-content-end">
+        <div class="nav-item dropdown">
+          <div v-if="useFeed" class="nav-link dropdown-toggle cursor-pointer"
+               id="dropdown-feeds" data-toggle="dropdown"
+               aria-haspopup="true" aria-expanded="false">
+            <ins>{{ $t('message.datasets.datasetsFeed') }}</ins>
+          </div>
+          <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdown-feeds">
+            <app-link class="dropdown-item text-decoration-none"
+                      :path="getFeedLink('rss')"
+                      :query="getFeedQuery()"
+                      target="_blank"
+                      matomo-track-page-view>
+              RSS Feed</app-link>
+            <app-link class="dropdown-item text-decoration-none"
+                      :path="getFeedLink('atom')"
+                      :query="getFeedQuery()"
+                      target="_blank"
+                      matomo-track-page-view>
+              ATOM Feed</app-link>
+          </div>
+        </div>
+      </div>
+    </div>
+  </sub-navigation>
+</template>
+
+<script>
+import AppLink from "../widgets/AppLink.vue";
+import {mapGetters} from "vuex";
+
+export default {
+  name: "TopControls",
+  components: {
+    AppLink
+  },
+  props: [
+    "facets",
+    "getPage",
+    "getLimit"
+  ],
+  data() {
+    return {
+      useFeed: this.$env.content.datasets.useFeed,
+      baseUrl: this.$env.api.baseUrl,
+    }
+  },
+  computed: {
+    ...mapGetters('datasets', [
+      'getSort'
+    ])
+  },
+  methods: {
+    getFeedLink(format) {
+      return `${this.baseUrl}${this.$route.query.locale}/feeds/datasets.${format}`;
+    },
+    getFeedQuery() {
+      const feedQuery = {};
+      const query = this.$route?.query
+      if (query?.query) feedQuery.q = query.query;
+      if (this.facetsNotEmpty() && JSON.stringify(this.facets)) feedQuery.facets = JSON.stringify(this.facets);
+      if (this.getPage) feedQuery.page = Math.max(this.getPage - 1, 0);
+      if (this.getLimit) feedQuery.limit = this.getLimit;
+      feedQuery.facetOperator = query?.facetOperator || 'AND';
+      feedQuery.facetGroupOperator = query?.facetOperator || 'AND';
+      feedQuery.dataServices = query?.dataServices || 'false';
+      if (this.getSort) feedQuery.sort = this.getSort;
+      return feedQuery;
+    },
+    facetsNotEmpty() {
+      return Object.values(this.facets).some(facet => facet.length > 0);
+    }
+  }
+}
+</script>
+
diff --git a/packages/piveau-hub-ui-modules/lib/services/datasetService.ts b/packages/piveau-hub-ui-modules/lib/services/datasetService.ts
index a8ece8c3c57d0553fdf9e63fd4668e8f3d0ca2e5..0a7d7ed32179d9ff4ee1f929d40e979b993b1e0a 100644
--- a/packages/piveau-hub-ui-modules/lib/services/datasetService.ts
+++ b/packages/piveau-hub-ui-modules/lib/services/datasetService.ts
@@ -5,7 +5,7 @@
 
  import dataGetters from './getters/data-getters';
 
- const getResponseData = (dataset: { is_hvd: boolean; }) => {
+ export const getResponseData = (dataset: { is_hvd: boolean; }) => {
    const ds: {[key: string]: unknown} = {};
    // New fields from DCAT-AP.de
    // Dataset
@@ -30,7 +30,7 @@
    ds.catalogRecord = dataGetters.getObject(dataset, 'catalog_record', ['issued', 'modified']);
    ds.categories = dataGetters.getArrayOfObjects(dataset, 'categories', ['id', 'label']);
    ds.conformsTo = dataGetters.getArrayOfObjects(dataset, 'conforms_to', ['label', 'resource']);
-   ds.contactPoints = dataGetters.getArrayOfObjects(dataset, 'contact_point', ['name', 'type', 'resource', 'email', 'telephone', 'address', 'url']);
+   ds.contactPoints = dataGetters.getArrayOfObjects(dataset, 'contact_point', ['name','organisation_name', 'type', 'resource', 'email', 'telephone', 'address', 'url']);
    ds.country = dataGetters.getObject(dataset, 'country', [{ key: 'id', default: 'eu' }, { key: 'title', default: 'European Union' }]);
    ds.creator = dataGetters.getObject(dataset, 'creator', ['name', 'type', 'email', 'resource', 'homepage']);
    ds.deadline = dataGetters.getString(dataset, 'deadline');
@@ -70,7 +70,7 @@
    ds.sample = dataGetters.getArrayOfStrings(dataset, 'sample');
    ds.sources = dataGetters.getArrayOfStrings(dataset, 'source');
    ds.spatial = dataGetters.getArrayOfObjects(dataset, 'spatial', ['type', 'coordinates']);
-   ds.spatialResolutionInMeters = dataGetters.getArrayOfNumbers(dataset, 'spatial_resolution_in_meters');
+   ds.spatialResolutionInMeters = dataGetters.getNumber(dataset, 'spatial_resolution_in_meters');
    ds.spatialResource = dataGetters.getArrayOfObjects(dataset, 'spatial_resource', ['label', 'resource']);
    ds.statUnitMeasures = dataGetters.getArrayOfStrings(dataset, 'stat_unit_measure');
    ds.subject = dataGetters.getArrayOfObjects(dataset, 'subject', ['resource', 'label', 'id']);
@@ -126,7 +126,8 @@
      distribution.pages = dataGetters.getArrayOfObjects(dist, 'page', ['format', 'title', 'description', 'resource']);
      distribution.releaseDate = dataGetters.getString(dist, 'issued');
      distribution.rights = dataGetters.getObject(dist, 'rights', ['label', 'resource']);
-     distribution.spatialResolutionInMeters = dataGetters.getArrayOfNumbers(dist, 'spatial_resolution_in_meters');
+     //distribution.spatialResolutionInMeters = dataGetters.getArrayOfNumbers(dist, 'spatial_resolution_in_meters');
+     distribution.spatialResolutionInMeters = dataGetters.getNumber(dist, 'spatial_resolution_in_meters');
      distribution.status = dataGetters.getObject(dist, 'status', ['label', 'resource']);
      distribution.temporalResolution = dataGetters.getArrayOfStrings(dist, 'temporal_resolution');
      distribution.title = dataGetters.getObjectLanguage(dist, 'title', '');
@@ -357,7 +358,7 @@
     /**
      * @description Get similar datasets to the dataset represented by the provided id.
      * @param id {string} The dataset id to get similar datasets for.
-     * @param payload
+     * @param properties additional parameters, in particular for the knn-request
      * @param query {SimilarDatasetsQuery} query params
      */
     getSimilarDatasets(id: any, properties: any, query?: SimilarDatasetsQuery) {
@@ -368,6 +369,8 @@
         }
         const similarityServiceName = this.similarityServiceName;
         if (similarityServiceName === 'knn_request') {
+            properties.exclude_uris = [`http://data.europa.eu/88u/dataset/${id}`];
+            // properties.exclude_uris = [`https://data.europa.eu/api/hub/search/datasets/${id}`];
             axios.post(`${url}knn_request/`, { ...properties, k: 10})
               .then((response) => {
                 resolve(response);
diff --git a/packages/piveau-hub-ui-modules/lib/store/modules/cataloguesStore.ts b/packages/piveau-hub-ui-modules/lib/store/modules/cataloguesStore.ts
index d46fac495c9c77e2474ba752b209ec33a059f485..d2ff82ca9f0dee8475f3213823df201d605000e9 100644
--- a/packages/piveau-hub-ui-modules/lib/store/modules/cataloguesStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/store/modules/cataloguesStore.ts
@@ -212,6 +212,12 @@ const actions = {
   setLoading({ commit }, isLoading) {
     commit('SET_LOADING', isLoading);
   },
+  setCatalogs({ commit }, catalogs) {
+    commit('SET_catalogS', catalogs);
+  },
+  setCatalogsCount({ commit }, count) {
+    commit('SET_catalogS_COUNT', count);
+  }
 };
 
 const mutations = {
diff --git a/packages/piveau-hub-ui-modules/lib/store/modules/datasetDetailsStore.ts b/packages/piveau-hub-ui-modules/lib/store/modules/datasetDetailsStore.ts
index ac6e1f8adf11148c020dbe685028b335e7f111fb..d308b4ba0f8461de7e5adecc3ebc5f55766041ef 100755
--- a/packages/piveau-hub-ui-modules/lib/store/modules/datasetDetailsStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/store/modules/datasetDetailsStore.ts
@@ -90,7 +90,7 @@ const state = {
         sources: [],
         spatial: [],
         spatialResource: [],
-        spatialResolutionInMeters: [],
+        spatialResolutionInMeters: 0,
         statUnitMeasures: [],
         subject: [],
         temporal: [],
diff --git a/packages/piveau-hub-ui-modules/lib/store/modules/datasetsStore.ts b/packages/piveau-hub-ui-modules/lib/store/modules/datasetsStore.ts
index 79248d470dd77c18b517105c6314cff95f0e0b65..e4c2d950a4d4f8735d28779ea6053abe0de09c7a 100644
--- a/packages/piveau-hub-ui-modules/lib/store/modules/datasetsStore.ts
+++ b/packages/piveau-hub-ui-modules/lib/store/modules/datasetsStore.ts
@@ -172,7 +172,6 @@ const actions = {
           reject(error);
         });
     });
-
   },
 
     /**
@@ -318,6 +317,18 @@ const actions = {
   setDataScope({ commit }, dataScope) {
     commit('SET_DATA_SCOPE', dataScope);
   },
+  setAvailableFacets({ commit }, facets) {
+    commit('SET_AVAILABLE_FACETS', facets);
+  },
+  setScoringCount({ commit }, count) {
+    commit('SET_SCORING_COUNT', count);
+  },
+  setDatasetsCount({ commit }, count) {
+    commit('SET_DATASETS_COUNT', count);
+  },
+  setDatasets({ commit }, datasets) {
+    commit('SET_DATASETS', datasets);
+  },
 };
 
 const mutations = {
diff --git a/packages/piveau-hub-ui-modules/lib/widgets/ResourceAccessPopup.vue b/packages/piveau-hub-ui-modules/lib/widgets/ResourceAccessPopup.vue
index 9423442948bbe19acb3a404e29107de5966609d1..f0b12a0d9c1598c5634117e5b4a4b6bae5c78590 100644
--- a/packages/piveau-hub-ui-modules/lib/widgets/ResourceAccessPopup.vue
+++ b/packages/piveau-hub-ui-modules/lib/widgets/ResourceAccessPopup.vue
@@ -47,9 +47,9 @@ export default {
       this.callback = '';
       this.callback = callbackFunction;
       this.toggleDownloadPopup = toggleDownloadPopup;
-      if (cookie === 'false') {
+      if (cookie === 'false' || !cookie) {
         $('#externalAccess').appendTo("body").modal('show');
-        $('#myModal').appendTo("body").modal('show');
+        $('#myModal').appendTo("body").modal('show'); // what is this?
       } else {
         this.callback();
       }
diff --git a/packages/piveau-hub-ui-modules/package.json b/packages/piveau-hub-ui-modules/package.json
index d44853316a7548f186417adbc27c3492636636bb..edaf3276992d29c8b61581d3f701ffdf76d59d4f 100644
--- a/packages/piveau-hub-ui-modules/package.json
+++ b/packages/piveau-hub-ui-modules/package.json
@@ -7,15 +7,31 @@
   "exports": {
     ".": {
       "types": "./dist/index.d.ts",
+      "import": "./dist/index",
       "default": "./dist/index"
     },
     "./configSchema": {
       "types": "./dist/configSchema.d.ts",
+      "import": "./dist/configSchema.mjs",
       "default": "./dist/configSchema.mjs"
     },
+    "./dataProviderInterface": {
+      "types": "./dist/data-provider-interface/index.d.ts",
+      "import": "./dist/dataProviderInterface.mjs",
+      "default": "./dist/dataProviderInterface.mjs"
+    },
     "./styles": "./dist/piveau-hub-ui-modules.css"
   },
   "types": "./dist/index.d.ts",
+  "typesVersions": {
+    "*": {
+      "*": [
+        "./dist/index.d.ts",
+        "./dist/configSchema.d.ts",
+        "./dist/data-provider-interface/index.d.ts"
+      ]
+    }
+  },
   "files": [
     "dist"
   ],
@@ -52,7 +68,7 @@
     "@unhead/vue": "^1.8.8",
     "leaflet": "^1.9.4",
     "leaflet-easybutton": "^2.4.0",
-    "vue": "^3.3.8",
+    "vue": "^3.5.12",
     "vue-demi": "^0.13.1",
     "vue-router": "^4.1.6",
     "vuex": "^4.0.2",
diff --git a/packages/piveau-hub-ui-modules/vite.config.ts b/packages/piveau-hub-ui-modules/vite.config.ts
index 9314bcf619def5fd32a5c4a93bf9bec21cae970d..ff71a3daa93b95c28861eaf53190ab8aa66d2981 100644
--- a/packages/piveau-hub-ui-modules/vite.config.ts
+++ b/packages/piveau-hub-ui-modules/vite.config.ts
@@ -24,6 +24,7 @@ const peerDependencies = {
   "@triply/yasgui": "x.x.x",
   "@triply/yasqe": "x.x.x",
   "@triply/yasr": "x.x.x",
+  "@vueuse/router": "",
   "animejs": "x.x.x",
   "axios": "x.x.x",
   "bootstrap": "x.x.x",
@@ -105,7 +106,7 @@ export default defineConfig({
     ),
     copy({
       targets: [
-        { src: 'lib/scss', dest: 'dist' }
+        { src: 'lib/scss', dest: 'dist' },
       ],
       hook: 'writeBundle',
       verbose: true,
@@ -168,6 +169,7 @@ export default defineConfig({
     lib: {
       entry: {
         'index': path.resolve(__dirname, 'lib/index'),
+        'dataProviderInterface': path.resolve(__dirname, 'lib/data-provider-interface/index'),
         // We build config schema as a separate module due to side effects in the main modules
         // for those who want to use consume the config schema in isolation
         'configSchema': path.resolve(__dirname, 'lib/configurations/config-schema/index'),
@@ -187,6 +189,8 @@ export default defineConfig({
           vue: 'Vue'
         },
 
+        chunkFileNames: 'piveau-hub-ui-modules.[ext]',
+
         entryFileNames: (chunkInfo) => {
           // if chunkInfo.name starts with node_modules, replace with external
           if (chunkInfo.name.startsWith('node_modules')) {