diff --git a/.env.example b/.env.example index 2f97d5d..ea6aeaa 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,4 @@ APP_URL=//tethys.at VUE_API=//www.tethys.at -# SOLR_HOST=tethys.at -# SOLR_CORE=rdr_data -OPEN_HOST=192.168.21.18 -OPEN_CORE=tethys-records \ No newline at end of file +SOLR_HOST=tethys.at +SOLR_CORE=rdr_data \ No newline at end of file diff --git a/OpenSearch queries.txt b/OpenSearch queries.txt deleted file mode 100644 index 5a84e5e..0000000 --- a/OpenSearch queries.txt +++ /dev/null @@ -1,9 +0,0 @@ -Get all documents in the index ("core" in solr) ----------------------------------------------------- -curl -XGET "http://192.168.21.18/tethys-records/_search?pretty" -H 'Content-Type: application/json' -d' -{ - "query": { - "match_all": {} - } -}' - diff --git a/SOLR queries.txt b/SOLR queries.txt deleted file mode 100644 index 30d17b7..0000000 --- a/SOLR queries.txt +++ /dev/null @@ -1,60 +0,0 @@ -Search by a specific value for one of the fields -https://tethys.at/solr/rdr_data/select?&q=year:2024 - -Search within a specific range of values for one of the fields -https://tethys.at/solr/rdr_data/select?&q=year:2023%20TO%202024 years 2023 to 2024 - -Search for a term (search done in predefined field?) -https://tethys.at/solr/rdr_data/select?&q=linz - -Predefined Tethys Search -https://tethys.at/solr/rdr_data/select?&0=fl%3Did%2Clicence%2Cserver_date_published%2Cabstract_output%2Cidentifier%2Ctitle_output%2Ctitle_additional%2Cauthor%2Csubject%2Cdoctype&q=%2A&q.op=or&defType=edismax&qf=title%5E3%20author%5E2%20subject%5E1&indent=on&wt=json&rows=10&start=0&sort=server_date_published%20desc&facet=on&json.facet.language=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22language%22%20%7D&json.facet.subject=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22subject%22%2C%20limit%3A%20-1%20%7D&json.facet.year=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22year%22%20%7D&json.facet.author=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22author_facet%22%2C%20limit%3A%20-1%20%7D - -Predefined Tethys search changing the last facet to "doctype" -https://tethys.at/solr/rdr_data/select?&0=fl%3Did%2Clicence%2Cserver_date_published%2Cabstract_output%2Cidentifier%2Ctitle_output%2Ctitle_additional%2Cauthor%2Csubject%2Cdoctype&q=*&q.op=or&defType=edismax&qf=title^3%20author^2%20subject^1&indent=on&wt=json&rows=10&start=0&sort=server_date_published%20desc&facet=on&json.facet.language={%20type%3A%20%22terms%22%2C%20field%3A%20%22language%22%20}&json.facet.subject={%20type%3A%20%22terms%22%2C%20field%3A%20%22subject%22%2C%20limit%3A%20-1%20}&json.facet.author={%20type%3A%20%22terms%22%2C%20field%3A%20%22author_facet%22%2C%20limit%3A%20-1%20}&json.facet.doctype={%20type%3A%20%22terms%22%2C%20field%3A%20%22doctype%22%2C%20limit%3A%20-1%20} - -Giving a value for only one facet => Author: Coric, Stjepan (16) -https://tethys.at/solr/rdr_data/select?&0=fl%3Did%2Clicence%2Cserver_date_published%2Cabstract_output%2Cidentifier%2Ctitle_output%2Ctitle_additional%2Cauthor%2Csubject%2Cdoctype&q=%2A&q.op=or&defType=edismax&qf=title%5E3%20author%5E2%20subject%5E1&indent=on&wt=json&rows=10&fq=author%3A%28%22Coric%2C%20Stjepan%22%29&start=0&sort=server_date_published%20desc&facet=on&json.facet.language=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22language%22%20%7D&json.facet.subject=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22subject%22%2C%20limit%3A%20-1%20%7D&json.facet.year=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22year%22%20%7D&json.facet.author=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22author_facet%22%2C%20limit%3A%20-1%20%7D - - - -ASCII -+----+-----+----+-----+----+-----+----+-----+ -| Hx | Chr | Hx | Chr | Hx | Chr | Hx | Chr | -+----+-----+----+-----+----+-----+----+-----+ -| 00 | NUL | 20 | SPC | 40 | @ | 60 | ` | -| 01 | SOH | 21 | ! | 41 | A | 61 | a | -| 02 | STX | 22 | " | 42 | B | 62 | b | -| 03 | ETX | 23 | # | 43 | C | 63 | c | -| 04 | EOT | 24 | $ | 44 | D | 64 | d | -| 05 | ENQ | 25 | % | 45 | E | 65 | e | -| 06 | ACK | 26 | & | 46 | F | 66 | f | -| 07 | BEL | 27 | ' | 47 | G | 67 | g | -| 08 | BS | 28 | ( | 48 | H | 68 | h | -| 09 | TAB | 29 | ) | 49 | I | 69 | i | -| 0A | LF | 2A | * | 4A | J | 6A | j | -| 0B | VT | 2B | + | 4B | K | 6B | k | -| 0C | FF | 2C | , | 4C | L | 6C | l | -| 0D | CR | 2D | - | 4D | M | 6D | m | -| 0E | SO | 2E | . | 4E | N | 6E | n | -| 0F | SI | 2F | / | 4F | O | 6F | o | -| 10 | DLE | 30 | 0 | 50 | P | 70 | p | -| 11 | DC1 | 31 | 1 | 51 | Q | 71 | q | -| 12 | DC2 | 32 | 2 | 52 | R | 72 | r | -| 13 | DC3 | 33 | 3 | 53 | S | 73 | s | -| 14 | DC4 | 34 | 4 | 54 | T | 74 | t | -| 15 | NAK | 35 | 5 | 55 | U | 75 | u | -| 16 | SYN | 36 | 6 | 56 | V | 76 | v | -| 17 | ETB | 37 | 7 | 57 | W | 77 | w | -| 18 | CAN | 38 | 8 | 58 | X | 78 | x | -| 19 | EM | 39 | 9 | 59 | Y | 79 | y | -| 1A | SUB | 3A | : | 5A | Z | 7A | z | -| 1B | ESC | 3B | ; | 5B | [ | 7B | { | -| 1C | FS | 3C | < | 5C | \ | 7C | | | -| 1D | GS | 3D | = | 5D | ] | 7D | } | -| 1E | RS | 3E | > | 5E | ^ | 7E | ~ | -| 1F | US | 3F | ? | 5F | _ | 7F | DEL | -+----+-----+----+-----+----+-----+----+-----+ -https://www.asciitable.com/ see Hx - -If you write encodeURIComponent(",") in your JavaScript console, then you will also get %2C. And with decodeURIComponent("%2C") you will get back the "," \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fd2d521..dd1474d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "axios": "^1.2.2", "class-transformer": "^0.5.1", "dayjs": "^1.10.7", - "dompurify": "^3.1.6", "leaflet": "^1.9.4", "qs": "^6.10.1", "rxjs": "^7.5.5", @@ -30,7 +29,6 @@ "@babel/plugin-proposal-decorators": "^7.22.5", "@babel/preset-env": "^7.22.5", "@tailwindcss/forms": "^0.5.7", - "@types/dompurify": "^3.0.5", "@types/leaflet": "^1.7.9", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", @@ -2499,16 +2497,6 @@ "@types/node": "*" } }, - "node_modules/@types/dompurify": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/trusted-types": "*" - } - }, "node_modules/@types/eslint": { "version": "8.56.7", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz", @@ -2706,12 +2694,6 @@ "@types/node": "*" } }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true - }, "node_modules/@types/webpack-env": { "version": "1.18.4", "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.4.tgz", @@ -3973,11 +3955,10 @@ "peer": true }, "node_modules/assert-never": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.3.0.tgz", - "integrity": "sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/async": { @@ -4145,7 +4126,6 @@ "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "@babel/types": "^7.9.6" @@ -4313,13 +4293,12 @@ } }, "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" + "fill-range": "^7.0.1" }, "engines": { "node": ">=8" @@ -5586,7 +5565,6 @@ "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/dom-converter": { @@ -5648,12 +5626,6 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", - "license": "(MPL-2.0 OR Apache-2.0)" - }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", @@ -6664,11 +6636,10 @@ } }, "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7845,7 +7816,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -8056,7 +8026,6 @@ "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/js-tokens": { @@ -10425,14 +10394,13 @@ "dev": true }, "node_modules/pug": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", - "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { - "pug-code-gen": "^3.0.3", + "pug-code-gen": "^3.0.2", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", @@ -10447,7 +10415,6 @@ "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "constantinople": "^4.0.1", @@ -10456,29 +10423,27 @@ } }, "node_modules/pug-code-gen": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", - "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", "pug-attrs": "^3.0.0", - "pug-error": "^2.1.0", - "pug-runtime": "^3.0.1", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", "void-elements": "^3.1.0", "with": "^7.0.0" } }, "node_modules/pug-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", - "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/pug-filters": { @@ -10557,7 +10522,6 @@ "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", "dev": true, - "license": "MIT", "peer": true }, "node_modules/pug-strip-comments": { @@ -12023,7 +11987,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -12421,7 +12384,6 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", "dev": true, - "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" @@ -12999,11 +12961,10 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -13163,7 +13124,6 @@ "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", "dev": true, - "license": "MIT", "peer": true, "dependencies": { "@babel/parser": "^7.9.6", @@ -13283,11 +13243,10 @@ "dev": true }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.3.0" }, diff --git a/package.json b/package.json index e0ef097..9c2e95f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "axios": "^1.2.2", "class-transformer": "^0.5.1", "dayjs": "^1.10.7", - "dompurify": "^3.1.6", "leaflet": "^1.9.4", "qs": "^6.10.1", "rxjs": "^7.5.5", @@ -33,7 +32,6 @@ "@babel/plugin-proposal-decorators": "^7.22.5", "@babel/preset-env": "^7.22.5", "@tailwindcss/forms": "^0.5.7", - "@types/dompurify": "^3.0.5", "@types/leaflet": "^1.7.9", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", diff --git a/src/App.vue b/src/App.vue index ecf21ea..ed37f71 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,4 +1,9 @@ --> - - + {
- - {{ getFilterItemsAlias(categoryAlias) }} + +
@@ -19,7 +18,7 @@ th, td { border-bottom: 0px solid #e1e1e1; } -.gsaterm { +.gbaterm { color: #0099cc; border: 1px solid rgb(200, 210, 255); padding: 4px; @@ -43,7 +42,6 @@ input[type="checkbox"].css-checkbox { } input[type="checkbox"].css-checkbox + label.css-label { - text-transform: capitalize; padding-left: 25px; /* height: 24px; display: inline-block; */ diff --git a/src/components/face-category/FacetCategory.ts b/src/components/face-category/FacetCategory.ts index 447340a..8a3f5c2 100644 --- a/src/components/face-category/FacetCategory.ts +++ b/src/components/face-category/FacetCategory.ts @@ -19,44 +19,8 @@ export default class FacetCategory extends Vue { }) filterName!: string; - replacements = new Map([ - ["gis", "GIS"], - ["analysisdata", "Analysis Data"], - ["models", "Models"], - ["monitoring", "Monitoring"], - ["measurementdata", "Measurement Data"], - ["mixedtype", "Mixed Type"], - ["de", "Deutsch"], - ["en", "English"] - ]); - - /** - * The alias for the Active facet box will be set depending on the name of the category. - * This will allow to display the customised terms "creator" and "keyword" instead of the values currently used in the OpenSearch index: "author" and "subjects" - * NOTE: This should be corrected directly in the index - */ - get categoryAlias(): string { - // console.log("filterName:", this.filterName); - // return this.filterName == "datatype" ? "doctype" : this.filterName; - - switch (this.filterName) { - case "author": - return "creator"; - case "subjects": - return "keyword"; - case "doctype": - return "Data Type"; - default: - return this.filterName; - } - } - - /** - * The alias for the items inside the "doctype / Datatype" category will be set manually in order to show user-friendly terms instead of the predefined doctypes in the DB - * NOTE: This could be corrected directly in the index - */ - itemAlias(val: string): string { - return this.replacements.get(val) || val; + get alias(): string { + return this.filterName == "datatype" ? "doctype" : this.filterName; } // get filterItems(): Array { @@ -79,34 +43,19 @@ export default class FacetCategory extends Vue { } toggle(): void { - this.collapsed = !this.collapsed; - - // Scroll to the top of the page only when collapsing - if (this.collapsed) { - this.scrollTop(); + if (this.collapsed == true) { + this.collapsed = false; + } else if (this.collapsed == false) { + this.collapsed = true; + //list.children("li:gt(4)").hide(); } } @Emit("filter") activateItem(filterItem: FacetItem): FacetItem { - console.log("Emit: ActivateItem"); - // filterItem.category = this.alias; - filterItem.category = this.filterName; + filterItem.category = this.alias; filterItem.active = true; // this.$emit("filter", filterItem); - - // Scroll to the top of the page when activating a new filter - this.scrollTop(); - return filterItem; } - - scrollTop(): void { - setTimeout(() => { - window.scrollTo({ - top: 0, - behavior: 'smooth' // Smooth scroll to the top - }); - }, 50); // Delay to allow the DOM to update - } } diff --git a/src/components/face-category/facet-category.vue b/src/components/face-category/facet-category.vue index bf3620a..4dd196d 100644 --- a/src/components/face-category/facet-category.vue +++ b/src/components/face-category/facet-category.vue @@ -2,16 +2,14 @@
-

{{ categoryAlias }}

- +

{{ filterName }}

  • - - {{ itemAlias(item.val) }} ({{ item.count }}) + {{ item.val }} ({{ item.count }})
- +
- -
- - +
    -
  • Loading results...
  • -
  • -
    - - +
@@ -136,7 +127,7 @@ input { list-style-type: none; z-index: 1000; position: absolute; - max-height: 192px; + max-height: 200px; overflow-y: auto; overflow: hidden; background: white; @@ -149,17 +140,15 @@ input { .autocomplete-result-item { list-style: none; text-align: left; - padding: 0px 0px 0px 5px; // top,right,bottom,left + /* padding: 7px 10px; */ cursor: pointer; } .autocomplete-result-item.is-active { background: rgba(0, 180, 255, 0.15); - // background: #3cc; } .autocomplete-result-item:hover { - // background: rgba(0, 180, 255, 0.075); - background: #baedf1; + background: rgba(0, 180, 255, 0.075); } diff --git a/src/components/vs-result/vs-result.ts b/src/components/vs-result/vs-result.ts index 39f6514..6984809 100644 --- a/src/components/vs-result/vs-result.ts +++ b/src/components/vs-result/vs-result.ts @@ -14,16 +14,6 @@ export default class VsResult extends Vue { return this.datasets; } - public simplifyAuthor(author:string): string { - - if (author.endsWith(" ")) { - return author.substring(0, author.indexOf(",")); - } else { - let firstNameInitial:string = author.charAt(author.indexOf(",") + 2); - return author.substring(0, author.indexOf(",") + 2) + firstNameInitial; - } - } - public getDomainWithoutSubdomain(): string { const urlParts = new URL(window.location.href).hostname.split("."); @@ -33,15 +23,13 @@ export default class VsResult extends Vue { .join("."); } - // private convert(unixtimestamp: number): string { // SOLR - private convert(unixtimestamp: string): string { // OpenSearch + private convert(unixtimestamp: number): string { // Unixtimestamp // var unixtimestamp = document.getElementById('timestamp').value; // Months array const months_arr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; // Convert timestamp to milliseconds - // const date = new Date(unixtimestamp * 1000); // SOLR - const date = new Date(Number(unixtimestamp) * 1000); // OpenSearch + const date = new Date(unixtimestamp * 1000); // Year const year = date.getFullYear(); // Month diff --git a/src/components/vs-result/vs-result.vue b/src/components/vs-result/vs-result.vue index 5387123..60b1494 100644 --- a/src/components/vs-result/vs-result.vue +++ b/src/components/vs-result/vs-result.vue @@ -3,46 +3,49 @@

+ + + {{ "https://doi.org/" + document.identifier[0] + " ➤" }}   - - - - - - - {{ simplifyAuthor(document.author[0]) }} - - - - - {{ simplifyAuthor(author) }}; - - - - - - {{ simplifyAuthor(author) }}; - - et al. - - + {{ document.author[0] }}

+ +

- + + + {{ + document.title_output + }}

+ +

{{ convert(document.server_date_published) + ": " }} - - {{ document.abstract[0] }} + {{ document.abstract_output }} ... @@ -50,9 +53,11 @@

{{ document.doctype }} + Open Access

+
diff --git a/src/constants.ts b/src/constants.ts index 2bc8d53..f689273 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,26 +1,14 @@ declare const APP_URL: string; declare const VUE_API: string; -// declare const SOLR_HOST: string; -// declare const SOLR_CORE: string; - -// OPENSEARCH -declare const OPEN_HOST: string; -declare const OPEN_CORE: string; +declare const SOLR_HOST: string; +declare const SOLR_CORE: string; const _APP_URL = APP_URL; const _VUE_API = VUE_API; -// const _SOLR_HOST = SOLR_HOST; -// const _SOLR_CORE = SOLR_CORE; - -// OPENSEARCH -const _OPEN_HOST = OPEN_HOST; -const _OPEN_CORE = OPEN_CORE; +const _SOLR_HOST = SOLR_HOST; +const _SOLR_CORE = SOLR_CORE; export { _APP_URL as APP_URL }; export { _VUE_API as VUE_API }; -// export { _SOLR_HOST as SOLR_HOST }; -// export { _SOLR_CORE as SOLR_CORE }; - -// OPENSEARCH -export { _OPEN_HOST as OPEN_HOST }; -export { _OPEN_CORE as OPEN_CORE }; +export { _SOLR_HOST as SOLR_HOST }; +export { _SOLR_CORE as SOLR_CORE }; diff --git a/src/models/dataset.ts b/src/models/dataset.ts index 9df56f3..0ec4832 100644 --- a/src/models/dataset.ts +++ b/src/models/dataset.ts @@ -1,92 +1,72 @@ // import moment from "moment"; import dayjs from "dayjs"; -// // SOLR Dataset original -// export interface Dataset { -// abstract_additional: Array;// OpenSearch: abstract: Array -// abstract_output: string;// ----- -// author: Array;// EQUAL -// author_sort: Array;// ----- -// belongs_to_bibliography: boolean;// EQUAL -// creating_corporation: string;// EQUAL -// doctype: string;// EQUAL -// geo_location: string;// EQUAL -// id: number;// EQUAL -// identifier: Identifier;// OpenSearch: identifier: Array -// language: string;// EQUAL -// licence: string;// EQUAL -// publisher_name: string;// EQUAL -// server_date_published: Array;// OpenSearch not array! -// subject: Array;// OpenSearch: subjectS -// title_output: string;// EQUAL -// year: number;// EQUAL -// year_inverted: number;// EQUAL -// } - -// OpenSearch Dataset export interface Dataset { - abstract: Array;// OpenSearch: abstract: Array - // abstract_output: string;// ----- NOT in OpenSearch - author: Array;// EQUAL - // author_sort: Array;// ----- NOT in OpenSearch - belongs_to_bibliography: boolean;// EQUAL - creating_corporation: string;// EQUAL - doctype: string;// EQUAL - geo_location: string;// EQUAL - id: number;// EQUAL - // identifier: Identifier;// OpenSearch: identifier: Array - identifier: Array// DIFF DATATYPE - language: string;// EQUAL - licence: string;// EQUAL - publisher_name: string;// EQUAL - // server_date_published: Array;// OpenSearch string! - server_date_published: string;// DIFF DATATYPE - // subject: Array;// OpenSearch: subjectS - subjects: Array;// DIFF DATATYPE - title_output: string;// EQUAL - year: number;// EQUAL - year_inverted: number;// EQUAL - - title: string // Unique in OpenSearch - title_additional: Array // Unique in OpenSearch - bbox_xmin: string // Unique in OpenSearch - bbox_xmax: string // Unique in OpenSearch - bbox_ymin: string // Unique in OpenSearch - bbox_ymax: string // Unique in OpenSearch - reference: Array // Unique in OpenSearch - abstract_additional: Array;// Unique in OpenSearch + abstract_additional: Array; + abstract_output: string; + author: Array; + author_sort: Array; + belongs_to_bibliography: boolean; + creating_corporation: string; + doctype: string; + geo_location: string; + id: number; + identifier: Identifier; + language: string; + licence: string; + publisher_name: string; + server_date_published: Array; + subject: Array; + title_output: string; + year: number; + year_inverted: number; } - export class Suggestion { constructor( - public value: string, // Store the text value returned by OpenSearch - // Store the highlight: i.e. the text value with the emphasised term that generated that results by OpenSearch. - // In this way we can highlight the real term existing in the publication independently of how different was the inserted term used for the FUZZY search. e.g. "Vien" fuzzy matched with "Wien" - public highlight: string, - public type: SearchType, // Type of search element + public value: string, + public type: SearchType, ) {} // value!: string; // type!: SearchType; } -// export class Suggestion { -// constructor( -// public value: string, -// public type: SearchType, -// ) {} -// // value!: string; -// // type!: SearchType; -// } - export enum SearchType { Title = "title", Author = "author", - Subject = "subjects", // ** !! The field has this name in OpenSearch!! - Doctype = "doctype" + Subject = "subject", } export class DbDataset { + // public id!: number; + // public url!: string; + // public contributing_corporation!: string; + // public creating_corporation!: string; + // public publisher_name!: string; + // public embargo_date!: string; + // public publish_id!: number; + // public project_id!: number; + // public type!: string; + // public language!: string; + // public server_state!: string; + // public belongs_to_bibliography!: boolean; + // public created_at!: string; + // public server_date_modified!: string; + // public server_date_published!: string; + // public account_id!: number; + // public editor_id!: number; + // public reviewer_id!: number; + // public preferred_reviewer!: number; + // public preferred_reviewer_email!: string; + // public reject_editor_note!: string; + // public reject_reviewer_note!: string; + // public reviewer_note_visible!: string; + // public titles!: Array; + // public abstracts!: Array<Abstract>; + // public authors!: Array<Author>; + // public contributors!: Array<Author>; + // public user!: Person; + // public subjects!: Array<Subject>; constructor( public id: string, @@ -235,31 +215,17 @@ export class DbDataset { const yMax = this.coverage.y_max; // const elevationAbsolut = this.coverage.elevation_absolut; - // let geoLocation = - // "- SOUTH-BOUND LATITUDE: " + - // yMin + - // "\n" + - // "- WEST-BOUND LONGITUDE: " + - // xMin + - // "\n" + - // "- NORTH-BOUND LATITUDE: " + - // yMax + - // "\n" + - // "- EAST-BOUND LONGITUDE: " + - // xMax; - let geoLocation = - // "- SOUTH-BOUND LATITUDE: " + - "- South-bound Latitude: " + + "* SOUTH-BOUND LATITUDE: " + yMin + "\n" + - "- West-bound Longitude: " + + "* WEST-BOUND LONGITUDE: " + xMin + "\n" + - "- North-bound Latitude: " + + "* NORTH-BOUND LATITUDE: " + yMax + "\n" + - "- East-bound Longitude: " + + "* EAST-BOUND LONGITUDE: " + xMax; // geoLocation += elevationAbsolut != null ? ` * ELEVATION ABSOLUT: ${elevationAbsolut}\n` : ""; @@ -268,66 +234,32 @@ export class DbDataset { let elevation = ""; if (this.coverage.elevation_max != null && this.coverage.elevation_min != null) { - // elevation += "\n- ELEVATION MIN: " + this.coverage.elevation_min + " \n- ELEVATION MAX: " + this.coverage.elevation_max; - elevation += "\n- Elevation Min.: " + this.coverage.elevation_min + " m\n- Elevation Max.: " + this.coverage.elevation_max + " m"; + elevation += "\n* ELEVATION MIN: " + this.coverage.elevation_min + " *\nELEVATION MAX: " + this.coverage.elevation_max; } if (this.coverage.elevation_absolut != null) { - elevation += "\n- Elevation Absolut: " + this.coverage.elevation_absolut + " m"; + elevation += "\n* ELEVATION ABSOLUT: " + this.coverage.elevation_absolut; } - // if (elevation != "") geoLocation += ("\n---" + elevation); + if (elevation != "") geoLocation += elevation; let depth = ""; if (this.coverage.depth_max != null && this.coverage.depth_min != null) { - depth += "\n- Depth Min.: " + this.coverage.depth_min + " m\n- Depth Max.: " + this.coverage.depth_max + " m"; + depth += "\n* DEPTH MIN: " + this.coverage.depth_min + "\n* DEPTH MAX: " + this.coverage.depth_max; } if (this.coverage.elevation_absolut != null) { - depth += "\n- Depth Absolut: " + this.coverage.depth_absolut + " m"; + depth += "\n* DEPTH ABSOLUT: " + this.coverage.depth_absolut; } - // if (depth != "") geoLocation += depth; + if (depth != "") geoLocation += depth; let time = ""; if (this.coverage.time_max != null && this.coverage.time_min != null) { - time += "\n- Time Min.: " + this.coverage.time_min + "\n- Time Max.: " + this.coverage.time_max; + time += "\n* TIME MIN: " + this.coverage.time_min + "\n* TIME MAX: " + this.coverage.time_max; } if (this.coverage.time_absolut != null) { - time += "\n- Time Absolut: " + this.coverage.time_absolut; + time += "\n* TIME ABSOLUT: " + this.coverage.time_absolut; } - // if (time != "") geoLocation += time; + if (time != "") geoLocation += time; - // let elevation = ""; - // if (this.coverage.elevation_max != null && this.coverage.elevation_min != null) { - // elevation += "\n* ELEVATION MIN: " + this.coverage.elevation_min + " \n* ELEVATION MAX: " + this.coverage.elevation_max; - // } - // if (this.coverage.elevation_absolut != null) { - // elevation += "\n* ELEVATION ABSOLUT: " + this.coverage.elevation_absolut; - // } - // if (elevation != "") geoLocation += elevation; - - // let depth = ""; - // if (this.coverage.depth_max != null && this.coverage.depth_min != null) { - // depth += "\n* DEPTH MIN: " + this.coverage.depth_min + "\n* DEPTH MAX: " + this.coverage.depth_max; - // } - // if (this.coverage.elevation_absolut != null) { - // depth += "\n* DEPTH ABSOLUT: " + this.coverage.depth_absolut; - // } - // if (depth != "") geoLocation += depth; - - // let time = ""; - // if (this.coverage.time_max != null && this.coverage.time_min != null) { - // time += "\n* TIME MIN: " + this.coverage.time_min + "\n* TIME MAX: " + this.coverage.time_max; - // } - // if (this.coverage.time_absolut != null) { - // time += "\n* TIME ABSOLUT: " + this.coverage.time_absolut; - // } - // if (time != "") geoLocation += time; - - if (elevation != "" || depth != "" || time != "" ) { - return geoLocation + "\n ---" + elevation + depth + time; - } else { - return geoLocation + elevation + depth + time; - } - - // return geoLocation; + return geoLocation; } else { return ""; } diff --git a/src/models/headers.ts b/src/models/headers.ts index 82c5423..d7cac90 100644 --- a/src/models/headers.ts +++ b/src/models/headers.ts @@ -18,6 +18,19 @@ export interface ResponseHeaderParams { rows?: number; start?: number; wt?: string; + + // 0:'fl=id,licence,server_date_published,abstract_output,identifier,title_output,title_additional,author,subject,doctype' + + // df:'title' + // facet:'on' + // indent:'on' + // json.facet.language:'{ type: "terms", field: "language" }' + // json.facet.subject:'{ type: "terms", field: "subject" }' + // q:'title:Geodaten - Blatt 49 Wels (1:50.000)' + // q.op:'and' + // rows:'10' + // start:'0' + // wt:'json' } export interface ResponseContent { @@ -26,21 +39,36 @@ export interface ResponseContent { docs: Array<Dataset>; } -//Used +// export interface FacetCount { +// facet_fields: FacetCategory<any>; +// } + +// export class FacetCategory<T> { + +// [key: string]: { +// values: T[]; +// }; +// } + export class FacetResults { + // language!: Array<FacetItem>; + // subject!: Array<FacetItem>; [key: string]: Array<FacetItem>; } +//#region solr response facets export class FacetFields { + // count: number; language!: FacetInstance; subject!: FacetInstance; + // [key: string]: FacetInstance; } export interface FacetInstance { [key: string]: Array<FacetItem>; + // buckets: Array<FacetItem>; } -//Used export class FacetItem { val: string; count: number; @@ -55,85 +83,3 @@ export class FacetItem { } } //#endregion - -// OPENSEARCH -// ======================================================================== -export interface OpenSearchResponse { - took: number; - timed_out: boolean; - _shards: Shards; - hits: Hits; // Equivalent SOLR: response > docs - aggregations?: Aggregations; // Equivalent SOLR: facets -} - -export interface Shards { - total: number; - successful: number; - skipped: number; - failed: number; -} - -export interface Hits { - total: Total; - max_score: number; - hits: Array<Hit>; -} - -export interface Total { - value: number; // Equivalent SOLR: response > numFound - relation: string; -} - -export interface Hit { - _index: string; - _id: string; - _score: number; - _source: Dataset; - highlight: HitHighlight; // !! This name is to avoid collision with Typescript "Highlight" class -} - -export interface HitHighlight { - subjects?: Array<string>; - title?: Array<string>; - author?: Array<string>; - doctype?: Array<string>; -} - -export interface Aggregations { // Equivalent SOLR: FacetFields - subjects: Subjects; - language: Language; - doctype: Doctype; -} - -export interface Subjects { - doc_count_error_upper_bound: number; - sum_other_doc_count: number; - buckets: Array<Bucket>; -} - -export interface Language { - doc_count_error_upper_bound: number; - sum_other_doc_count: number; - buckets: Array<Bucket>; -} - -export interface Doctype { - doc_count_error_upper_bound: number; - sum_other_doc_count: number; - buckets: Array<Bucket>; -} - -export interface Bucket { - key: string; - doc_count: number; -} -// // Needed? -// export interface Aggregations { -// [key: string]: Aggregation; -// } - -// export interface Aggregation { -// buckets: Array<Bucket>; -// } - - diff --git a/src/models/solr.ts b/src/models/solr.ts index d850e71..3e87ca2 100644 --- a/src/models/solr.ts +++ b/src/models/solr.ts @@ -1,9 +1,4 @@ -// export interface SolrSettings { -// core: string; -// host: string; -// } - -export interface OpenSettings { +export interface SolrSettings { core: string; host: string; } diff --git a/src/services/dataset.service - Tests with OpenSearch b/src/services/dataset.service - Tests with OpenSearch deleted file mode 100644 index db453f0..0000000 --- a/src/services/dataset.service - Tests with OpenSearch +++ /dev/null @@ -1,161 +0,0 @@ - // public facetedSearchOPEN( - // suggestion: Suggestion | string, - // activeFilterCategories: ActiveFilterCategories, - // openCore: string, - // openHost: string, - // start?: string, // Starting page - // ): Observable<OpenSearchResponse> { - // // OpenSearch endpoint - // const host = openHost; - // const path = "/" + openCore + "/_search"; - // const base = host + path; - - // // Constructing Filters Based on Active Filter Categories - // const filters = Object.entries(activeFilterCategories).map(([category, values]) => { - // if (category === "language" || category === "year") { - // return { terms: { [category]: values } }; - // } else { - // return { terms: { [`${category}.keyword`]: values } }; - // } - // }); - // console.log("filters:", filters); - - // // Determine search term and query fields based on the suggestion type - // let query; - // if (typeof suggestion === "string") { // If suggestion is a string, append a wildcard (*) for partial matches - // const lowercaseTerm = suggestion.toLowerCase() - // query = { - // bool: { - // should: [ - // { match: { title: { query: suggestion, fuzziness: "AUTO", boost: 3 } } }, - // { match: { author: { query: suggestion, fuzziness: "AUTO", boost: 2 } } }, - // { match: { subjects: { query: suggestion, fuzziness: "AUTO", boost: 1 } } }, - // { wildcard: { title: { value: `${lowercaseTerm}*`, boost: 3 } } }, - // { wildcard: { author: { value: `${lowercaseTerm}*`, boost: 2 } } }, - // { wildcard: { subjects: { value: `${lowercaseTerm}*`, boost: 1 } } } - // ], - // minimum_should_match: 1 - // } - // }; - // } else if (suggestion instanceof Suggestion) { // If suggestion is a Suggestion object, form a specific query - // query = { - // match: { - // [suggestion.type]: { - // query: suggestion.value, - // operator: 'and' // all the terms in the query must be present in the field e.g. if is a title, the complete title - // } - // } - // }; - // } - - // // Set default value for start if not provided - // const startValue = start ? parseInt(start) : 0; - - // // console.log(activeFilterCategories); - // // console.log("mainQuery:", mainQuery); - - // // Construct the body of the OpenSearch query - // const body = { - - // query: { - // bool: { - // must: [ - // mainQuery, // Ensure the main query must be satisfied - // ...filters // Ensure all filters must be satisfied - // ] - // } - // }, - - // // // WORKS // Expected: 12 results - // // query: { - // // bool: { - // // "must": [ - // // { "term": { "language": "en" } }, - // // { "term": { "subjects.keyword": "Lower Austria" } }, - // // { "term": { "subjects.keyword": "counting data" } } - // // ], - // // } - // // }, - - // // // THIS WORKS: // Expected: 19 results - // // query: { - // // bool: { - // // must: [ - // // { "match": { "title": "Blatt" } }, - // // { "term": { "subjects": "bayern" } } - // // ], - // // } - // // }, - - // // // WORKS // Expected: 4 results - // // query: { - // // bool: { - // // "must": [ - // // { "match": { "title": "blatt" } }, - // // { "term": { "subjects": "bayern" } }, - // // { "term": { "subjects": "salzburg" } } - // // ], - // // } - // // }, - - // // // WORKS // Expected: 2 results - // // query: { - // // bool: { - // // "must": [ - // // { "match": { "title": "blatt" } }, - // // { "term": { "subjects": "ungarn" } }, - // // { "term": { "subjects": "steiermark" } } - // // ], - // // } - // // }, - - // // WORKS // Expected: 12 results - // query: { - // bool: { - // "must": [ - // { "term": { "language": "en" } }, - // { "term": { "subjects.keyword": "Lower Austria" } }, - // { "term": { "subjects.keyword": "counting data" } } - // ], - // "should": [ - // { match: { title: { query: "halger", fuzziness: "AUTO", boost: 3 } } }, - // { match: { author: { query: "halger", fuzziness: "AUTO", boost: 2 } } }, - // { match: { subjects: { query: "halger", fuzziness: "AUTO", boost: 1 } } }, - // { wildcard: { title: { value: "halger", boost: 3 } } }, - // { wildcard: { author: { value: "halger", boost: 2 } } }, - // { wildcard: { subjects: { value: "halger", boost: 1 } } } - // ], - // minimum_should_match: 1 - // } - // }, - - // size: 10, - // from: startValue, - // sort: [{ _score: { order: "desc" } }], - // track_scores: true, - - // aggs: { - // subjects: { terms: { field: "subjects.keyword", size: 1000 } }, - // language: { terms: { field: "language" } }, - // author: { terms: { field: "author.keyword", size: 1000 } }, - // year: { terms: { field: "year", size: 100 } } - // }, - - // highlight: { - // fields: { - // title: {}, - // author: {}, - // subjects: {} - // } - // } - // }; - - // console.log("mainQuery:", mainQuery); - // console.log("filters:", filters); - // console.log("body:", body); - - // // Make API call to OpenSearch and return the result - // const stations = api.post<OpenSearchResponse>(base, body); - - // return stations; - // } diff --git a/src/services/dataset.service.ts b/src/services/dataset.service.ts index c897b29..4643ea9 100644 --- a/src/services/dataset.service.ts +++ b/src/services/dataset.service.ts @@ -1,386 +1,361 @@ import api from "../api/api"; +// import { Observable, of } from "rxjs"; import { Observable } from "rxjs"; -import { tap, map } from "rxjs/operators"; +import { map } from "rxjs/operators"; import { Dataset, DbDataset, Suggestion } from "@/models/dataset"; -import { HitHighlight, OpenSearchResponse, SolrResponse } from "@/models/headers"; +import { SolrResponse } from "@/models/headers"; import { ActiveFilterCategories } from "@/models/solr"; import { VUE_API } from "@/constants"; +// import { deserialize, instanceToInstance } from "class-transformer"; import { deserialize } from "class-transformer"; +// import { OAI_DATASETS } from "./mock-oai-datasets"; +// import { OaiDataset, OaiPerson } from "@/models/oai"; +// import xml2js from "xml2js"; class DatasetService { - /** - * Search datasets with OpenSearch API, allowing for fuzzy search and boosting relevance in title, author, and subject fields. - * @param {string} searchTerm - Search query term - * @param {string} openCore - The OpenSearch core to search in - * @param {string} openHost - The OpenSearch host URL - * @returns {Observable} - Observable emitting datasets and their highlights - */ - public searchTerm(term: string, openCore: string, openHost: string): Observable<{ datasets: Dataset[], highlights: HitHighlight[] }> { + // for the autocomplete search + public searchTerm(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> { + // solr endpoint + // const host = 'http://voyagerdemo.com/'; + // const host = 'https://www.tethys.at/';'' + const host = "https://" + solrHost; + const path = "/solr/" + solrCore + "/select?"; + // const base = "https://geomon.geologie.ac.at/52n-sos-webapp/api/features"; //host + path; + const base = host + path; - const host = openHost; // OpenSearch host URL - const path = "/" + openCore + "/_search"; // API endpoint for searching - const base = host + path; // Complete URL for the request - /** - * The match query used for title, author, and subjects fields is case-insensitive by default. The standard analyzer is typically used, which lowercases the terms. - * The wildcard query is case-sensitive by default. To make it case-insensitive, it is needed to use a lowercase filter */ - const lowercaseTerm = term.toLowerCase(); // Lowercase the search term - - // Request body defining search query logic - const body = { - query: { - bool: { - should: [ - { match: { title: { query: term, fuzziness: "AUTO", boost: 3 } } }, - { match: { author: { query: term, fuzziness: "AUTO", boost: 2 } } }, - { match: { subjects: { query: term, fuzziness: "AUTO", boost: 1 } } }, // In SOLR is "subject"! - { match: { doctype: { query: term, fuzziness: "AUTO", boost: 1 } } }, // doctype - { wildcard: { title: { value: `${lowercaseTerm}*`, boost: 3 } } }, - { wildcard: { author: { value: `${lowercaseTerm}*`, boost: 2 } } }, - { wildcard: { subjects: { value: `${lowercaseTerm}*`, boost: 1 } } }, // In SOLR is "subject"! - { wildcard: { doctype: { value: `${lowercaseTerm}*`, boost: 1 } } } // doctype - ], - minimum_should_match: 1 // Require at least one match - } - }, - size: 10, // Limit to 10 results - from: 0, // Pagination: start from the first result - sort: [{ _score: { order: "desc" } }], // Sort by relevance (_score) - // sort: [{ server_date_published: { order: "desc" } }], - track_scores: true, // This ensures "_score" is included even when sorting by other criteria. Otherwise the relevance score is not calculated - aggs: { - subjects: { terms: { field: "subjects.keyword", size: 1000 } }, // In SOLR is "subject"! - language: { terms: { field: "language" } }, // << ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - author: { terms: { field: "author.keyword", size: 1000 } }, - year: { terms: { field: "year", size: 100 } }, // << ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - doctype: { terms: { field: "doctype", size: 50 } } // << ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - }, - highlight: { - fields: { - title: {}, // Highlight matching terms in title - author: {}, // Highlight matching terms in author - subjects: {}, // Highlight matching terms in subjects - doctype: {} // Highlight matching terms in document type - } - } + //const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned + const fields = [ + "id", + "licence", + "server_date_published", + "abstract_output", + "title_output", + "title_additional", + "author", + "subject", + "doctype", + ].toString(); + + //var dismaxFields = "title^3 abstract^2 subject^1"; + const qfFields = "title^3 author^2 subject^1"; + // let params = "fl=" + fields; + // // if (term == "*%3A*") { // *: + // // params += "&defType=edismax&wt=json&indent=on"; //edismax + // // } else { + // params += "&defType=edismax&qf=" + qfFields + "&wt=json&indent=on"; //dismax + // // } + + // const query = "&q=" + term + "*"; + // const apiU = base + params + query; + + const q_params = { + "0": "fl=" + fields, + q: term + "*", + defType: "edismax", + qf: qfFields, + indent: "on", + wt: "json", }; - /** - * Make API call to OpenSearch and return the result - * When a POST request is made to the OpenSearch server using the api.post<OpenSearchResponse> method, the response received from OpenSearch is an object that includes various details about the search results. - * One of the key properties of this response object is _source, which is an array of documents (datasets) that match the search criteria. - * It is used the pipe method to chain RxJS operators to the Observable returned by api.get. The map operator is used to transform the emitted items of the Observable. - */ - return api.post<OpenSearchResponse>(base, body).pipe( - map(response => ({ - datasets: response.hits.hits.map(hit => hit._source), - highlights: response.hits.hits.map(hit => hit.highlight) - })) - ); + const stations = api.get<SolrResponse>(base, q_params).pipe(map((res: SolrResponse) => res.response.docs)); + + return stations; } - // // For the autocomplete search. Method to perform a search based on a term - // public searchTermSOLR(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> { - // // SOLR endpoint - // const host = "https://" + solrHost; - // const path = "/solr/" + solrCore + "/select?"; - // const base = host + path; - - // //const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned - // const fields = [ - // "id", - // "licence", - // "server_date_published", - // "abstract_output", - // "title_output", - // "title_additional", - // "author", - // "subject", - // "doctype", - // ].toString(); - - // const qfFields = "title^3 author^2 subject^1"; - - // const q_params = { - // "0": "fl=" + fields, - // q: term + "*", - // defType: "edismax", - // qf: qfFields, - // indent: "on", - // wt: "json", - // }; - - // // Make API call to Solr and return the result - // /** - // * When a GET request is made to the Solr server using the api.get<SolrResponse> method, the response received from Solr is an object that includes various details about the search results. - // * One of the key properties of this response object is docs, which is an array of documents (datasets) that match the search criteria. - // * It is used the pipe method to chain RxJS operators to the Observable returned by api.get. The map operator is used to transform the emitted items of the Observable. - // */ - // const stations = api.get<SolrResponse>(base, q_params).pipe(map((res: SolrResponse) => res.response.docs)); - - // return stations; - // } - - - /** - * Perform faceted search with OpenSearch API using filters and suggestions - * @param {Suggestion | string} suggestion - Search term or suggestion - * @param {ActiveFilterCategories} activeFilterCategories - Active filters to apply - * @param {string} openCore - The OpenSearch core to search in - * @param {string} openHost - The OpenSearch host URL - * @param {string} start - Optional: starting page - * @returns {Observable<OpenSearchResponse>} - Observable emitting search results - */ public facetedSearch( suggestion: Suggestion | string, activeFilterCategories: ActiveFilterCategories, - openCore: string, - openHost: string, - start?: string, // Starting page - ): Observable<OpenSearchResponse> { - const host = openHost; - const path = "/" + openCore + "/_search"; + solrCore: string, + solrHost: string, + start?: string, + ): Observable<SolrResponse> { + // solr endpoint + // const host = 'http://voyagerdemo.com/'; + //const host = 'https://www.tethys.at/'; + //const host = 'https://' + solrHost; + const host = "https://" + solrHost; + const path = "/solr/" + solrCore + "/select?"; const base = host + path; - - const lowercaseTerm = typeof suggestion === 'string' ? suggestion.toLowerCase() : suggestion.value; - - /** - * The query construction depends on whether the suggestion is a string or a Suggestion object. - * */ - - // When suggestion is a string: - const mainQuery = typeof suggestion === 'string' - ? { - bool: { - should: [ - { match: { title: { query: suggestion, fuzziness: "AUTO", boost: 3 } } }, - { match: { author: { query: suggestion, fuzziness: "AUTO", boost: 2 } } }, - { match: { subjects: { query: suggestion, fuzziness: "AUTO", boost: 1 } } }, - { match: { doctype: { query: suggestion, fuzziness: "AUTO", boost: 1 } } }, - { wildcard: { title: { value: `${lowercaseTerm}*`, boost: 3 } } }, - { wildcard: { author: { value: `${lowercaseTerm}*`, boost: 2 } } }, - { wildcard: { subjects: { value: `${lowercaseTerm}*`, boost: 1 } } }, - { wildcard: { doctype: { value: `${lowercaseTerm}*`, boost: 1 } } } - ], - minimum_should_match: 1 - } - } - // When suggestion is a suggestion object: - : { - match: { - [suggestion.type]: { - query: suggestion.value, - operator: 'and' // all the terms in the query must be present in the field - } - } - }; - - // Build filters based on the active filter categories - const filters = Object.entries(activeFilterCategories).map(([category, values]) => { - if (category === "language" || category === "year" || category === "doctype") { - return values.map(value => ({ term: { [category]: value } })); - } else { - return values.map(value => ({ term: { [`${category}.keyword`]: value } })); - } - }).flat(); - // Request body for the faceted search - const body = { - query: { - bool: { - must: [ - mainQuery, // Ensure the main query must be satisfied - ...filters // Ensure all filters must be satisfied - ] - } - }, + //const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned + const fields = [ + "id", + "licence", + "server_date_published", + "abstract_output", + "identifier", + "title_output", + "title_additional", + "author", + "subject", + "doctype", + ].toString(); - size: 10, - from: start ? parseInt(start) : 0, - sort: [{ server_date_published: { order: "desc" } }], // Sort by publication date - // sort: [{ _score: { order: "desc" } }], // Sort by _score in descending order - track_scores: true, - /** - * Defines aggregations for facets - * terms: Aggregation type that returns the most common terms in a field. - * !For a large number of terms setting an extremely large size might not be efficient - * If you genuinely need all unique terms and expect a large number of them, consider using a composite aggregation for more efficient pagination of terms. - */ - aggs: { - subjects: { terms: { field: "subjects.keyword", size: 1000 } }, // In SOLR is "subject"! - language: { terms: { field: "language" } }, // ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - author: { terms: { field: "author.keyword", size: 1000 } }, - year: { terms: { field: "year", size: 100 } }, // ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - doctype: { terms: { field: "doctype", size: 50 } } // ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS - }, - highlight: { - fields: { - title: {}, - author: {}, - subjects: {}, - doctype: {} - } + // const qfFields = "title^3 author^2 subject^1"; + // let params = "fl=" + fields; + // if (term == "*%3A*") { + // params += "&defType=edismax&wt=json&indent=on"; //edismax + // } else { + // params += "&defType=dismax&qf=" + qfFields + "&wt=json&indent=on"; //dismax + // } + + let term, queryOperator, qfFields; + if (typeof suggestion === "string") { + term = suggestion + "*"; + queryOperator = "or"; + qfFields = "title^3 author^2 subject^1"; + } else if (suggestion instanceof Suggestion) { + term = suggestion.type + ':"' + suggestion.value + '"'; + queryOperator = "and"; + qfFields = undefined; + } + + if (start === undefined) start = "0"; + // start = "&start=" + start; + + // const facetFields = + // "&facet=on&facet.field=language&facet.field={!key=datatype}doctype&facet.field=subject"; //&fq=year:(2019)";//&facet.query=year:2018"; + + const filterFields = new Array<string>(); + if (Object.keys(activeFilterCategories).length > 0) { + // filterFields = '["'; + // const filterFields: string[] = []; + // const facet_fields: FacetFields = res.facets; + let prop: keyof typeof activeFilterCategories; + for (prop in activeFilterCategories) { + const filterItems = activeFilterCategories[prop]; + // const filterItems = facetCategory.values; + // filterItems.forEach((filterItem) => { + // console.log(`${key} ${valueArray}`); + filterItems.forEach(function (value: string) { + // filterFields += "&fq=" + key + ':("' + value + '")'; + filterFields.push(prop + ':("' + value + '")'); + // filterFields += prop + ":" + value; + }); } + // filterFields += '"]'; + } + // const query = "&sort=server_date_published desc" + "&q=" + term; + + // const api = + // base + params + limit + start + query + filterFields + facetFields; + + // https://solr.apache.org/guide/8_4/json-request-api.html + const q_params = { + "0": "fl=" + fields, + q: term, + "q.op": queryOperator, + defType: "edismax", + qf: qfFields, + // df: "title", + indent: "on", + wt: "json", + rows: 10, + // fq: ["subject:Steiermark", "language:de"], + fq: filterFields, + start: start, + sort: "server_date_published desc", + facet: "on", + // "facet.field": "language", + "json.facet.language": '{ type: "terms", field: "language" }', + "json.facet.subject": '{ type: "terms", field: "subject", limit: -1 }', + "json.facet.year": '{ type: "terms", field: "year" }', + "json.facet.author": '{ type: "terms", field: "author_facet", limit: -1 }', }; - - // API call and return observable of search results - const stations = api.post<OpenSearchResponse>(base, body); + + const stations = api.get<SolrResponse>(base, q_params); + // .pipe(map((res) => res.response.docs)); + return stations; } - - // /** - // * This method performs a faceted search on a Solr core. Faceted search allows the user to filter search results based on various categories (facets) - // */ - // public facetedSearchSOLR( - // suggestion: Suggestion | string, - // activeFilterCategories: ActiveFilterCategories, - // solrCore: string, - // solrHost: string, - // start?: string, // Starting page - // ): Observable<SolrResponse> { - // // console.log("face:", suggestion); - // // console.log(activeFilterCategories); - // // console.log(solrCore); - // // console.log(solrHost); - // // console.log(start); - - // console.log("facetedsearchSOLR > suggestion entered:"); - // console.log(suggestion); - // // Construct Solr query parameters - // const host = "https://" + solrHost; - // const path = "/solr/" + solrCore + "/select?"; - // const base = host + path; - - // const fields = [ - // "id", - // "licence", - // "server_date_published", - // "abstract_output", - // "identifier", - // "title_output", - // "title_additional", - // "author", - // "subject", - // "doctype", - // ].toString(); - - // // Determine search term, query operator, and query fields based on the suggestion type. Depending on whether suggestion is a string or a Suggestion object, it constructs the search term and query fields differently. - // let term, queryOperator, qfFields; - // if (typeof suggestion === "string") { // f suggestion is a string, it appends a wildcard (*) for partial matches. - // term = suggestion + "*"; - // queryOperator = "or"; - // qfFields = "title^3 author^2 subject^1"; - // } else if (suggestion instanceof Suggestion) { // If suggestion is a Suggestion object, it forms a more specific query based on the type and value of the suggestion. - // term = suggestion.type + ':"' + suggestion.value + '"'; - // queryOperator = "and"; - // qfFields = undefined; - // } - - // // Set default value for start if not provided - // if (start === undefined) start = "0"; - - // // Construct filter fields based on active filter categories - // const filterFields = new Array<string>(); - // if (Object.keys(activeFilterCategories).length > 0) { - // /* Declare variable prop with a type that is a key of the activeFilterCategories. The 'keyof typeof' activeFilterCategories type represents all possible keys - // that can exist on the activeFilterCategories --> prop can only be assigned a value that is a key of the activeFilterCategories object */ - // let prop: keyof typeof activeFilterCategories; - // for (prop in activeFilterCategories) { - // const filterItems = activeFilterCategories[prop]; - // filterItems.forEach(function (value: string) { - // filterFields.push(prop + ':("' + value + '")'); - // // e.g. Array [ 'subject:("Vektordaten")', 'author:("GeoSphere Austria, ")' ] - // }); - // } - // } - - // // https://solr.apache.org/guide/8_4/json-request-api.html - // // Construct Solr query parameters - // const q_params = { - // "0": "fl=" + fields, - // q: term, - // "q.op": queryOperator, - // defType: "edismax", - // qf: qfFields, - // // df: "title", - // indent: "on", - // wt: "json", - // rows: 10, - // // fq: ["subject:Steiermark", "language:de"], - // fq: filterFields, - // start: start, - // sort: "server_date_published desc", - // facet: "on", - // // "facet.field": "language", - // "json.facet.language": '{ type: "terms", field: "language" }', - // "json.facet.subject": '{ type: "terms", field: "subject", limit: -1 }', - // "json.facet.year": '{ type: "terms", field: "year" }', - // "json.facet.author": '{ type: "terms", field: "author_facet", limit: -1 }', - // }; - // /* E.g. - // {"0":"fl=id,licence,server_date_published,abstract_output,identifier,title_output,title_additional,author,subject,doctype","q":"*","q.op":"or","defType":"edismax", - // "qf":"title^3 author^2 subject^1", - // "indent":"on","wt":"json","rows":10, - // "fq":["subject:(\"Vektordaten\")","author:(\"GeoSphere Austria, \")"], - // "start":"0","sort":"server_date_published desc","facet":"on", - // "json.facet.language":"{ type: \"terms\", field: \"language\" }", - // "json.facet.subject":"{ type: \"terms\", field: \"subject\", limit: -1 }", - // "json.facet.year":"{ type: \"terms\", field: \"year\" }", - // "json.facet.author":"{ type: \"terms\", field: \"author_facet\", limit: -1 }"} - // */ - // // console.log(JSON.stringify(q_params)); - - // // Make API call to Solr and return the result - // const stations = api.get<SolrResponse>(base, q_params); - - // return stations; - // } - - // Method to fetch years public getYears(): Observable<string[]> { + // const heroes = of(HEROES); + // const host = "https:" + VUE_API; const host = VUE_API; const path = "/api/years"; const base = host + path; const years = api.get<string[]>(base); + // this.messageService.add('HeroService: fetched heroes'); return years; } - // Method to fetch documents for a specific year public getDocuments(year: string): Observable<Array<DbDataset>> { + // const host = "https:" + VUE_API; const host = VUE_API; const path = "/api/sitelinks/" + year; const base = host + path; const documents: Observable<DbDataset[]> = api.get<Array<DbDataset>>(base); + // this.messageService.add('HeroService: fetched heroes'); return documents; } - // Method to fetch a dataset by its ID public getDataset(id: number): Observable<DbDataset> { + // const host = "https:" + VUE_API; const host = VUE_API; const path = "/api/dataset/" + id; const apiUrl = host + path; - const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res))); + // const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res, apiUrl))); + + // this.messageService.add('HeroService: fetched heroes'); return dataset; } - // Method to fetch a dataset by its DOI public getDatasetByDoi(doi: string): Observable<DbDataset> { + // const host = "https:" + VUE_API; const host = VUE_API; const path = "/api/dataset/10.24341/tethys." + doi; const apiUrl = host + path; - const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res))); + // const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res, apiUrl))); + + // this.messageService.add('HeroService: fetched heroes'); return dataset; } - // Prepare dataset object by deserializing it and adding a URL - private prepareDataset(datasetObj: DbDataset): DbDataset { + // public getOaiDatasets(): Observable<OaiDataset[]> { + // const apiUrl = "https://data.tethys.at/oai?verb=ListRecords&metadataPrefix=oai_datacite"; + // const oaiDatasets = api.get<string>(apiUrl).pipe( + // map( + // (response: string) => { + // // const parser = new DOMParser(); + // // const xmlDoc: XMLDocument = parser.parseFromString(response, "application/xml"); + // // const xslDoc = parser.parseFromString(this.xsl, "application/xml"); + // // const xsltProcessor = new XSLTProcessor(); + // // xsltProcessor.importStylesheet(xslDoc); + // // console.log(xmlDoc); + // // const xmlDom = xsltProcessor.transformToDocument(xmlDoc); + + // // const serializer = new XMLSerializer(); + // // const html = serializer.serializeToString(xmlDom.documentElement); + // // console.log(html); + + // // const arrOai = new Array<OaiDataset>(); + // // return arrOai; + // const arrOai = this.parseXML(response); + // return arrOai; + // // .then((data) => { + // // return data; + // // }); + // }, + // // (error: string) => this.errorHandler(error), + // ), + // ); + // // const oaiDatasets = of(OAI_DATASETS); + + // // this.messageService.add('HeroService: fetched heroes'); + // return oaiDatasets; + // } + + // private parseXML(xmlStr: string): Array<OaiDataset> { + // // let k = ""; + // const arr: OaiDataset[] = []; + // const domParser = new DOMParser(); + // const doc = domParser.parseFromString(xmlStr, "application/xml"); + // const records = doc.getElementsByTagName("ListRecords")[0]; + // // // const rt = xmlNode.resumptionToken; + // // for (let i = 0; i < records.length; i++) { + // // console.log(records[i].getAttribute("name")); + // // } + + // const parser: xml2js.Parser = new xml2js.Parser({ + // trim: true, + // explicitArray: false, + // ignoreAttrs: false, + // // mergeAttrs: true, + // }); + // parser.parseString(records.outerHTML, function (err: Error | null, result: any) { + // const xmlNode = result.ListRecords; + // // const rt = xmlNode.resumptionToken; + // for (const rNode in xmlNode.record) { + // const item = xmlNode.record[rNode]; + + // const dc = item.metadata.resource; + // const t = dc.titles.title; + // const id = dc.identifier._; + + // const lang = "en"; //dc.titles.title.attributes("xml",True)->lang; + // let title: string; + // if (lang == "en" && t.length > 1) { + // title = t[1]._; + // } else { + // title = t[0]._; + // } + + // let creator = ""; + // if (dc.creators.creator instanceof Array) { + // dc.creators.creator.forEach((person: OaiPerson) => { + // creator += person.creatorName + "; "; + // }); + // } else { + // creator += dc.creators.creator.creatorName._; + // } + + // let contributor = ""; + // if (dc.contributors) { + // if (dc.contributors.contributor instanceof Array) { + // dc.contributors.contributor.forEach((person: OaiPerson) => { + // contributor += person.contributorName + "; "; + // }); + // } else { + // contributor += dc.contributors.contributor.contributorName; + // } + // } + + // // ?.map((u: any) => u.creatorName._).join("; "); + // // foreach ($dc->creators->creator as $c) { + // // foreach ($c->creatorName as $d) { + // // if (count(explode(',',$d)) > 1) { + // // $creator .= explode(',',$d)[0] . ', ' . substr(explode(',',$d)[1],1,1) . '; '; + // // } else { + // // $creator .= explode(',',$d)[0]; + // // } + + // // } + // // } + + // const north = dc.geoLocations.geoLocation.geoLocationBox.northBoundLatitude; + // const east = dc.geoLocations.geoLocation.geoLocationBox.eastBoundLongitude; + // const south = dc.geoLocations.geoLocation.geoLocationBox.southBoundLatitude; + // const west = dc.geoLocations.geoLocation.geoLocationBox.westBoundLongitude; + + // const subject = dc.subjects.subject.map((u: any) => u._).join(", "); + + // const oaiDataset = { + // doi: id, + // title: title, + // creator: creator, + // contributor: contributor, + // subject: subject, + // north: north, + // south: south, + // east: east, + // west: west, + // } as OaiDataset; + // arr.push(oaiDataset); + // } + // // resolve(arr); + // }); + // return arr; + // } + + // private prepareOAI(xml: any) : Array<OaiDataset> { + // // + // } + + // private prepareDataset(datasetObj: DbDataset, apiUrl: string): DbDataset { + private prepareDataset(datasetObj: DbDataset): DbDataset { const dataset = deserialize<DbDataset>(DbDataset, JSON.stringify(datasetObj)); dataset.url = document.documentURI; + // this.internalDatasetId.generateInternalId(dataset); + // if (dataset.seriesParameters) { + // dataset.parameters = dataset.seriesParameters; + // delete dataset.seriesParameters; + // } return dataset; } } diff --git a/src/views/dataset-detail.component/dataset-detail.component.ts b/src/views/dataset-detail.component/dataset-detail.component.ts index a2dc7b6..279089e 100644 --- a/src/views/dataset-detail.component/dataset-detail.component.ts +++ b/src/views/dataset-detail.component/dataset-detail.component.ts @@ -17,65 +17,55 @@ import * as L from 'leaflet'; name: "DatasetDetailComponent", components: { VsInput, - Minimap - // DataMetricsBadge, // Commented out but prepared for future use + Minimap, + // DataMetricsBadge, }, }) export default class DatasetDetailComponent extends Vue { @Prop() - datasetId!: string; // datasetId is passed as a prop and is required. + datasetId!: string; - searchTerm: string | Suggestion = ""; // Search term used in the search functionality. - private subscriptions: Array<Subscription> = []; // Subscriptions to RxJS observables to prevent memory leaks. - public dataset = {} as DbDataset; // Holds dataset details. - private error: string = ""; // Stores error messages, if any. - public loaded = false; // Indicates whether the dataset is fully loaded. - public openAccessLicences: Array<string> = ["CC-BY-4.0", "CC-BY-SA-4.0"]; // Available open-access licenses. - public portal = VUE_API + "/api/file/download/"; // Portal URL for file downloads. + // @Prop() + // identifier!: string; - // If needed for stats - // public post = { - // views: 25, // Number of views for the dataset - // downloads: 1262, // Number of downloads - // citations: 2424, // Number of citations - // }; + searchTerm: string | Suggestion = ""; + + private subscriptions: Array<Subscription> = []; + public dataset = {} as DbDataset; + private error: string = ""; + public loaded = false; + public openAccessLicences: Array<string> = ["CC-BY-4.0", "CC-BY-SA-4.0"]; + public portal = VUE_API + "/api/file/download/"; + + public post = { + views: 25, + downloads: 1262, + citations: 2424, + }; - /** - * Lifecycle hook: Called when the component is created. - * Extends dayjs with advanced format plugin and determines whether to - * fetch dataset by ID or by DOI. - */ created(): void { - dayjs.extend(advancedFormat); // Adds advanced date formatting options to dayjs. + dayjs.extend(advancedFormat); if (!this.datasetId.includes(".")) { - // Fetch dataset by publish_id (numeric ID) + // get datset by publish_id this.getDataset(Number(this.datasetId)); } else { - // Fetch dataset by DOI (alphanumeric ID) + // get datset by doi_value this.getDatasetByIdentifier(this.datasetId); } } - /** - * Lifecycle hook: Called before the component is unmounted. - * Unsubscribes from all subscriptions to prevent memory leaks. - */ beforeUnmount(): void { + //unsunscribe to ensure no memory leaks + // this.subscription.unsubscribe(); for (const subs of this.subscriptions) { subs.unsubscribe(); } } - /** - * Handles search functionality based on user input or suggestion selection. - * Opens a new window or navigates internally based on the host's domain. - * @param suggestion - The suggestion or search term entered by the user. - */ - onSearch(suggestion: Suggestion | string): void { + onSearch(suggestion: Suggestion | string): void { const host = window.location.host; const parts = host.split("."); if (parts[0] === "doi") { - // If in DOI subdomain, open external search in a new window let term; if (typeof suggestion === "string") { term = suggestion; @@ -86,7 +76,6 @@ export default class DatasetDetailComponent extends Vue { window.open("https://tethys.at/search/" + term + "/" + type, "_self"); } } else { - // Otherwise, route internally to search page let term; if (typeof suggestion === "string") { term = suggestion; @@ -96,125 +85,79 @@ export default class DatasetDetailComponent extends Vue { this.$router.push({ name: "Search", params: { display: term, type: suggestion.type } }); } } + + // this.searchTerm = suggestion; + // this.$router.push({ name: "Search", params: { display: term, suggestion instanceof Suggestion ? ty} }); } - /** - * Fetches the dataset details by ID from the service and updates the component state. - * @param id - The dataset's numeric ID. - */ private getDataset(id: number): void { const newSub = DatasetService.getDataset(id).subscribe({ next: (res: DbDataset) => { - this.dataset = res; // Store dataset in component state. - this.loaded = true; // Mark as loaded. + this.dataset = res; + this.loaded = true; }, + // error: (error: string) => this.errorHandler(error), error: (error: string) => { - this.error = error; // Capture any errors during fetch. + this.error = error; }, }); - this.subscriptions.push(newSub); // Add subscription to array to manage unsubscribing later. + this.subscriptions.push(newSub); } - /** - * Fetches the dataset details by DOI from the service and updates the component state. - * @param id - The dataset's DOI (Digital Object Identifier). - */ private getDatasetByIdentifier(id: string): void { const newSub = DatasetService.getDatasetByDoi(id).subscribe({ next: (res: DbDataset) => { - this.dataset = res; // Store dataset in component state. - this.loaded = true; // Mark as loaded. + this.dataset = res; + this.loaded = true; }, error: (error: string) => this.errorHandler(error), }); - this.subscriptions.push(newSub); // Add subscription to array. + this.subscriptions.push(newSub); } - /** - * Handles errors and updates the error message in the component. - * @param err - Error message. - */ private errorHandler(err: string): void { - this.error = err; // Update error message. + this.error = err; + // this.loading = false; } - /** - * Navigates back by one page in the router history, similar to browser back. - */ public goBack(): void { - this.$router.go(-1); // Go back one step in the browser history. + // go back by one record, the same as history.back() + // router.go(-1); + this.$router.go(-1); } - /** - * Extracts the file extension from a given filename. - * @param filename - The name of the file. - * @returns The file extension as a string. - */ public getExtension(filename: string): string { return filename.substring(filename.lastIndexOf(".") + 1, filename.length) || filename; } - /** - * Formats the file size into a human-readable string with appropriate units. - * @param file_size - The size of the file in bytes. - * @returns The formatted file size string. - */ public formatSize(file_size: number): string { let size = file_size; - const unit = ["Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; // Units for size. + const unit = ["Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; let i; for (i = 0; size >= 1024 && i < unit.length - 1; i++) { - size = size / 1024; // Convert size to appropriate unit. + size = size / 1024; } + // return Math.round((size * precision) / precision) + " " + unit[i]; return Math.round((size + Number.EPSILON) * 100) / 100 + " " + unit[i]; } - /** - * Formats a given date into a human-readable string with the full day, month, and year. - * @param date - The date string to format. - * @returns The formatted date string. - */ public getPublishedDate(date: string): string { + // return moment(date).format("ddd, MMMM Do, YYYY h:mm a"); return dayjs(date).format("ddd, MMMM Do, YYYY h:mm a"); } - /** - * Formats a given date into a simpler "DD.MM.YYYY HH:mm" format. - * @param date - The date string to format. - * @returns The formatted date string. - */ public getHumanDate(date: string): string { + // return moment(date).format("DD.MM.YYYY HH:mm"); return dayjs(date).format("DD.MM.YYYY HH:mm"); } - /** - * Extracts the year from a given date string. - * @param date - The date string to extract the year from. - * @returns The year as a string. - */ public getYear(date: string): string { return dayjs(date).format("YYYY"); + // return moment(date).format("YYYY"); } - /** - * Returns the human-readable language string based on the language code. - * @param language - The language code (e.g., "de" for German). - * @returns The language name as a string. - */ - public getLanguage(language: string): string { - if (language === "de") { - return "Deutsch"; - } else { - return "English"; - } - } - - /** - * Generates a citation string for the dataset based on its authors and publication details. - * @returns The citation as a string. - */ public getCitation(): string { let citation = this.dataset.authors .map((u) => { @@ -223,27 +166,16 @@ export default class DatasetDetailComponent extends Vue { name += ", " + u.first_name?.substring(0, 1).toUpperCase() + "."; } return name; + // u.last_name + ", " + u.first_name?.substring(0, 1).toUpperCase() + "." }) .join(", "); citation += " (" + dayjs(this.dataset.server_date_published).format("YYYY") + "): "; citation += this.dataset.MainTitle?.value; - citation += ". " + this.dataset.creating_corporation + ", "; + citation += "." + this.dataset.creating_corporation + ", "; citation += this.dataset.publisher_name; citation += ", Wien"; return citation; } - accessNotFromDoi(): boolean { - const host = window.location.host; - const parts = host.split("."); - if (parts[0] === "doi") { - console.log("From DOI"); - // If in DOI subdomain, open external search in a new window - return false; - } else { - console.log("Not From DOI"); - return true; - } - } } diff --git a/src/views/dataset-detail.component/dataset-detail.component.vue b/src/views/dataset-detail.component/dataset-detail.component.vue index ac55a61..c8a3e9e 100644 --- a/src/views/dataset-detail.component/dataset-detail.component.vue +++ b/src/views/dataset-detail.component/dataset-detail.component.vue @@ -1,55 +1,53 @@ <!-- detail-dataset.component.vue --> <template v-if="datasetId"> - + <!-- <div class="container"> + <section class="section" v-if="dataset != undefined"> + <h2 v-if="dataset.hasOwnProperty('titles')">{{ dataset.titles[0].value }} details!</h2> + <div v-if="dataset" class="dataset__blog-meta">published: {{ getHumanDate(dataset.server_date_published) }}</div> + <p v-if="dataset.hasOwnProperty('abstracts')" class="dataset__abstract">{{ dataset.abstracts[0].value }}</p> + <div><label>id: </label>{{ dataset.id }}</div> + <button v-on:click="goBack">Back</button> + </section> + </div> --> <div class="container-fluid banner mz-5"> - <!-- Search input component --> - <!-- Placeholder text for search input, and triggers onSearch method when the search term changes --> <vs-input v-bind:placeholder="'Enter your search term...'" @search-change="onSearch"></vs-input> </div> - - <!-- Section that shows the dataset details once the data is loaded --> <section v-if="loaded" class="section"> <div class="container"> + <!-- <span class="is-size-5"> Basic Table </span> + <br /> --> <div class="columns"> - <!-- Main content area displaying dataset details --> <div class="column is-8 results_column" style="padding-top: 1.2rem; padding-right: 1rem; padding-left: 1rem"> - <!-- Card displaying the publication date --> <div class="card"> <div class="column dataset__blog-meta"> <h2 class="label uppercase">published: {{ getPublishedDate(dataset.server_date_published) }}</h2> </div> </div> - <!-- Card displaying the dataset citation --> <div class="card"> <div class="column"> <label class="label"> {{ getCitation() }} - <!-- Link to the dataset's DOI if available --> <a v-if="dataset.identifier" target="_blank" class="link-label" v-bind:href="'https://doi.org/' + dataset.identifier.value" >({{ "https://doi.org/" + dataset.identifier.value }})</a > </label> </div> - <!-- Section showing references related to the dataset --> <div v-for="reference in dataset.references" v-bind:key="reference.id" class="columns"> <div class="column is-3-desktop is-4-tablet label">{{ reference.relation }}</div> <div class="column is-9-desktop is-8-tablet"> {{ reference.type }}: - <!-- Link to the reference if it's a DOI --> <a v-if="reference.type === 'DOI'" target="_blank" class="link-label" v-bind:href="reference.value"> {{ reference.value }} </a> </div> </div> - - <!-- Section showing newer versions of the dataset --> <div v-for="reference in dataset.referenced_by" v-bind:key="reference.id" class="columns"> <div class="column is-3-desktop is-4-tablet label">has newer version:</div> <div class="column is-9-desktop is-8-tablet"> + <!-- {{ "https://doi.org/" + reference.value }} --> {{ reference.type }}: - <!-- Link to the newer version's DOI --> <a v-if="reference.type === 'DOI'" target="_blank" @@ -62,11 +60,10 @@ </div> </div> - <!-- Card displaying dataset titles --> <div class="card record-elem"> - <!-- Section for Main and Translated Titles --> <div v-if="dataset.hasOwnProperty('titles')" class="columns"> <div class="column is-3-desktop is-4-tablet label">Title/<br />title:</div> + <!-- <div class="column is-9-desktop is-8-tablet">{{ dataset.titles[0].value }}</div> --> <div class="column is-9-desktop is-8-tablet"> <p>{{ dataset.MainTitle?.value }}</p> <br /> @@ -75,8 +72,6 @@ </p> </div> </div> - - <!-- Section for dataset abstracts --> <div v-if="dataset.hasOwnProperty('abstracts')" class="columns"> <div class="column is-3-desktop is-4-tablet label"> Zusammenfassung/<br /> @@ -90,7 +85,6 @@ </p> </div> </div> - <!-- Section for series information --> <div v-if="dataset.hasOwnProperty('abstracts')" class="columns"> <div class="column is-3-desktop is-4-tablet label">Serieninformation/<br />series information:</div> <div v-if="dataset.hasSeriesInformationAbstract()" class="column is-9-desktop is-8-tablet"> @@ -102,8 +96,6 @@ </div> <div v-else class="column is-9-desktop is-8-tablet">-</div> </div> - - <!-- Section for method description --> <div v-if="dataset.hasOwnProperty('abstracts')" class="columns"> <div class="column is-3-desktop is-4-tablet label">Methodik/<br />method:</div> <div v-if="dataset.hasMethodsAbstract()" class="column is-9-desktop is-8-tablet"> @@ -112,11 +104,9 @@ <div v-else class="column is-9-desktop is-8-tablet">-</div> </div> - <!-- Section for dataset files and their details --> <div class="columns"> <div class="column is-3-desktop is-4-tablet label">Downloads/<br />downloads:</div> <div v-if="dataset.files.length > 0" class="column is-9-desktop is-8-tablet"> - <!-- Table showing file details if the embargo has passed --> <table v-if="dataset.hasEmbargoPassed()" id="items" class="table is-bordered is-striped"> <thead> <tr> @@ -130,6 +120,7 @@ <td> <a class="link-label" target="_blank" v-bind:href="portal + file.id"> {{ file.label }} </a> <br /> + <!-- <span>md5: {{ file.hashvalues.find((e) => e.type === "md5")?.value }}</span> --> </td> <td> <span>{{ getExtension(file.path_name) }}</span> @@ -145,7 +136,6 @@ </div> </div> - <!-- Section for technical metadata of the dataset --> <div class="columns"> <div class="column is-3-desktop is-4-tablet label">Technische Metadaten/<br />technical metadata:</div> <div class="column is-9-desktop is-8-tablet"> @@ -159,10 +149,7 @@ </div> </div> - <!-- Sidebar displaying additional dataset details --> <div id="id-side-bar" class="column is-4 sidebar_column" style="padding-top: 1.2rem; padding-right: 1rem; padding-left: 1rem"> - - <!-- Sidebar card for dataset details like creation year, coverage, language, etc. --> <div class="card"> <div class="column"> <h2 class="label uppercase">Details</h2> @@ -177,34 +164,24 @@ <Minimap :bounds="dataset.Bounds"></Minimap> </div> </div> - <!-- Sidebar card showing dataset keywords --> <div class="card"> <div class="column"> - <h3 class="label uppercase">Schlüsselwörter/Keywords</h3> - <p v-if="dataset.hasOwnProperty('subjects')"> - <!-- Iterate through subjects and display them as router links --> - <span v-if="accessNotFromDoi()"> - <span v-for="(subject, index) in dataset.subjects" :key="subject.value"> - <router-link - :to="{ name: 'Search', params: { display: subject.value, type: 'subjects' } }" - class="link-label" - > - {{ subject.value }} - </router-link> - <!-- Add a comma and space after each keyword except the last one --> - <span v-if="index < dataset.subjects.length - 1">, </span> - </span> - </span> - - <span v-else> - {{ dataset.subjects.map((u) => u.value).join(", ") }} - </span> + <h3 class="label uppercase">Beitragende/Contributor</h3> + <p v-if="dataset.hasContributors()"> + {{ dataset.contributors.map((u) => u.full_name).join(", ") }} + </p> + <p v-else>-</p> + </div> + </div> + <div class="card"> + <div class="column"> + <h3 class="label uppercase">Schlüsselwörter/Keywords</h3> + <p v-if="dataset.hasOwnProperty('subjects')"> + {{ dataset.subjects.map((u) => u.value).join(", ") }} </p> <p v-else>-</p> </div> </div> - - <!-- Sidebar cards displaying year, coverage, language, object type, and other dataset details --> <div class="card"> <div class="column"> <h3 class="label uppercase">Erstellungsjahr/Year</h3> @@ -225,7 +202,7 @@ <div class="column"> <h3 class="label uppercase">Sprache/Language</h3> <p> - {{ getLanguage(dataset.language) }} + {{ dataset.language }} </p> </div> </div> @@ -237,22 +214,14 @@ </p> </div> </div> - <!-- Sidebar card showing dataset licenses --> <div class="card"> <div class="column"> <h3 class="label uppercase">Lizenz/License</h3> <p v-if="dataset.hasLicenses()"> <label v-for="license in dataset.licenses" v-bind:key="license.id"> - <!-- Link to the appropriate Creative Commons license --> <span class="normal label"> - <a v-if="license.name=='CC-BY-4.0'" target="_blank" class="link-label" v-bind:href="'https://creativecommons.org/licenses/by/4.0/'" - ><i class="fa-brands fa-creative-commons"></i> {{ license.name }}</a - > - <a v-else target="_blank" class="link-label" v-bind:href="'https://creativecommons.org/licenses/by-sa/4.0/'" - ><i class="fa-brands fa-creative-commons"></i> {{ license.name }}</a - > + {{ license.name }} </span> - <!-- Display Open Access label if the license allows it --> <span v-if="openAccessLicences.includes(license.name)" class="normal label uppercase" ><i class="fas fa-lock-open"></i> Open Access</span > @@ -269,14 +238,11 @@ <p v-else>-</p> </div> </div> - - <!-- Sidebar card showing references --> <div class="card"> <div class="column"> <h3 class="label uppercase">Referenzen/References</h3> <ul v-if="dataset.references.length > 0"> <li v-for="(reference, i) in dataset.references" v-bind:key="reference.id"> - <!-- Link to reference if it's a DOI or URL --> <a v-if="reference.type == 'DOI' || reference.type == 'URL'" target="_blank" @@ -289,12 +255,14 @@ {{ `${reference.relation} (${reference.type}): ${reference.value}` }} </span> <span v-if="dataset.references.length > 0 && i < dataset.references.length - 1" class="normal label">--</span> + <!-- <span v-if="openAccessLicences.includes(license.name)" class="normal label uppercase" + ><i class="fas fa-lock-open"></i> Open Access</span + > --> </li> </ul> <p v-else>-</p> </div> </div> - <!-- Sidebar card for showing embargo details --> <div class="card"> <div class="column"> <h3 class="label uppercase">Embargo</h3> @@ -304,51 +272,27 @@ <p v-else>-</p> </div> </div> - - <!-- Sidebar card for displaying dataset contributors --> - <div class="card"> - <div class="column"> - <h3 class="label uppercase">Beitragende/Contributor</h3> - <p v-if="dataset.hasContributors()"> - {{ dataset.contributors.map((u) => u.full_name).join(", ") }} - </p> - <p v-else>-</p> - </div> - </div> - </div> </div> </div> - <!-- Footer section with partner logos --> <div class="container-fluid" style="padding-top: 3.8em"> - <div class="columns"> - <div class="column col-sm"> - <div class="card mx-auto" style="width: 18rem; box-shadow: none; border: 0rem"> - <div class="card-body"> - <a target="_blank" href="https://www.re3data.org/repository/r3d100013400"> - <img src="@/assets/site/img/re3-data-logo-mono.jpg" alt="re3 data logo" /> - </a> - </div> - </div> + <div class="columns is-mobile partner-logos"> + <div class="column col-sm text-center"> + <a target="_blank" href="https://www.re3data.org/repository/r3d100013400" + ><img src="@/assets/site/img/re3-data-logo-mono.jpg" alt="re3 data logo" + /></a> </div> - <div class="column col-sm"> - <div class="card mx-auto" style="width: 28rem; box-shadow: none; border: 0rem"> - <div class="card-body"> - <a target="_blank" href="http://www.geosphere.at/"> - <img src="@/assets/site/img/geosphere-austria-logo.jpg" alt="logo geosphere austria" /> - </a> - </div> - </div> + <div class="column col-sm text-center"> + <a target="_blank" href="http://www.geosphere.at/"> + <img src="@/assets/site/img/geosphere-austria-logo.jpg" class="pb-3" alt="logo geosphere austria" /> + <!-- <img src="@/assets/site/img/gbaLogoRGB_web.png" alt="GeoSphere Austria logo" /> --> + </a> </div> - <div class="column col-sm"> - <div class="card mx-auto" style="width: 18rem; box-shadow: none; border: 0rem"> - <div class="card-body"> - <a target="_blank" href="https://www.base-search.net/Search/Results?q=coll:fttethysrdr&refid=dctablede"> - <img src="@/assets/site/img/base_logo.png" alt="logo base" /> - </a> - </div> - </div> + <div class="column col-sm text-center"> + <a target="_blank" href="https://www.base-search.net/Search/Results?q=coll:fttethysrdr&refid=dctablede"> + <img src="@/assets/site/img/base-logo.gif" alt="logo base" /> + </a> </div> </div> </div> @@ -367,32 +311,26 @@ export default DatasetDetailComponent; font-size: 0.8rem; padding: 0; } - .card { border-radius: 0; - /* Remove box-shadow for a flat design */ + /* rempve box-shadow */ box-shadow: none; } - .link-label { color: #33cccc; } - .label { /* color: #363636; */ display: block; font-size: 0.8rem; font-weight: 700; } - .label.uppercase { text-transform: uppercase; } - .normal.label { font-weight: 400; } - .column p span i { color: #336699; } @@ -403,4 +341,27 @@ export default DatasetDetailComponent; font-weight: 700; background-color: #ccddf1; } +// input { +// height: 2em; +// font-size: 1em; +// padding-left: 0.4em; +// } +// button { +// margin-top: 20px; +// font-family: Arial; +// background-color: #eee; +// border: none; +// padding: 5px 10px; +// border-radius: 4px; +// cursor: pointer; +// cursor: hand; +// } +// button:hover { +// background-color: #cfd8dc; +// } +// button:disabled { +// background-color: #eee; +// color: #ccc; +// cursor: auto; +// } </style> diff --git a/src/views/home-view/home-view-component.ts b/src/views/home-view/home-view-component.ts index eca6844..e8fe76a 100644 --- a/src/views/home-view/home-view-component.ts +++ b/src/views/home-view/home-view-component.ts @@ -11,9 +11,6 @@ import { Suggestion } from "@/models/dataset"; export default class HomeViewComponent extends Vue { public display = ""; - /* This method is called when a search suggestion is selected. It takes a parameter suggestion which can be either a Suggestion object or a string. - If it's a string, the method extracts the term and navigates to the "Search" route with the term as a parameter. If it's a Suggestion object, it extracts - the value and type from the suggestion and navigates to the "Search" route with both parameters.*/ onSearch(suggestion: Suggestion | string): void { let term; if (typeof suggestion === "string") { @@ -25,7 +22,6 @@ export default class HomeViewComponent extends Vue { } } - /* This method is called when the user initiates a search. It navigates to the "Search" route with the display property as a parameter. */ search(): void { this.$router.push({ name: "Search", params: { display: this.display } }); } diff --git a/src/views/home-view/home-view-component.vue b/src/views/home-view/home-view-component.vue index ebd6c58..26339c1 100644 --- a/src/views/home-view/home-view-component.vue +++ b/src/views/home-view/home-view-component.vue @@ -18,6 +18,13 @@ </a> </div> --> + <!-- <div class="column"> + <div class="col text-center py-3"> + <h1>Tethys Research Data Repository</h1> + <p class="lead">Data Publisher for Geoscience Austria</p> + <hr class="center-line" /> + </div> + </div> --> <div class="column"> <div class="col text-center py-3"> <h1>Tethys Research Data Repository</h1> diff --git a/src/views/search-view/search-view-component.ts b/src/views/search-view/search-view-component.ts index 55db805..44b72dd 100644 --- a/src/views/search-view/search-view-component.ts +++ b/src/views/search-view/search-view-component.ts @@ -1,26 +1,18 @@ -// Import necessary modules, components, and models from Vue and the project import { Component, Vue, Prop } from "vue-facing-decorator"; import VsInput from "@/components/vs-input/vs-input.vue"; import VsResult from "@/components/vs-result/vs-result.vue"; import FacetCategory from "@/components/face-category/facet-category.vue"; import ActiveFacetCategory from "@/components/active-facet-category/active-facet-category.vue"; - -// Import models and services -// import { SolrSettings } from "@/models/solr"; -import { OpenSettings } from "@/models/solr"; +import { SolrSettings } from "@/models/solr"; +// import { DatasetService } from "@/services/dataset.service"; import DatasetService from "../../services/dataset.service"; import { Suggestion, Dataset, SearchType } from "@/models/dataset"; -// import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "@/models/headers"; -// import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers"; -import { FacetItem, FacetResults, OpenSearchResponse } from "@/models/headers"; +import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "@/models/headers"; import { ActiveFilterCategories } from "@/models/solr"; -// import { SOLR_HOST, SOLR_CORE } from "@/constants"; +import { SOLR_HOST, SOLR_CORE } from "@/constants"; import { IPagination } from "@/models/pagination"; import PaginationComponent from "@/components/PaginationComponent.vue"; -import { OPEN_HOST, OPEN_CORE } from "@/constants"; - -// Define the Vue component, its name, and child components @Component({ name: "SearchViewComponent", components: { @@ -31,76 +23,48 @@ import { OPEN_HOST, OPEN_CORE } from "@/constants"; PaginationComponent, }, }) - -// Export the default class for the component export default class SearchViewComponent extends Vue { - // Define props passed from the parent component - @Prop() - display!: string; // Search display string - @Prop() - type!: string; // Search type - - // Declare variables used in the component - results: Array<Dataset> = []; // Array to hold search results - facets: FacetResults = new FacetResults(); // Object to hold facet results - searchTerm: string | Suggestion = ""; // The search term input - activeFilterCategories: ActiveFilterCategories = new ActiveFilterCategories(); // Active filter categories for search - pagination: IPagination = { // Pagination data for the results + @Prop() + display!: string; + + @Prop() + type!: string; + + results: Array<Dataset> = []; + + // facets: FacetFields = new FacetFields(); + facets: FacetResults = new FacetResults(); + searchTerm: string | Suggestion = ""; + // activeFilterCategories: Object = {}; + activeFilterCategories: ActiveFilterCategories = new ActiveFilterCategories(); // = new Array<ActiveFilterCategory>(); + pagination: IPagination = { total: 0, perPage: 10, currentPage: 1, + // lastPage: 0, data: [], }; - loaded = false; // Boolean to track whether data has been loaded - numFound!: number; // Number of results found - - // private solr: SolrSettings = { - // core: SOLR_CORE, //"rdr_data", // SOLR.core; - // host: SOLR_HOST, //"tethys.at", - // }; - - // Define settings for the OpenSearch API (core and host information) - private open: OpenSettings = { - core: OPEN_CORE, - host: OPEN_HOST, //"https://catalog.geosphere.at", + loaded = false; + numFound!: number; + private solr: SolrSettings = { + core: SOLR_CORE, //"rdr_data", // SOLR.core; + host: SOLR_HOST, //"tethys.at", + // core: "test_data", // SOLR.core; + // host: "repository.geologie.ac.at", }; - + // private rdrAPI!: DatasetService; private error = ""; - // Computed property to get search term as string get stringSearchTerm(): string { - // If searchTerm is a string, return it directly if (typeof this.searchTerm === "string") { return this.searchTerm; - // If searchTerm is a Suggestion, return its value and type alias } else if (this.searchTerm instanceof Suggestion) { - return this.searchTerm.value + " (" + this.getTypeAlias(this.searchTerm.type) + ")"; - // return this.searchTerm.value + " (" + this.searchTerm.type + ")"; - // Default to empty string + return this.searchTerm.value + " (" + this.searchTerm.type + ")"; } else { return ""; } } - /** - * The alias for the search term type will be set depending on the name of the type. - * This will allow to display the customised terms instead of the values currently used in the OpenSearch index. - * TODO: This should be corrected directly in the index - */ - getTypeAlias(type: string): string { - switch (type) { - case "author": - return "creator"; - case "subjects": - return "keyword"; - case "doctype": - return "data type"; - default: - return type; - } - } - - // Method to check if a search term is present hasSearchTerm(): boolean { if (typeof this.searchTerm === "string" && this.searchTerm !== "") { return true; @@ -110,22 +74,21 @@ export default class SearchViewComponent extends Vue { return false; } } - - // Method to get enum key by enum value + // getKeyName(value: string) { + // return Object.entries(Suggestion).find(([key, val]) => val === value)?.[0]; + // } getEnumKeyByEnumValue<T extends { [index: string]: string }>(myEnum: T, enumValue: string): keyof T | null { const keys = Object.keys(myEnum).filter((x) => myEnum[x] == enumValue); return keys.length > 0 ? keys[0] : null; // return keys[0]; } - // Lifecycle hook: executed before the component is mounted beforeMount(): void { - // Trigger search based on provided display and type props + // this.rdrAPI = new DatasetService(); if (this.display != "" && this.type != undefined) { - const enumKey: "Title" | "Author" | "Subject" | "Doctype" | null = this.getEnumKeyByEnumValue(SearchType, this.type); + const enumKey: "Title" | "Author" | "Subject" | null = this.getEnumKeyByEnumValue(SearchType, this.type); if (enumKey) { - const suggestion = new Suggestion(this.display, "NO-IDEA", SearchType[enumKey]); - // const suggestion = new Suggestion(this.display, "" , SearchType[enumKey]); + const suggestion = new Suggestion(this.display, SearchType[enumKey]); this.onSearch(suggestion); } else { this.onSearch(this.display); @@ -137,294 +100,216 @@ export default class SearchViewComponent extends Vue { } } - // Method to trigger a search + // onSearch(term: string): void { onSearch(suggestion: Suggestion | string): void { - // console.log("ONSEARCH"); - - // Reset active filter categories and facet results + // let queryOperator; + // if (typeof suggestion === "string") { + // suggestion = suggestion + "*"; + // queryOperator = "or"; + // } else if (suggestion instanceof Suggestion) { + // // term = suggestion.value; + // queryOperator = "and"; + // } + + // if (term) { + // term = term.trim(); + // } else { + // term = "*%3A*"; + // } + this.activeFilterCategories = new ActiveFilterCategories(); this.facets = new FacetResults(); - this.searchTerm = suggestion; - - // /* Perform faceted search. The method returns an Observable, and the code subscribes to this Observable to handle the response. If the response is successful, it calls the dataHandler method - // with the Solr response as a parameter. If there is an error, it calls the errorHandler method with the error message as a parameter */ - // DatasetService.facetedSearchSOLR(suggestion, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ - // next: (res: SolrResponse) => this.dataHandler(res), - // error: (error: string) => this.errorHandler(error), - // }); - DatasetService.facetedSearch(suggestion, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ - next: (res: OpenSearchResponse) => this.dataHandler(res), + // this.facets = {}; + this.searchTerm = suggestion; + DatasetService.facetedSearch(suggestion, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ + next: (res: SolrResponse) => this.dataHandler(res), error: (error: string) => this.errorHandler(error), }); - } - // Handle the search results - private dataHandler(res: OpenSearchResponse, filterItem?: FacetItem): void { - this.results = res.hits.hits.map(hit => hit._source); - this.numFound = res.hits.total.value; - this.pagination.total = res.hits.total.value; - this.pagination.perPage = 10; - this.pagination.data = this.results; + private dataHandler(res: SolrResponse, filterItem?: FacetItem): void { + // this.results = datasets; + this.results = res.response.docs; + this.numFound = res.response.numFound; + + // pagination + this.pagination["total"] = res.response.numFound; + this.pagination["perPage"] = res.responseHeader.params.rows as number; + // this.pagination["currentPage"] = 1; + this.pagination["data"] = res.response.docs; this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); - if (res.aggregations) { - const facet_fields = res.aggregations; - - let prop: keyof typeof facet_fields; - - // Iterate through facet fields - for (prop in facet_fields) { - const facetCategory = facet_fields[prop]; - if (facetCategory.buckets) { - const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); - - let facetValues = facetItems.map((facetItem) => { - let rObj: FacetItem; - // Check if current facet item matches filter item - if (filterItem?.val == facetItem.val) { - rObj = filterItem; - } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { - const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); - rObj = this.facets[prop][indexOfFacetValue]; - rObj.count = facetItem.count; - } else { - // Create new facet item - rObj = new FacetItem(facetItem.val, facetItem.count); - } - return rObj; - }); - - // Filter out null values and values with count <= 0 - facetValues = facetValues.filter(el => el.count > 0); - this.facets[prop] = facetValues; - } + // facets + // const facet_fields = res.facet_counts.facet_fields; + // for (const prop in facet_fields) { + // const facetCategory: FacetCategory<any> = facet_fields[prop]; + // const facetValues = facetCategory.key.values.map((facet_value: any, i: number) => { + // if (i % 2 === 0 && typeof facet_value == "string") { + // //var rObj = { value: facet, count: facet_fields[prop][i + 1] }; + // // FiletrItem with value and count + // const rObj = new FilterItem(facet_value, facetCategory.key.values[i + 1]); + // return rObj; + // } + // }); + // .filter(function (el: FilterItem) { + // return el != null && el.count > 0; + // }); + // //this.facets.push({ filterName: prop, values: facetValues }); + // this.facets[prop] = facetValues; + // } + + const facet_fields: FacetFields = res.facets; + let prop: keyof typeof facet_fields; + for (prop in facet_fields) { + const facetCategory = facet_fields[prop]; + if (facetCategory.buckets) { + const facetItems: Array<FacetItem> = facetCategory.buckets; + + let facetValues = facetItems.map((facetItem) => { + let rObj: FacetItem; + if (filterItem?.val == facetItem.val) { + rObj = filterItem; + } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { + // console.log(facetValue + " is included") + const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); + // console.log(indexOfFacetValue); + rObj = this.facets[prop][indexOfFacetValue]; + rObj.count = facetItem.count; + // rObj = new FacetItem(val, count); + } else { + rObj = new FacetItem(facetItem.val, facetItem.count); + } + return rObj; + }); + + facetValues = facetValues.filter(function (el) { + return el != null && el.count > 0; + }); + // this.facets[prop] = facetCategory; + this.facets[prop] = facetValues; } } } - // // Method to handle search response - // private dataHandlerSOLR(res: SolrResponse, filterItem?: FacetItem): void { - // // console.log("dataHandlerSOLR (docs, numFound):"); - // // console.log(res.response.docs); - // // console.log(res.response.numFound); - - // // Update results - // this.results = res.response.docs; - // this.numFound = res.response.numFound; - - // // Update pagination - // this.pagination["total"] = res.response.numFound; - // this.pagination["perPage"] = res.responseHeader.params.rows as number; - // this.pagination["data"] = res.response.docs; - // this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); - - // const facet_fields: FacetFields = res.facets; - - // /* This code declares a variable prop with a type of keys of the facet_fields object. The keyof typeof facet_fields type represents the keys of the facet_fields object. - // This means that prop can only hold values that are keys of the facet_fields object. */ - // let prop: keyof typeof facet_fields; - - // // Iterate through facet fields - // for (prop in facet_fields) { - // const facetCategory = facet_fields[prop]; - // if (facetCategory.buckets) { - // const facetItems: Array<FacetItem> = facetCategory.buckets; - - // let facetValues = facetItems.map((facetItem) => { - // let rObj: FacetItem; - // // Check if current facet item matches filter item - // if (filterItem?.val == facetItem.val) { - // rObj = filterItem; - // } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { - // // console.log(facetValue + " is included") - // // Update existing facet item with new count - // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); - // // console.log(indexOfFacetValue); - // rObj = this.facets[prop][indexOfFacetValue]; - // rObj.count = facetItem.count; - // // rObj = new FacetItem(val, count); - // } else { - // // Create new facet item - // rObj = new FacetItem(facetItem.val, facetItem.count); - // } - // return rObj; - // }); - - // // Filter out null values and values with count <= 0 - // facetValues = facetValues.filter(function (el) { - // return el != null && el.count > 0; - // }); - // // this.facets[prop] = facetCategory; - // // Update facet values - // this.facets[prop] = facetValues; - // } - // } - // } - - // Method to handle search errors private errorHandler(err: string): void { this.error = err; + // this.loading = false; } - // Method to handle pagination onMenuClick(page: number) { - console.log("onMenuClick"); - + // const test = page; + // console.log(test); this.pagination.currentPage = page; const start = page * this.pagination.perPage - this.pagination.perPage; - // // Trigger new search with updated pagination parameters - // DatasetService.facetedSearchSOLR(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, start.toString()).subscribe( - // (res: SolrResponse) => this.dataHandler(res), - // (error: string) => this.errorHandler(error), - // ); - - DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, start.toString()).subscribe({ - next: (res: OpenSearchResponse) => this.dataHandler(res), - error: (error: string) => this.errorHandler(error), - }); + DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, start.toString()).subscribe( + (res: SolrResponse) => this.dataHandler(res), + (error: string) => this.errorHandler(error), + ); } - // Method to handle facet filtering onFilter(facetItem: FacetItem): void { - console.log("onFilter"); - - // Reset current page this.pagination.currentPage = 1; - - // Check if filter item already exists + // console.log(facetItem.val); + // if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) { if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) { this.activeFilterCategories[facetItem.category] = new Array<string>(); } - - // Check if filter item is not already applied + // if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { - // Add filter item to active filter categories this.activeFilterCategories[facetItem.category].push(facetItem.val); - // DatasetService.facetedSearchSOLR(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe( - // (res: SolrResponse) => this.dataHandler(res, facetItem), - // (error: string) => this.errorHandler(error), - // ); + DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe( + (res: SolrResponse) => this.dataHandler(res, facetItem), + (error: string) => this.errorHandler(error), + ); + // alert(this.activeFilterCategories[filter.Category]); + // var res = await rdrApi.search(this.searchTerm, this.activeFilterCategories, this.solrCore, this.solrHost); + // this.results = res.response.docs; + // this.numFound = res.response.numFound; - // Trigger new search with updated filter - DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ - next: (res: OpenSearchResponse) => this.dataHandler(res, facetItem), - error: (error: string) => this.errorHandler(error), - }); + // // pagination + // this.pagination['total'] = res.response.numFound; + // this.pagination['per_page'] = res.responseHeader.params.rows; + // this.pagination['current_page'] = 1; + // this.pagination['data'] = res.response.docs; + + // var facet_fields = res.facet_counts.facet_fields; + // for (var prop in facet_fields) { + // var facetValues = facet_fields[prop].map((facetValue, i) => { + // if (i % 2 === 0) { + // // var rObj = { value: facetValue, count: facet_fields[prop][i + 1] }; + // var rObj; + // if (filter.value == facetValue) { + // rObj = filter; + // } else if (this.facets[prop].some(e => e.value === facetValue)) { + // // console.log(facetValue + " is included") + // var indexOfFacetValue = this.facets[prop].findIndex(i => i.value === facetValue); + // // console.log(indexOfFacetValue); + // rObj = this.facets[prop][indexOfFacetValue]; + // rObj.count = facet_fields[prop][i + 1]; + // } else { + // rObj = new FilterItem(facetValue, facet_fields[prop][i + 1]); + // } + // return rObj; + // } + // }).filter(function (el) { + // return el != null && el.count > 0; + // }); + // // this.facets.push({ filterName: prop, values: facetValues }); + // this.facets[prop] = facetValues; } } - // // // Method to clear facet category filter - // onClearFacetCategorySOLR(categoryName: string): void { - // console.log("onClearFacetCategory"); - - // delete this.activeFilterCategories[categoryName]; - - // // Trigger new search with updated filter - // DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ - // next: (res: SolrResponse) => { - // this.results = res.response.docs; - // this.numFound = res.response.numFound; - - // // pagination - // this.pagination["total"] = res.response.numFound; - // this.pagination["perPage"] = res.responseHeader.params.rows as number; - // this.pagination["currentPage"] = 1; - // this.pagination["data"] = res.response.docs; - - // const facet_fields: FacetFields = res.facets; - // let prop: keyof typeof facet_fields; - // for (prop in facet_fields) { - // const facetCategory: FacetInstance = facet_fields[prop]; - // if (facetCategory.buckets) { - // const facetItems: Array<FacetItem> = facetCategory.buckets; - - // const facetValues = facetItems.map((facetItem) => { - // let rObj: FacetItem; - // if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { - // // console.log(facetValue + " is included") - // // Update existing facet item with new count - // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); - // // console.log(indexOfFacetValue); - // rObj = this.facets[prop][indexOfFacetValue]; - // rObj.count = facetItem.count; - // // rObj = new FacetItem(val, count); - // // if facet ccategory is reactivated category, deactivate all filter items - // if (prop == categoryName) { - // rObj.active = false; - // } - // } else { - // // Create new facet item - // rObj = new FacetItem(facetItem.val, facetItem.count); - // } - // return rObj; - // }); - // this.facets[prop] = facetValues; - // } - // } - // }, - // error: (error: string) => this.errorHandler(error), - // complete: () => console.log("clear facet category completed"), - // }); - // } - - // Method to clear facet category filter onClearFacetCategory(categoryName: string): void { - // console.log("onClearFacetCategory"); + // alert(categoryName); delete this.activeFilterCategories[categoryName]; - // Trigger new search with updated filter - DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ - next: (res: OpenSearchResponse) => { - this.results = res.hits.hits.map(hit => hit._source); - this.numFound = res.hits.total.value; - - // Update pagination - this.pagination.total = res.hits.total.value; - this.pagination.perPage = 10; - this.pagination.currentPage = 1; - this.pagination.data = this.results; - this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); - - if (res.aggregations) { - const facet_fields = res.aggregations; - - let prop: keyof typeof facet_fields; - - for (prop in facet_fields) { - const facetCategory = facet_fields[prop]; - if (facetCategory.buckets) { - const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); - - const facetValues = facetItems.map((facetItem) => { - let rObj: FacetItem; - if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { - // Update existing facet item with new count - const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); - rObj = this.facets[prop][indexOfFacetValue]; - rObj.count = facetItem.count; - // if facet category is reactivated category, deactivate all filter items - if (prop === categoryName) { - rObj.active = false; - } - } else { - // Create new facet item - rObj = new FacetItem(facetItem.val, facetItem.count); + DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ + next: (res: SolrResponse) => { + this.results = res.response.docs; + this.numFound = res.response.numFound; + + // pagination + this.pagination["total"] = res.response.numFound; + this.pagination["perPage"] = res.responseHeader.params.rows as number; + this.pagination["currentPage"] = 1; + this.pagination["data"] = res.response.docs; + + const facet_fields: FacetFields = res.facets; + let prop: keyof typeof facet_fields; + for (prop in facet_fields) { + const facetCategory: FacetInstance = facet_fields[prop]; + if (facetCategory.buckets) { + const facetItems: Array<FacetItem> = facetCategory.buckets; + + const facetValues = facetItems.map((facetItem) => { + let rObj: FacetItem; + if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { + // console.log(facetValue + " is included") + const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); + // console.log(indexOfFacetValue); + rObj = this.facets[prop][indexOfFacetValue]; + rObj.count = facetItem.count; + // rObj = new FacetItem(val, count); + //if facet ccategory is reactivated category, deactivate all filter items + if (prop == categoryName) { + rObj.active = false; } - return rObj; - }).filter(el => el.count > 0); // Filter out items with count <= 0 - - this.facets[prop] = facetValues; - } + } else { + rObj = new FacetItem(facetItem.val, facetItem.count); + } + return rObj; + }); + this.facets[prop] = facetValues; } } }, error: (error: string) => this.errorHandler(error), - complete: () => console.log("Clear facet category completed"), + complete: () => console.log("clear facet category completed"), }); } + // onPaging(page: number): void {} } diff --git a/src/views/search-view/search-view-component.vue b/src/views/search-view/search-view-component.vue index 4fa064f..5afc7d1 100644 --- a/src/views/search-view/search-view-component.vue +++ b/src/views/search-view/search-view-component.vue @@ -1,39 +1,46 @@ <template> <div id="page_style" class="rows site-content page__style page__description" autocomplete="off"> - - <!-- Search input section --> <div class="container-fluid banner mz-5"> <vs-input v-bind:propDisplay="searchTerm" v-bind:placeholder="'Enter your search term...'" @search-change="onSearch"></vs-input> </div> - - <!-- Results area on top of the list of publications --> - <div class="columns"> - <!-- Left sidebar section. Empty, just to keep simetry --> - <div id="id-side-bar" class="column is-4 sidebar_column" style="padding-top: 0rem; padding-right: 1.5rem; padding-left: 1.5rem"> - </div> - - <!-- Results section --> - <div class="col col-8 column is-8 results_column" style="padding-top: 0.5rem; padding-right: 1rem; padding-left: 1rem; padding-bottom: 0rem;"> - <!-- Display results if any --> - <div v-if="results.length > 0" class="result-list-info"> - <div v-if="hasSearchTerm()" class="p-1 mb-0 text-sm bg-[#d8f4f7] rounded-lg" role="alert"> - <span class="font-medium pl-5">Your search term</span> <span class="font-semibold">{{ "'" + stringSearchTerm + "'" }}</span> yielded <strong>{{ numFound }}</strong> results: - </div> + <div class="column is-half is-offset-one-quarter" style="padding-top: 0; margin-top: 0"> + <!-- <div class="tabs is-centered"> + <ul id="id-results-tabs"> + <li class="search_tab is-active"> + <a target="_self">Web</a> + </li> + <li class="search_tab"> + <a target="_self">Images</a> + </li> + <li class="search_tab"> + <a target="_self">Videos</a> + </li> + <li class="search_tab"> + <a target="_self">Homepages</a> + </li> + <li class="search_tab"> + <a target="_self">Food</a> + </li> + <li class="search_tab"> + <a target="_self">Books</a> + </li> + </ul> + </div> --> + <div v-if="results.length > 0" class="result-list-info"> + <div v-if="hasSearchTerm()" class="resultheader"> + Your search term {{ "'" + stringSearchTerm + "'" }} yielded <strong>{{ numFound }}</strong> results: </div> - <!-- Display message if no results found --> - <div v-else-if="results.length == 0"> - <div class="p-1 mb-0 text-sm bg-[#d8f4f7] rounded-lg" role="alert"> - <!-- <span class="font-medium pl-5">Your search yielded <strong> 0</strong> results.</span> --> - <span class="font-medium pl-5">Your search term</span> <span class="font-semibold">{{ "'" + stringSearchTerm + "'" }}</span> yielded <strong>0</strong> results: - </div> + </div> + <div v-else-if="results.length == 0"> + <div class="resultheader"> + Your search yielded + <strong> 0</strong> results: </div> </div> </div> - <!-- Area with the list of facets (left) and list of publications (right) --> <div class="columns"> - <!-- Sidebar with facets --> - <div id="id-side-bar" class="column is-4 sidebar_column" style="padding-top: 0.5rem; padding-right: 1.5rem; padding-left: 1.5rem"> + <div id="id-side-bar" class="column is-4 sidebar_column" style="padding-top: 1.2rem; padding-right: 1.5rem; padding-left: 1.5rem"> <div id="externals" class=""> <div v-for="(facetItems, key, index) in facets" v-bind:key="index" name="external_card" style="margin-bottom: 0px"> <facet-category v-bind:facetItems="facetItems" v-bind:filterName="key" @filter="onFilter"></facet-category> @@ -41,11 +48,9 @@ </div> </div> - <!-- Main results section with pagination and active filters --> - <div class="col col-8 column is-8 results_column" style="padding-top: 0.5rem; padding-right: 1rem; padding-left: 1rem"> + <div class="col col-8 column is-8 results_column" style="padding-top: 1.2rem; padding-right: 1rem; padding-left: 1rem"> <div v-if="activeFilterCategories && Object.keys(activeFilterCategories).length > 0" class="column"> <span v-for="(values, key, index) in activeFilterCategories" v-bind:key="index" class="active-filter-items"> - <!-- Active filter categories --> <active-facet-category v-bind:filterItems="values" v-bind:categoryName="key" @@ -54,17 +59,38 @@ </span> </div> <div class="results"> - <!-- Pagination before search results --> + <!-- pagination before search results --> <PaginationComponent class="mb-5" v-bind:data="pagination" @menu-click="onMenuClick"></PaginationComponent> <!-- Results section --> <vs-result v-bind:datasets="results"></vs-result> - <!-- Pagination after search results --> + <!-- pagination after serach results --> <PaginationComponent class="mt-5" v-bind:data="pagination" @menu-click="onMenuClick"></PaginationComponent> </div> </div> + + <!-- <PaginationComponent v-bind:data="pagination"></PaginationComponent> --> </div> - <!-- Partner logos section --> + <!-- <div class="container-fluid" style="padding-top: 3.8em"> + <div class="columns is-mobile partner-logos"> + <div class="column col-sm text-center"> + <a target="_blank" href="https://www.re3data.org/repository/r3d100013400" + ><img src="@/assets/site/img/re3-data-logo-mono.jpg" alt="re3 data logo" + /></a> + </div> + <div class="column col-sm text-center"> + <a target="_blank" href="http://www.geosphere.at/"> + <img src="@/assets/site/img/geosphere-austria-logo.jpg" alt="logo geosphere austria" /> + </a> + </div> + <div class="column col-sm text-center"> + <a target="_blank" href="https://www.base-search.net/Search/Results?q=coll:fttethysrdr&refid=dctablede"> + <img src="@/assets/site/img/base-logo.gif" alt="logo base" /> + </a> + </div> + </div> + </div> --> + <div class="container-fluid"> <!-- <div class="columns is-mobile partner-logos"> --> <div class="columns"> @@ -108,4 +134,4 @@ export default SearchViewComponent; import "@/index.css"; </script> -<style scoped></style> \ No newline at end of file +<style scoped></style> diff --git a/vue.config.cjs b/vue.config.cjs index 4fc1199..a15c57a 100644 --- a/vue.config.cjs +++ b/vue.config.cjs @@ -89,11 +89,8 @@ module.exports = { __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false", APP_URL: JSON.stringify(process.env.APP_URL), VUE_API: JSON.stringify(process.env.VUE_API), - // SOLR_HOST: JSON.stringify(process.env.SOLR_HOST), - // SOLR_CORE: JSON.stringify(process.env.SOLR_CORE), - // OPENSEARCH - OPEN_HOST: JSON.stringify(process.env.OPEN_HOST), - OPEN_CORE: JSON.stringify(process.env.OPEN_CORE), + SOLR_HOST: JSON.stringify(process.env.SOLR_HOST), + SOLR_CORE: JSON.stringify(process.env.SOLR_CORE), }), // new NodePolyfillPlugin(), ],