Compare commits
94 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 01e10d6f9d | |||
| 5dd8821667 | |||
| 9f076daf15 | |||
| de0ccdfcac | |||
| 5eaf505669 | |||
| 8e3f4fa88e | |||
| fef92c392d | |||
| 6f1b9f4c5f | |||
| 013d12e7b3 | |||
| 50ab318854 | |||
| bb7d8eb378 | |||
| 826c5b8c4e | |||
| 7953b3c09c | |||
| f4bd82a453 | |||
| c47d77401b | |||
| bd32e6071d | |||
| 2b7b5323d3 | |||
| 6fb7ad0e93 | |||
| 9ad4037c74 | |||
| 0126ae9f85 | |||
| 03a55f6a58 | |||
| 110c2db8bf | |||
| cc62df68da | |||
| 332923df2d | |||
| 8767748f9c | |||
| 32f743c04e | |||
| 95c7c8ba7b | |||
| d135ab2d50 | |||
| da430d6142 | |||
| a70e454cbc | |||
| 9b8b2bd5ac | |||
| 4f53411d07 | |||
| 6d1c1b28c3 | |||
| a853e93b68 | |||
| 953f6551a1 | |||
| 9968b1e466 | |||
| ccf4e238f3 | |||
| 2d38b690fa | |||
| 376b828831 | |||
| 97f6d359b9 | |||
| 484be48d1e | |||
| 8962345f99 | |||
| fab69f496b | |||
| 515ef24c54 | |||
| 0611ba9437 | |||
| d50e93a658 | |||
| d50bf55fb3 | |||
| 07bdcd9610 | |||
| 85ab6fb8cc | |||
| 524e996c8a | |||
| 3dbb04d737 | |||
| d75ab4f367 | |||
| 1e2e37aef3 | |||
| afa3b8264b | |||
| a1b2f39e98 | |||
| 8e3245c270 | |||
| c040f6c380 | |||
| 1f855b9629 | |||
| 00d5bbb8db | |||
| debccc2e53 | |||
| b570e364b9 | |||
| e997c0e1a1 | |||
| c6469b00b4 | |||
| 315eabf3bb | |||
| 59a83c1978 | |||
| a85debca92 | |||
|
|
6f63db4a71 | ||
|
|
1e33c340a2 | ||
|
|
5bcd4b1bbe | ||
|
|
63ef3ad0ab | ||
|
|
49658ae5ea | ||
|
|
05662dfc2d | ||
|
|
251eebc138 | ||
|
|
9ea5c15844 | ||
|
|
6f5881e627 | ||
|
|
4dd238ec36 | ||
|
|
d2c0fb72fd | ||
|
|
3faf538afd | ||
|
|
4f1ea85982 | ||
|
|
cfc81f2d90 | ||
|
|
f1fbc2d917 | ||
|
|
c0a758dbc2 | ||
|
|
eb6476dfcb | ||
|
|
426228705c | ||
|
|
6295f7ea1c | ||
|
|
5603614045 | ||
|
|
82872bf3fb | ||
|
|
49ef135106 | ||
|
|
20720fad0c | ||
|
|
2f690f5bf2 | ||
|
|
f749b2eb3e | ||
|
|
38b8973f02 | ||
|
|
a72337ed6f | ||
|
|
8fd116df7f |
98 changed files with 8487 additions and 28381 deletions
|
|
@ -1,3 +1,3 @@
|
|||
> 1%
|
||||
last 2 versions
|
||||
last 4 versions
|
||||
not dead
|
||||
|
|
|
|||
6
.env.example
Normal file
6
.env.example
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
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
|
||||
58
.eslintrc.cjs
Normal file
58
.eslintrc.cjs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// https://npmmirror.com/package/@typescript-eslint/eslint-plugin/v/5.0.1-alpha.14
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "vue-eslint-parser",
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
// extends: ["plugin:vue/vue3-essential", "eslint:recommended", "@vue/typescript/recommended", "@vue/prettier", "@vue/prettier/@typescript-eslint"],
|
||||
extends: [
|
||||
// "plugin:vue/vue3-essential",
|
||||
"plugin:vue/vue3-recommended",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended",
|
||||
// "plugin:@typescript-eslint/recommended",
|
||||
|
||||
// "plugin:prettier/recommended",
|
||||
"@vue/prettier",
|
||||
// "@vue/prettier/@typescript-eslint"
|
||||
],
|
||||
// plugins: ["@typescript-eslint"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
// parser: "@typescript-eslint/parser",
|
||||
},
|
||||
rules: {
|
||||
// indent: [
|
||||
// 'error',
|
||||
// 2,
|
||||
// {
|
||||
// SwitchCase: 1,
|
||||
// ignoredNodes: ['ConditionalExpression'], <-- I add this line
|
||||
// },
|
||||
// ],
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"@typescript-eslint/indent": ["error", 4, {"SwitchCase": 1, ignoredNodes: ["PropertyDefinition"] }],
|
||||
"arrow-parens": "off",
|
||||
semi: "error",
|
||||
// "@vue-eslint/printWidth": ["error", 120],
|
||||
"vue/v-bind-style": ["warn", "longform"], //autofix
|
||||
"vue/prop-name-casing": ["error", "camelCase"], //autofix
|
||||
"vue/multi-word-component-names": ["warn"],
|
||||
// https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/attribute-hyphenation.md
|
||||
"vue/attribute-hyphenation": [
|
||||
"error",
|
||||
"never",
|
||||
{
|
||||
ignore: [],
|
||||
},
|
||||
],
|
||||
|
||||
// 'prettier/prettier': ['error', { printWidth: 120 }],
|
||||
// "prettier/prettier": "error",
|
||||
"prettier/prettier": ["error", { singleQuote: false }],
|
||||
},
|
||||
};
|
||||
19
.eslintrc.js
19
.eslintrc.js
|
|
@ -1,19 +0,0 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
extends: ["plugin:vue/vue3-essential", "eslint:recommended", "@vue/typescript/recommended", "@vue/prettier", "@vue/prettier/@typescript-eslint"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
rules: {
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
// 'prettier/prettier': ['error', { printWidth: 120 }],
|
||||
"prettier/prettier": "error",
|
||||
"@typescript-eslint/indent": ["error", 4],
|
||||
// "@vue-eslint/printWidth": ["error", 120],
|
||||
},
|
||||
};
|
||||
|
|
@ -5,5 +5,5 @@
|
|||
"singleQuote": false,
|
||||
"arrowParens": "always",
|
||||
"proseWrap": "preserve",
|
||||
"printWidth": 180
|
||||
"printWidth": 160
|
||||
}
|
||||
9
OpenSearch queries.txt
Normal file
9
OpenSearch queries.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
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": {}
|
||||
}
|
||||
}'
|
||||
|
||||
26
README.md
26
README.md
|
|
@ -1,24 +1,38 @@
|
|||
# typescript-vueapp
|
||||
# tethys.frontend is a typescript-vueapp
|
||||
|
||||
## Project setup
|
||||
```
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
## create .env file for environments
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Check out deployment instructions at <https://cli.vuejs.org/guide/deployment.html> \
|
||||
After building, copy the dist folder to the web root of your Nginx server.
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
### Customize build and dev configuration
|
||||
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
|
|
|||
60
SOLR queries.txt
Normal file
60
SOLR queries.txt
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
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 ","
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
||||
// module.exports = {
|
||||
// presets: ["@vue/cli-plugin-babel/preset"],
|
||||
// };
|
||||
|
|
|
|||
18719
package-lock.json
generated
18719
package-lock.json
generated
File diff suppressed because it is too large
Load diff
59
package.json
59
package.json
|
|
@ -3,50 +3,61 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve --port 3000",
|
||||
"serve": "vue-cli-service serve --port 3001",
|
||||
"serve2": "vue-cli-service serve --port 3002",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"lint": "vue-cli-service lint --check",
|
||||
"lint2": "eslint ./src --ext .js,.ts",
|
||||
"format": "prettier --check src/**/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@openfonts/open-sans_all": "^1.44.2",
|
||||
"axios": "^0.27.2",
|
||||
"axios": "^1.2.2",
|
||||
"class-transformer": "^0.5.1",
|
||||
"core-js": "^3.6.5",
|
||||
"dayjs": "^1.10.7",
|
||||
"leaflet": "^1.7.1",
|
||||
"dompurify": "^3.1.6",
|
||||
"leaflet": "^1.9.4",
|
||||
"qs": "^6.10.1",
|
||||
"rxjs": "^7.5.5",
|
||||
"vue": "^3.0.0",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue": "^3.2.47",
|
||||
"vue-facing-decorator": "^3.0.4",
|
||||
"vue-matomo": "^4.1.0",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"vue-router": "^4.0.12",
|
||||
"xml2js": "^0.4.23",
|
||||
"xslt3": "^2.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.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",
|
||||
"@types/xml2js": "^0.4.9",
|
||||
"@typescript-eslint/eslint-plugin": "^4.18.0",
|
||||
"@typescript-eslint/parser": "^4.18.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.4",
|
||||
"@vue/cli-plugin-typescript": "~5.0.4",
|
||||
"@vue/cli-service": "~5.0.4",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^7.0.0",
|
||||
"bulma": "^0.9.3",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"node-polyfill-webpack-plugin": "^2.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"babel-preset-typescript-vue3": "^2.0.17",
|
||||
"bulma": "^0.9.4",
|
||||
"eslint": "^8.25.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-vue": "^9.9.0",
|
||||
"postcss": "^8.4.36",
|
||||
"prettier": "^3.2.5",
|
||||
"pug-plain-loader": "^1.1.0",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^13.0.0",
|
||||
"typescript": "^4.7.2",
|
||||
"sass-loader": "^14.1.1",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.1.3",
|
||||
"vue-loader": "^17.0.1",
|
||||
"webpack": "^5.72.1"
|
||||
}
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
|
|||
6
postcss.config.cjs
Normal file
6
postcss.config.cjs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
Binary file not shown.
BIN
public/docs/PreservationPlanTethys.pdf
Normal file
BIN
public/docs/PreservationPlanTethys.pdf
Normal file
Binary file not shown.
47
src/App.vue
47
src/App.vue
|
|
@ -1,25 +1,27 @@
|
|||
<template>
|
||||
<!-- <HelloWorld msg="Welcome to Your Vue.js plus TypeScript App" /> -->
|
||||
|
||||
<!-- <link
|
||||
rel="stylesheet"
|
||||
href="https://use.fontawesome.com/releases/v5.2.0/css/all.css"
|
||||
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<nav class="navbar navbar-light border-bottom" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
<!-- <img src="./assets/images/TETHYS-Logo.svg" width="240px" height="86" alt="TETHYS Logo" /> -->
|
||||
<img src="./assets/images/TETHYS-Logo.svg" width="240" height="86" />
|
||||
<img src="./assets/images/TETHYS-Logo.svg" width="240" height="86" />
|
||||
<a href="https://doi.org/10.34894/TKWVFL" target="_blank"><img src="./assets/images/cts-logo.png" width="80" height="80" /></a>
|
||||
</a>
|
||||
<a id="menu-icon" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" :class="active ? 'is-active' : ''" @click="showMobilemenu">
|
||||
<a
|
||||
id="menu-icon"
|
||||
role="button"
|
||||
class="navbar-burger"
|
||||
aria-label="menu"
|
||||
aria-expanded="false"
|
||||
v-bind:class="active ? 'is-active' : ''"
|
||||
@click="showMobilemenu"
|
||||
>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="navMenu" class="navbar-menu" :class="active ? 'is-active' : ''">
|
||||
<div id="navMenu" class="navbar-menu" v-bind:class="active ? 'is-active' : ''">
|
||||
<ul class="navbar-start" style="flex-grow: 1; justify-content: center">
|
||||
<li class="navbar-item">
|
||||
<!-- <a class="navbar-link is-arrowless active" href="#">STARTSEITE</a> -->
|
||||
|
|
@ -53,7 +55,7 @@
|
|||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<a v-bind:href="portal" class="button is-primary custom-button">
|
||||
<a v-bind:href="portal" target="_blank" class="button is-primary custom-button">
|
||||
<i class="fas fa-sign-in-alt"></i>
|
||||
<!-- <fa :icon="['fas', 'phone']" class="fas fa-sign-in-alt" /> -->
|
||||
<!-- </span> -->
|
||||
|
|
@ -78,8 +80,10 @@
|
|||
<ul class="list-group list-group-flush">
|
||||
<!-- <li class="list-group-item"><a href="#">OAI</a></li> -->
|
||||
<li class="list-group-item"><router-link to="/oai">OAI</router-link></li>
|
||||
<li class="list-group-item"><a href="https://www.geologie.ac.at/" target="_blank">About GBA</a></li>
|
||||
<li class="list-group-item"><a href="https://www.geosphere.at/" target="_blank">geosphere.at</a></li>
|
||||
<li class="list-group-item"><a href="https://www.geologie.ac.at/news/news" target="_blank">News</a></li>
|
||||
<li class="list-group-item"><a href="docs/PreservationPlanTethys.pdf" target="_blank">Preservation Plan</a></li>
|
||||
<li class="list-group-item"><a href="docs/HandbuchTethys.pdf" target="_blank">Manual</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -118,16 +122,16 @@
|
|||
<h5 class="card-title">Connect with us</h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
<a target="_blank" href="https://www.geologie.ac.at/"><i class="fas fa-home pr-2"></i>GBA</a>
|
||||
<a target="_blank" href="https://www.geosphere.at/"><i class="fas fa-home pr-2"></i>geosphere.at</a>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<a href="#"><i class="fas fa-phone-alt pr-2"></i> +43-1-7125674</a>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<a href="mailto:repository@geologie.ac.at"><i class="fas fa-envelope pr-2"></i> repository(at)geologie.ac.at </a>
|
||||
<a href="mailto:repository@geologie.ac.at"><i class="fas fa-envelope pr-2"></i> repository(at)geosphere.at </a>
|
||||
</li>
|
||||
</ul>
|
||||
<img class="img-fluid pt-4" src="@/assets/site/img/geologische-bundesanstalt-logo.jpg" alt="Geologische Bundesanstalt logo" />
|
||||
<img class="img-fluid pt-4" src="@/assets/site/img/geosphere-austria-logo-negativ.png" alt="GeoSphere Austria Logo" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -135,7 +139,7 @@
|
|||
</footer>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="copyright-notice">Copyright 2022 TETHYS RDR</div>
|
||||
<div class="copyright-notice">© {{ currentYear }} TETHYS RDR</div>
|
||||
</div>
|
||||
|
||||
<!-- <vs-input
|
||||
|
|
@ -157,6 +161,7 @@ export default App;
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import 'leaflet/dist/leaflet.css';
|
||||
// #app {
|
||||
// font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
// -webkit-font-smoothing: antialiased;
|
||||
|
|
@ -234,7 +239,7 @@ footer .card-title {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
.list-group-flush > .list-group-item {
|
||||
border-width: 0 0 1px;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.list-group-item:first-child {
|
||||
|
|
@ -257,4 +262,12 @@ footer .list-group-item a {
|
|||
background-color: #384d6e;
|
||||
padding: 0.3em 0;
|
||||
}
|
||||
|
||||
.development-notice {
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background-color: red;
|
||||
padding: 1em 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
77
src/App2.vue
77
src/App2.vue
|
|
@ -1,18 +1,79 @@
|
|||
<template>
|
||||
<!-- <HelloWorld msg="Welcome to Your Vue.js plus TypeScript App" /> -->
|
||||
|
||||
<!-- <link
|
||||
rel="stylesheet"
|
||||
href="https://use.fontawesome.com/releases/v5.2.0/css/all.css"
|
||||
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ"
|
||||
crossorigin="anonymous"
|
||||
/> -->
|
||||
<nav class="navbar navbar-light border-bottom" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" v-bind:href="app_url">
|
||||
<!-- <img src="./assets/images/TETHYS-Logo.svg" width="240px" height="86" alt="TETHYS Logo" /> -->
|
||||
<img src="./assets/images/TETHYS-Logo.svg" width="240" height="86" />
|
||||
<img src="./assets/images/cts-logo.png" width="80" height="80" />
|
||||
</a>
|
||||
<a
|
||||
id="menu-icon"
|
||||
role="button"
|
||||
class="navbar-burger"
|
||||
aria-label="menu"
|
||||
aria-expanded="false"
|
||||
v-bind:class="active ? 'is-active' : ''"
|
||||
@click="showMobilemenu"
|
||||
>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="navMenu" class="navbar-menu" v-bind:class="active ? 'is-active' : ''">
|
||||
<ul class="navbar-start" style="flex-grow: 1; justify-content: center">
|
||||
<li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless active" v-bind:href="app_url">STARTSEITE</a>
|
||||
<!-- <router-link class="navbar-link is-arrowless" to="/">STARTSEITE</router-link> -->
|
||||
</li>
|
||||
<li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless" v-bind:href="search_url">SEARCH</a>
|
||||
<!-- <router-link class="navbar-link is-arrowless" to="/search">SEARCH</router-link> -->
|
||||
</li>
|
||||
<li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless" v-bind:href="service_url">SERVICES</a>
|
||||
<!-- <router-link class="navbar-link is-arrowless" to="/services">SERVICES</router-link> -->
|
||||
</li>
|
||||
<li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless" v-bind:href="help_url">HELP</a>
|
||||
<!-- <router-link class="navbar-link is-arrowless" to="/help">HELP</router-link> -->
|
||||
</li>
|
||||
<!-- <li class="navbar-item">
|
||||
<router-link class="navbar-link is-arrowless" to="/map">MAP</router-link>
|
||||
</li> -->
|
||||
<!-- <li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless" href="#">HELP</a>
|
||||
</li> -->
|
||||
<li class="navbar-item">
|
||||
<a class="navbar-link is-arrowless" v-bind:href="oai_url">OAI</a>
|
||||
<!-- <router-link target="_blank" class="navbar-link is-arrowless" to="/oai">OAI</router-link> -->
|
||||
</li>
|
||||
<!--
|
||||
<a href="#" class="custom-btn"><i class="fas fa-sign-in-alt"></i>SIGN IN</a> -->
|
||||
</ul>
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<a v-bind:href="portal" target="_blank" class="button is-primary custom-button">
|
||||
<i class="fas fa-sign-in-alt"></i>
|
||||
<!-- <fa :icon="['fas', 'phone']" class="fas fa-sign-in-alt" /> -->
|
||||
<!-- </span> -->
|
||||
<strong>Sign in</strong>
|
||||
</a>
|
||||
<!-- <a class="button is-light"> Log in </a> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- <home-view-component></home-view-component> -->
|
||||
<router-view></router-view>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="copyright-notice">Copyright 2022 TETHYS RDR</div>
|
||||
<div class="copyright-notice">© {{ currentYear }} TETHYS RDR</div>
|
||||
</div>
|
||||
|
||||
<!-- <vs-input
|
||||
|
|
@ -111,7 +172,7 @@ footer .card-title {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
.list-group-flush > .list-group-item {
|
||||
border-width: 0 0 1px;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.list-group-item:first-child {
|
||||
|
|
|
|||
|
|
@ -1,51 +1,37 @@
|
|||
import initializeAxios from "./axiosSetup";
|
||||
import { axiosRequestConfiguration } from "./config";
|
||||
import { map } from "rxjs/operators";
|
||||
// import { Observable } from "@reactivex/rxjs/compat";
|
||||
import { defer, Observable } from "rxjs";
|
||||
import { AxiosResponse } from "axios";
|
||||
// https://ichi.pro/de/so-wickeln-sie-axios-mit-typescript-und-react-in-rxjs-ein-118892823169891
|
||||
// Import the necessary modules and functions
|
||||
import initializeAxios from "./axiosSetup"; // Function to initialize the Axios instance
|
||||
import { axiosRequestConfiguration } from "./config"; // Axios configuration settings
|
||||
import { map } from "rxjs/operators"; // Operator to transform the items emitted by an Observable
|
||||
import { defer, Observable } from "rxjs"; // RxJS utilities for creating and working with Observables
|
||||
import { AxiosResponse } from "axios"; // Axios response type
|
||||
|
||||
// Initialize the Axios instance with the provided configuration
|
||||
const axiosInstance = initializeAxios(axiosRequestConfiguration);
|
||||
|
||||
// Function to make a GET request using Axios wrapped in an Observable
|
||||
// eslint-disable-next-line
|
||||
const get = <T>(url: string, queryParams?: any): Observable<T> => {
|
||||
return defer(() => axiosInstance.get<T>(url, { params: queryParams })).pipe(map((result: AxiosResponse) => result.data));
|
||||
// Use defer to create an Observable that makes the Axios GET request when subscribed to
|
||||
return defer(() => axiosInstance.get<T>(url, { params: queryParams }))
|
||||
// Use map to transform the Axios response to extract the data property
|
||||
.pipe(map((result: AxiosResponse) => result.data));
|
||||
};
|
||||
|
||||
// const post = <T>(
|
||||
// url: string,
|
||||
// body: object,
|
||||
// queryParams?: object
|
||||
// ): Observable<T | void> => {
|
||||
// return defer(() =>
|
||||
// axiosInstance.post<T>(url, body, { params: queryParams })
|
||||
// ).pipe(map((result) => result.data));
|
||||
// };
|
||||
// Function to make a POST request using Axios wrapped in an Observable
|
||||
const post = <T>(url: string, body: any, queryParams?: any): Observable<T> => {
|
||||
// Use defer to create an Observable that makes the Axios POST request when subscribed to
|
||||
// console.log(body);
|
||||
// console.log(queryParams);
|
||||
|
||||
return defer(() => axiosInstance.post<T>(url, body, {
|
||||
params: queryParams,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}))
|
||||
.pipe(map((result: AxiosResponse) => result.data)); // Use map to transform the Axios response to extract the data property
|
||||
};
|
||||
|
||||
// const put = <T>(
|
||||
// url: string,
|
||||
// body: object,
|
||||
// queryParams?: object
|
||||
// ): Observable<T | void> => {
|
||||
// return defer(() =>
|
||||
// axiosInstance.put<T>(url, body, { params: queryParams })
|
||||
// ).pipe(map((result) => result.data));
|
||||
// };
|
||||
|
||||
// const patch = <T>(
|
||||
// url: string,
|
||||
// body: object,
|
||||
// queryParams?: object
|
||||
// ): Observable<T | void> => {
|
||||
// return defer(() =>
|
||||
// axiosInstance.patch<T>(url, body, { params: queryParams })
|
||||
// ).pipe(map((result) => result.data));
|
||||
// };
|
||||
|
||||
// const deleteR = <T>(url: string, id: number): Observable<T | void> => {
|
||||
// return defer(() => axiosInstance.delete(`${url}/${id}`)).pipe(
|
||||
// map((result) => result.data)
|
||||
// );
|
||||
// };
|
||||
|
||||
export default { get };
|
||||
// Export the get and post functions as part of the default export
|
||||
export default { get, post };
|
||||
|
|
@ -1,20 +1,12 @@
|
|||
import axios, { AxiosRequestConfig, AxiosInstance } from "axios";
|
||||
|
||||
const initialization = (config: AxiosRequestConfig): AxiosInstance => {
|
||||
//axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
|
||||
|
||||
delete axios.defaults.headers.common["X-Requested-With"];
|
||||
// axios.defaults.withCredentials = true;
|
||||
// const token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
// if (token) {
|
||||
// axios.defaults.headers.common["X-CSRF-TOKEN"] = token.innerHTML;
|
||||
// }
|
||||
const axiosInstance = axios.create(config);
|
||||
|
||||
/*
|
||||
Add default headers, interceptors etc..
|
||||
*/
|
||||
const axiosInstance = axios.create(config);
|
||||
|
||||
return axiosInstance;
|
||||
};
|
||||
|
||||
export default initialization;
|
||||
export default initialization;
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
import { AxiosRequestConfig } from "axios";
|
||||
import * as qs from "qs";
|
||||
import { stringify } from "qs";
|
||||
|
||||
/* This file configures Axios to send requests with the specified headers and parameters serialization format for URL-encoded form data */
|
||||
export const axiosRequestConfiguration: AxiosRequestConfig = {
|
||||
responseType: "text",
|
||||
|
||||
headers: {
|
||||
// "Content-Type": "text/plain",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
// "Content-Type": "application/x-www-form-urlencoded",
|
||||
// credentials: "same-origin",
|
||||
// "Access-Control-Allow-Credentials": "true",
|
||||
// "Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
paramsSerializer: (params) => qs.stringify(params, { arrayFormat: "repeat" }),
|
||||
|
||||
paramsSerializer: {
|
||||
/* The serialize function takes an object of key-value pairs as input and uses the qs.stringify method to convert it into a URL-encoded string.
|
||||
The arrayFormat: "repeat" option specifies how arrays should be serialized in the URL parameters. */
|
||||
serialize: (params: Record<string, number>) => {
|
||||
return stringify(params, { arrayFormat: "repeat" });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
72
src/app.ts
72
src/app.ts
|
|
@ -1,7 +1,4 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Watch } from "vue-property-decorator";
|
||||
// import { RouteLocation } from "vue-router";
|
||||
import HelloWorld from "./components/HelloWorld/HelloWorld.vue";
|
||||
import { Component, Vue, Watch } from "vue-facing-decorator";
|
||||
import HomeViewComponent from "./views/home-view/home-view-component.vue";
|
||||
import HelpViewComponent from "./views/help-view/help-view-component.vue";
|
||||
import MapViewComponent from "./views/map-view/map-view.component.vue";
|
||||
|
|
@ -13,27 +10,10 @@ import ContactViewComponent from "./views/contact-view/contact-view-component.vu
|
|||
import SitelinkViewComponent from "./views/sitelink-view/sitelink-view-component.vue";
|
||||
import ImprintViewComponent from "./views/imprint-view/imprint-view-component.vue";
|
||||
import TermsViewComponent from "./views/terms-view/terms-view-component";
|
||||
import { VUE_APP_PORTAL } from "./constants";
|
||||
// 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 { SolrSettings } from "@/models/solr";
|
||||
// import { DatasetService } from "./services/dataset.service";
|
||||
// import { Suggestion } from "./models/dataset";
|
||||
// import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "./models/headers";
|
||||
// import { ActiveFilterCategories } from "@/models/solr";
|
||||
|
||||
// https://devsoniq.com/how-to-toggle-bulma-css-navbar-in-your-vue-js-project/
|
||||
@Options({
|
||||
@Component({
|
||||
components: {
|
||||
HelloWorld,
|
||||
HomeViewComponent,
|
||||
// VsInput,
|
||||
// VsResult,
|
||||
// FacetCategory,
|
||||
// ActiveFacetCategory,
|
||||
HelpViewComponent,
|
||||
MapViewComponent,
|
||||
SearchViewComponent,
|
||||
|
|
@ -48,36 +28,42 @@ import { VUE_APP_PORTAL } from "./constants";
|
|||
})
|
||||
export default class App extends Vue {
|
||||
public active = false;
|
||||
public portal = VUE_APP_PORTAL + "/login";
|
||||
public portal = "https://data.tethys.at/login"; // VUE_API + "/login";
|
||||
|
||||
mounted(): void {
|
||||
// const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll(".navbar-burger"), 0);
|
||||
// // Check if there are any navbar burgers
|
||||
// if ($navbarBurgers.length > 0) {
|
||||
// // Add a click event on each of them
|
||||
// $navbarBurgers.forEach((elNavBurger) => {
|
||||
// elNavBurger.addEventListener("click", () => {
|
||||
// // Get the target from the "data-target" attribute
|
||||
// const targetNavbar = elNavBurger.dataset.target;
|
||||
// const $target = document.getElementById(targetNavbar);
|
||||
// // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
|
||||
// elNavBurger.classList.toggle("is-active");
|
||||
// $target?.classList.toggle("is-active");
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
/**
|
||||
* Computed property that returns the current year.
|
||||
* @returns {number} The current year as a number.
|
||||
*/
|
||||
get currentYear() {
|
||||
return new Date().getFullYear();
|
||||
}
|
||||
|
||||
public showMobilemenu(event: PointerEvent): void {
|
||||
// Don't follow the link
|
||||
/**
|
||||
* Lifecycle hook called when the component is mounted.
|
||||
* Currently empty, but can be used to add setup logic when the component is mounted.
|
||||
*/
|
||||
mounted(): void {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the mobile menu.
|
||||
* @param {MouseEvent} event - The mouse event triggered by the user's interaction.
|
||||
*/
|
||||
public showMobilemenu(event: MouseEvent): void {
|
||||
// Prevent the default behavior of the event (e.g., following a link)
|
||||
event.preventDefault();
|
||||
// Toggle the active state of the mobile menu
|
||||
this.active = !this.active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Watcher that triggers when the route changes.
|
||||
* It deactivates the mobile menu by setting `active` to false.
|
||||
*/
|
||||
@Watch("$route")
|
||||
protected oRouteChangedChanged(): void {
|
||||
//(to: RouteLocation, from: RouteLocation): void {
|
||||
// console.log("setting " + from.path + " to " + to.path);
|
||||
// Close the mobile menu when the route changes
|
||||
this.active = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
src/app2.ts
23
src/app2.ts
|
|
@ -1,7 +1,5 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Watch } from "vue-property-decorator";
|
||||
import { Component, Vue, Watch } from "vue-facing-decorator";
|
||||
// import { RouteLocation } from "vue-router";
|
||||
import HelloWorld from "./components/HelloWorld/HelloWorld.vue";
|
||||
import HomeViewComponent from "./views/home-view/home-view-component.vue";
|
||||
import HelpViewComponent from "./views/help-view/help-view-component.vue";
|
||||
import SearchViewComponent from "./views/search-view/search-view-component.vue";
|
||||
|
|
@ -12,7 +10,7 @@ import ContactViewComponent from "./views/contact-view/contact-view-component.vu
|
|||
import SitelinkViewComponent from "./views/sitelink-view/sitelink-view-component.vue";
|
||||
import ImprintViewComponent from "./views/imprint-view/imprint-view-component.vue";
|
||||
import TermsViewComponent from "./views/terms-view/terms-view-component";
|
||||
import { VUE_APP_PORTAL } from "./constants";
|
||||
import { APP_URL } from "./constants";
|
||||
// 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";
|
||||
|
|
@ -25,9 +23,9 @@ import { VUE_APP_PORTAL } from "./constants";
|
|||
// import { ActiveFilterCategories } from "@/models/solr";
|
||||
|
||||
// https://devsoniq.com/how-to-toggle-bulma-css-navbar-in-your-vue-js-project/
|
||||
@Options({
|
||||
@Component({
|
||||
components: {
|
||||
HelloWorld,
|
||||
// HelloWorld,
|
||||
HomeViewComponent,
|
||||
// VsInput,
|
||||
// VsResult,
|
||||
|
|
@ -46,7 +44,16 @@ import { VUE_APP_PORTAL } from "./constants";
|
|||
})
|
||||
export default class App2 extends Vue {
|
||||
public active = false;
|
||||
public portal = VUE_APP_PORTAL + "/login";
|
||||
public portal = "https://data.tethys.at/login"; // VUE_API + "/login";
|
||||
public app_url = APP_URL;
|
||||
public search_url = APP_URL + "/search";
|
||||
public service_url = APP_URL + "/services";
|
||||
public help_url = APP_URL + "/help";
|
||||
public oai_url = APP_URL + "/oai";
|
||||
|
||||
get currentYear() {
|
||||
return new Date().getFullYear();
|
||||
}
|
||||
|
||||
mounted(): void {
|
||||
// const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll(".navbar-burger"), 0);
|
||||
|
|
@ -66,7 +73,7 @@ export default class App2 extends Vue {
|
|||
// }
|
||||
}
|
||||
|
||||
public showMobilemenu(event: PointerEvent): void {
|
||||
public showMobilemenu(event: MouseEvent): void {
|
||||
// Don't follow the link
|
||||
event.preventDefault();
|
||||
this.active = !this.active;
|
||||
|
|
|
|||
7
src/assets/datacite/citationIcon.vue
Normal file
7
src/assets/datacite/citationIcon.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
7
src/assets/datacite/downloadIcon.vue
Normal file
7
src/assets/datacite/downloadIcon.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path
|
||||
d="M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
17
src/assets/datacite/infoCircleIcon.vue
Normal file
17
src/assets/datacite/infoCircleIcon.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<template>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="info-circle"
|
||||
class="svg-inline--fa fa-info-circle fa-w-16"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
36
src/assets/datacite/mediumBadge.vue
Normal file
36
src/assets/datacite/mediumBadge.vue
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 420 525"
|
||||
style="enable-background: new 0 0 420 420"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
fill="navy"
|
||||
d="M210,420c115.98,0,210-94.02,210-210S325.98,0,210,0S0,94.02,0,210S94.02,420,210,420z M102.75,356.083 c4.694,0,8.5,3.806,8.5,8.5c0,4.694-3.806,8.5-8.5,8.5c-4.694,0-8.5-3.806-8.5-8.5C94.25,359.888,98.055,356.083,102.75,356.083z M126.417,387.083c-4.694,0-8.5-3.806-8.5-8.5c0-4.694,3.806-8.5,8.5-8.5s8.5,3.806,8.5,8.5 C134.917,383.277,131.111,387.083,126.417,387.083z M386.89,270.021c-4-0.844-8.532,2.038-13.756,8.727l-2.027-1.108 c1-7.57,3.666-13.371,7.993-17.3c5.727-5.199,13.053-5.803,16.877-5.708c-1.447,6.029-3.178,11.948-5.182,17.742 C389.733,271.223,388.447,270.346,386.89,270.021z M375.09,279.817c5.491-6.923,9.126-8.101,11.348-7.644 c1.397,0.291,2.552,1.312,3.494,2.642c-1.317,3.646-2.745,7.239-4.274,10.779L375.09,279.817z M343.703,113.234l2.954,4.862 l-4.862,2.954l-2.954-4.862L343.703,113.234z M330.318,114.278l-1.787-2.942l31.621-19.213l1.787,2.942L330.318,114.278z M348.767,121.569l2.954,4.862l-4.862,2.954l-2.954-4.862L348.767,121.569z M349.653,116.276l-2.954-4.862l4.862-2.954l2.954,4.862 L349.653,116.276z M356.625,116.795l2.954,4.862l-4.862,2.954l-2.954-4.862L356.625,116.795z M357.796,111.276l-2.954-4.862 l4.862-2.954l2.954,4.862L357.796,111.276z M364.768,111.795l2.954,4.862l-4.862,2.954l-2.954-4.862L364.768,111.795z M245.027,44.365V21.979c6.073,1.129,12.047,2.541,17.906,4.231v18.155H245.027z M222.974,44.365V19.202 c6.05,0.407,12.022,1.097,17.906,2.056v23.107H222.974z M218.828,18.964v25.401h-17.906V18.973 c3.009-0.141,6.034-0.221,9.078-0.221C212.959,18.752,215.901,18.83,218.828,18.964z M156.817,44.365V26.284 c5.858-1.699,11.833-3.12,17.906-4.258v22.338H156.817z M178.869,21.3c5.884-0.967,11.856-1.667,17.906-2.082v25.147h-17.906V21.3z M152.67,27.534v16.831h-26.337v4.146h167.083v-4.146h-26.337V27.453c34.488,10.807,64.8,31.139,87.848,57.899l-34.941,21.23 l30.117,49.568l23.498-14.277l13.388,26.034l8.535-4.389c3.731,14.887,5.724,30.456,5.724,46.483 c0,14.579-1.647,28.78-4.752,42.433c-4.033-0.185-12.269,0.297-18.856,6.262c-4.569,4.138-7.433,10.113-8.592,17.82l-4.236-2.315 l-24.94,45.629l11.588,6.334l-65.348,53.229l3.607,4.428c-12.342,5.683-25.388,10.085-38.969,13.044v-10.113h-62.667v13.235 c-14.036-1.609-27.615-4.739-40.566-9.229l8.453-12.694l-64.09-42.679l-10.609,15.932C55.395,327.723,36,297.139,26.105,262.583 H40.75v-10.306c15.005-13.643,21.584-26.699,19.55-38.855c-1.987-11.872-11.675-20.244-19.55-25.218v-7.287h5.333v-2.575 c6.492-1.971,11.962-7.543,12.402-13.187c0.252-3.229-0.944-9.076-11.786-11.967c-6.358-1.695-11.009-1.125-13.822,1.7 c-2.173,2.182-2.807,5.292-2.865,8.03h-5.39C40.947,98.677,89.868,47.31,152.67,27.534z M40.75,169.916v-7h-8.543 c0.049-2.283,0.557-4.797,2.23-6.478c2.216-2.225,6.15-2.605,11.696-1.126c6.894,1.838,10.502,5.272,10.159,9.67 c-0.354,4.536-4.863,9.169-10.209,11.043v-6.109H40.75z M35.75,169.249v4.667H22.417v-4.667H35.75z M22.417,183.249v-4.667H35.75 v4.667H22.417z M40.75,242.469c7.072-6.671,10.424-13.292,9.945-19.768c-0.532-7.187-5.618-12.565-9.945-15.887V190.9 c7.273,4.843,15.648,12.517,17.381,22.892c1.833,10.974-4.025,22.888-17.381,35.477V242.469z M40.75,224.916v-15.233 c3.619,3.087,7.34,7.576,7.752,13.189c0.392,5.336-2.222,10.868-7.752,16.53v-4.82H20.327c-0.412-3.198-0.746-6.421-0.997-9.667 H40.75z"
|
||||
/>
|
||||
<path
|
||||
d="M247.773,292.246c-11.503,5.304-24.298,8.269-37.773,8.269c-49.91,0-90.515-40.605-90.515-90.515 c0-49.91,40.605-90.515,90.515-90.515c49.699,0,90.165,40.263,90.507,89.883c1.634,0.243,3.22,0.635,4.734,1.176 c0.001-0.182,0.007-0.362,0.007-0.544c0-52.604-42.644-95.248-95.248-95.248c-52.604,0-95.248,42.644-95.248,95.248 c0,17.255,4.588,33.438,12.611,47.396l-61.7,38.931l5.692,9.021l61.839-39.019c17.336,23.598,45.28,38.918,76.806,38.918 c14.337,0,27.931-3.174,40.127-8.848L247.773,292.246z"
|
||||
/>
|
||||
<ellipse transform="matrix(0.5109 -0.8597 0.8597 0.5109 -12.1749 390.1086)" cx="336.721" cy="205.753" rx="22.5" ry="22.5" />
|
||||
<path
|
||||
d="M236.061,360.269l52.989-27.836c2.995-1.574,5.226-4.295,6.18-7.542s0.551-6.742-1.117-9.687l-17.798-31.413 c3.899-8.552,9.898-16.735,16.041-24.091c-7.731-14.904-7.732-27.708-7.719-28.688c0.073-5.55,4.647-10.065,10.197-10.065 l0.137,0.001c5.594,0.074,10.108,4.684,10.065,10.277c0.001,0.481,0.078,5.198,2.267,11.701c6.865-7.181,9.261-18.593,3.267-24.528 c-6.251-6.191-19.259-8.527-31.067,1.488c-16.156,13.866-24.122,24.407-33.247,44.826c-2.917,8.139-1.894,13.947,0.887,18.292 c0.018,0.032,0.031,0.066,0.049,0.098L266,316.301l-41.566,21.835c-6.111,3.211-8.463,10.768-5.253,16.88 c2.236,4.257,6.58,6.689,11.077,6.689C232.217,361.705,234.206,361.243,236.061,360.269z"
|
||||
/>
|
||||
<path
|
||||
d="M342.377,280.248c-39.021-16.042-39.54-47.6-39.542-49.04c0.034-4.398-3.491-8.002-7.895-8.06c-0.036,0-0.072,0-0.107,0 c-4.369,0-7.939,3.513-7.997,7.895c-0.023,1.774-0.003,43.671,49.457,64.005c0.995,0.409,2.025,0.603,3.039,0.603 c3.146,0,6.131-1.869,7.402-4.96C348.415,286.603,346.463,281.929,342.377,280.248z"
|
||||
/>
|
||||
<circle cx="90.083" cy="94.916" r="10.333" />
|
||||
<path
|
||||
d="M213.333,254.334v-11.835c16.475-1.67,29.333-15.583,29.333-32.499s-12.858-30.829-29.333-32.498v-11.835h-6.667v11.835 c-16.476,1.67-29.333,15.582-29.333,32.498s12.858,30.829,29.333,32.499v11.835H213.333z M185.333,210 c0-13.601,11.065-24.667,24.667-24.667s24.667,11.065,24.667,24.667S223.601,234.667,210,234.667S185.333,223.602,185.333,210z"
|
||||
/>
|
||||
<path d="M226.667,210c0-9.19-7.477-16.667-16.667-16.667S193.333,200.81,193.333,210s7.477,16.667,16.667,16.667 S226.667,219.19,226.667,210z" />
|
||||
<circle cx="70" cy="118.249" r="6.25" />
|
||||
<rect x="106.083" y="58.916" width="200" height="3.333" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
17
src/assets/datacite/smallBadge.vue
Normal file
17
src/assets/datacite/smallBadge.vue
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 125"
|
||||
enable-background="new 0 0 100 100"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<path
|
||||
fill="brown"
|
||||
d="M95.281,30.258H4.718V50v19.741h90.563L83.437,50L95.281,30.258z M87.586,32.014H90.9v3.314h-3.314V32.014z M81.346,32.014 h3.315v3.314h-3.315V32.014z M9.787,67.986H6.472v-3.314h3.315V67.986z M9.787,35.328H6.472v-3.314h3.315V35.328z M16.027,67.986 h-3.315v-3.314h3.315V67.986z M16.027,35.328h-3.315v-3.314h3.315V35.328z M22.266,67.986h-3.315v-3.314h3.315V67.986z M22.266,35.328h-3.315v-3.314h3.315V35.328z M28.506,67.986h-3.315v-3.314h3.315V67.986z M28.506,35.328h-3.315v-3.314h3.315 V35.328z M34.745,67.986H31.43v-3.314h3.315V67.986z M34.745,35.328H31.43v-3.314h3.315V35.328z M40.984,67.986H37.67v-3.314h3.314 V67.986z M40.984,35.328H37.67v-3.314h3.314V35.328z M47.224,67.986h-3.315v-3.314h3.315V67.986z M47.224,35.328h-3.315v-3.314 h3.315V35.328z M53.464,67.986h-3.315v-3.314h3.315V67.986z M53.464,35.328h-3.315v-3.314h3.315V35.328z M59.703,67.986h-3.315 v-3.314h3.315V67.986z M59.703,35.328h-3.315v-3.314h3.315V35.328z M65.941,67.986h-3.313v-3.314h3.313V67.986z M65.941,35.328 h-3.313v-3.314h3.313V35.328z M72.181,67.986h-3.313v-3.314h3.313V67.986z M72.181,35.328h-3.313v-3.314h3.313V35.328z M78.421,67.986h-3.314v-3.314h3.314V67.986z M78.421,35.328h-3.314v-3.314h3.314V35.328z M87.586,64.672H90.9v3.314h-3.314V64.672z M84.661,64.672v3.314h-3.315v-3.314H84.661z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
74
src/assets/datacite/testLogo.vue
Normal file
74
src/assets/datacite/testLogo.vue
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg
|
||||
id="Layer_1"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="-250 351.8 229.3 91.5"
|
||||
style="enable-background: new -250 351.8 229.3 91.5"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
id="SVGID_1_"
|
||||
class="st0"
|
||||
d="M-138.4,387.7h-4.6c-1.2,0-2,0.3-2.6,0.7c-0.6,0.4-0.9,1.2-0.9,2.1c0,1.8,1.2,2.7,3.5,2.7
|
||||
c0.8,0,1.5-0.1,2.1-0.2c0.5-0.2,1.1-0.5,1.5-0.9c0.5-0.5,0.8-1.5,0.8-2.9v-1.5H-138.4z M-138.3,396.2v-1.7
|
||||
c-0.7,0.7-1.4,1.3-2.2,1.5c-0.8,0.3-1.7,0.5-3,0.5c-1.2,0-2.2-0.2-3.1-0.5c-0.9-0.3-1.6-0.7-2.2-1.4c-1-1.1-1.5-2.4-1.5-4.1
|
||||
c0-1.1,0.3-2.1,0.8-2.9c0.5-0.8,1.3-1.5,2.2-2c1-0.4,2.2-0.7,3.7-0.7h5.1v-1.4c0-1.3-0.4-2.2-1-2.7c-0.6-0.5-1.7-0.9-3.2-0.9
|
||||
c-1.1,0-1.9,0.2-2.5,0.4c-0.6,0.3-1.2,0.7-1.7,1.4l-2.5-2.4c0.9-1.1,1.9-1.8,2.9-2.2c1.1-0.5,2.4-0.6,4.1-0.6c5.3,0,8,2.2,8,6.7
|
||||
v13L-138.3,396.2L-138.3,396.2z M-153.4,392.9h1.6v3.3h-2.3c-1.2,0-2.2-0.3-2.9-0.7c-0.8-0.5-1.4-1.2-1.8-2s-0.6-1.7-0.6-2.7
|
||||
v-10.7h-2.2v-3h2.2v-5.9h3.9v5.9h3.8v3h-3.8v10.4C-155.6,392.2-154.9,392.9-153.4,392.9z M-167.9,387.7h-4.6
|
||||
c-1.2,0-2,0.3-2.6,0.7c-0.6,0.4-0.9,1.2-0.9,2.1c0,1.8,1.2,2.7,3.5,2.7c0.8,0,1.5-0.1,2.1-0.2c0.5-0.2,1.1-0.5,1.5-0.9
|
||||
c0.5-0.5,0.8-1.5,0.8-2.9v-1.5H-167.9z M-167.8,396.2v-1.7c-0.7,0.7-1.4,1.3-2.2,1.5s-1.7,0.5-3,0.5c-1.2,0-2.2-0.2-3.1-0.5
|
||||
c-0.9-0.3-1.6-0.7-2.2-1.4c-1-1.1-1.5-2.4-1.5-4.1c0-1.1,0.3-2.1,0.8-2.9c0.5-0.8,1.3-1.5,2.2-2c1-0.4,2.2-0.7,3.7-0.7h5.1v-1.4
|
||||
c0-1.3-0.4-2.2-1-2.7s-1.7-0.9-3.2-0.9c-1.1,0-1.9,0.2-2.5,0.4c-0.6,0.3-1.2,0.7-1.7,1.4l-2.5-2.4c0.9-1.1,1.9-1.8,2.9-2.2
|
||||
c1.1-0.5,2.4-0.6,4.1-0.6c5.3,0,8,2.2,8,6.7v13L-167.8,396.2L-167.8,396.2z M-186.2,378.8c-0.1-0.8-0.2-1.6-0.4-2.4
|
||||
c-0.2-0.7-0.5-1.4-1-1.9c-1.1-1.3-2.7-1.9-4.6-1.9h-5.1v19.8h5c2,0,3.5-0.6,4.6-1.8c0.6-0.7,1.1-1.7,1.2-2.9
|
||||
c0.2-1.3,0.3-3,0.3-5.3C-186.2,380.9-186.2,379.7-186.2,378.8z M-182.2,387.6c-0.1,1.1-0.4,2.2-0.8,3.2c-0.4,1.1-1,2-1.8,2.8
|
||||
c-1.7,1.7-4.1,2.5-7,2.5h-9.5V369h9.5c3,0,5.3,0.8,7,2.5c0.8,0.8,1.4,1.7,1.8,2.7c0.4,1,0.6,2.1,0.8,3.1c0.1,1.1,0.2,2.2,0.2,3.7
|
||||
v1.4v1.3C-182.1,385.3-182.1,386.5-182.2,387.6z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
id="SVGID_3_"
|
||||
class="st1"
|
||||
d="M-77.6,383.9c-0.1-0.4-0.3-0.9-0.4-1.5c-0.4-1-1-1.7-1.9-2.2c-0.9-0.5-1.8-0.8-2.9-0.8
|
||||
c-1.1,0-2,0.3-2.9,0.8c-0.9,0.5-1.5,1.4-1.9,2.2c-0.3,0.6-0.4,1.1-0.4,1.5c-0.1,0.4-0.2,1.1-0.2,1.9h10.8
|
||||
C-77.5,385-77.5,384.3-77.6,383.9z M-88.3,387.4c0,2.3,0.5,4.1,1.5,5.4c1,1.3,2.5,1.9,4.4,1.9c1.1,0,2-0.2,2.7-0.5
|
||||
c0.7-0.4,1.5-0.9,2.3-1.7l1.4,1.2c-1,1-2,1.7-3,2.2c-1,0.4-2.2,0.6-3.7,0.6c-1.7,0-3.2-0.4-4.3-1.1c-1.2-0.7-2.1-1.8-2.6-3.1
|
||||
c-0.6-1.4-0.9-3.1-0.9-5.2c0-1.5,0.2-2.8,0.5-4c0.4-1.2,0.8-2.2,1.4-3s1.4-1.4,2.3-1.9c0.9-0.4,2-0.6,3.1-0.6
|
||||
c1.2,0,2.2,0.2,3.1,0.6c0.9,0.4,1.7,1,2.3,1.8c0.6,0.8,1.2,1.7,1.4,2.8c0.4,1.1,0.5,2.3,0.5,3.8v0.9H-88.3z M-94.4,394.5h1.3v1.7
|
||||
h-1.7c-0.9,0-1.7-0.2-2.4-0.6c-0.6-0.4-1.2-1-1.5-1.7c-0.4-0.7-0.5-1.5-0.5-2.5v-12.1h-2.5v-1.4h2.5V372h2v5.9h4.1v1.4h-4.1v12.1
|
||||
C-97.3,393.5-96.3,394.5-94.4,394.5z M-105.2,396.2h-2v-18.4h2V396.2z M-107.4,371.4V369h2.4v2.4H-107.4z M-116.4,372.3
|
||||
c-1.3-1.2-2.8-1.7-4.6-1.7c-1,0-1.9,0.2-2.8,0.5c-0.9,0.4-1.7,0.9-2.3,1.5c-0.5,0.4-0.9,1-1.2,1.5s-0.4,1.2-0.6,2
|
||||
c-0.2,0.8-0.3,1.7-0.3,2.7s-0.1,2.2-0.1,3.7c0,2.2,0,3.8,0.1,5c0.1,1.2,0.3,2.1,0.5,2.9c0.3,0.8,0.7,1.5,1.3,2.1
|
||||
c0.7,0.7,1.4,1.2,2.3,1.5c0.9,0.4,1.8,0.5,2.8,0.5c1.2,0,2.3-0.3,3.3-0.7s1.8-1.2,2.5-2.2c0.7-0.9,1.2-2,1.4-3.2h2
|
||||
c-0.3,1.6-0.9,3.1-1.7,4.2c-0.8,1.2-1.9,2.1-3.2,2.7c-1.3,0.6-2.7,1-4.3,1c-1.3,0-2.5-0.3-3.7-0.7c-1.2-0.4-2.2-1.2-3.1-2.1
|
||||
c-0.8-0.8-1.3-1.6-1.7-2.5c-0.4-0.9-0.5-1.9-0.6-3.1c-0.1-1.2-0.1-3-0.1-5.4s0-4.2,0.1-5.4c0.1-1.2,0.3-2.2,0.6-3.1
|
||||
s0.9-1.7,1.7-2.5c0.9-0.9,1.9-1.5,3.1-2.1c1.3-0.5,2.5-0.7,3.9-0.7c1.6,0,3.1,0.4,4.3,1s2.3,1.5,3.2,2.7c0.8,1.2,1.4,2.6,1.7,4.2
|
||||
h-2.1C-114.3,374.8-115.2,373.4-116.4,372.3z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
class="st2"
|
||||
d="M-236.2,375.1c-0.3,0-0.5,0-0.8,0c7.6,0.8,14.3,3.7,11.6,8.4c-3,5.1-15.5,8.5-26.2,8.5
|
||||
c0.3,0.1,0.6,0.1,0.9,0.2c14.4,2.9,35.9-0.9,38.6-7.9C-210.1,378.6-222.1,374.6-236.2,375.1z"
|
||||
/>
|
||||
<path
|
||||
class="st3"
|
||||
d="M-220.2,391.9c-2.5,15.2-15.6,6.1-18.7-4.5c-4.5-10.9-0.5-25,10.7-16.8c-9.3-4.2-10.2,8.1-6.3,16.8
|
||||
c3.3,7.3,10.4,12,14,4.5C-220.4,392-220.2,392-220.2,391.9z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
7
src/assets/datacite/viewIcon.vue
Normal file
7
src/assets/datacite/viewIcon.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
|
||||
<path
|
||||
d="M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
BIN
src/assets/images/cts-logo.png
Normal file
BIN
src/assets/images/cts-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +2,7 @@
|
|||
// @import "~bulma";
|
||||
// @import "@fontsource/open-sans"; // Defaults to weight 400.
|
||||
@import "~@openfonts/open-sans_all/index.css";
|
||||
@import '~leaflet/dist/leaflet.css';
|
||||
// @import '~leaflet/dist/leaflet.css';
|
||||
|
||||
// 1. Import the initial variables
|
||||
@import "~bulma/sass/utilities/_all.sass";
|
||||
|
|
|
|||
BIN
src/assets/site/img/base_logo.png
Normal file
BIN
src/assets/site/img/base_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
src/assets/site/img/geosphere-austria-logo-negativ.png
Normal file
BIN
src/assets/site/img/geosphere-austria-logo-negativ.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 24 KiB |
103
src/colors.ts
Normal file
103
src/colors.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
const gradientBgBase = "bg-gradient-to-tr";
|
||||
export const gradientBgPurplePink = `${gradientBgBase} from-purple-400 via-pink-500 to-red-500`;
|
||||
export const gradientBgDark = `${gradientBgBase} from-slate-700 via-slate-900 to-slate-800`;
|
||||
export const gradientBgPinkRed = `${gradientBgBase} from-pink-400 via-red-500 to-yellow-500`;
|
||||
export const gradientBgGreenBlue = `${gradientBgBase} from-green-400 to-blue-400`;
|
||||
|
||||
export const colorsBgLight = {
|
||||
white: "bg-white text-black",
|
||||
light: "bg-white text-black dark:bg-slate-900/70 dark:text-white",
|
||||
contrast: "bg-gray-800 text-white dark:bg-white dark:text-black",
|
||||
success: "bg-emerald-500 border-emerald-500 text-white",
|
||||
danger: "bg-red-500 border-red-500 text-white",
|
||||
warning: "bg-yellow-500 border-yellow-500 text-white",
|
||||
info: "bg-blue-500 border-blue-500 text-white",
|
||||
};
|
||||
|
||||
export const colorsText = {
|
||||
white: "text-black dark:text-slate-100",
|
||||
light: "text-gray-700 dark:text-slate-400",
|
||||
contrast: "dark:text-white",
|
||||
success: "text-emerald-500",
|
||||
danger: "text-red-500",
|
||||
warning: "text-yellow-500",
|
||||
info: "text-blue-500",
|
||||
modern: "text-teal-500",
|
||||
};
|
||||
|
||||
export const colorsOutline = {
|
||||
white: [colorsText.white, "border-gray-100"],
|
||||
light: [colorsText.light, "border-gray-100"],
|
||||
contrast: [colorsText.contrast, "border-gray-900 dark:border-slate-100"],
|
||||
success: [colorsText.success, "border-emerald-500"],
|
||||
danger: [colorsText.danger, "border-red-500"],
|
||||
warning: [colorsText.warning, "border-yellow-500"],
|
||||
info: [colorsText.info, "border-blue-500"],
|
||||
};
|
||||
|
||||
export const getButtonColor = (color: "white" | "contrast" | "light" | "success" | "danger" | "warning" | "modern", isOutlined: boolean, hasHover: boolean) => {
|
||||
const colors = {
|
||||
bg: {
|
||||
white: "bg-white text-black",
|
||||
contrast: "bg-gray-800 text-white dark:bg-white dark:text-black",
|
||||
light: "bg-gray-50 text-black",
|
||||
success: "bg-emerald-600 dark:bg-emerald-500 text-white",
|
||||
danger: "bg-red-600 dark:bg-red-500 text-white",
|
||||
warning: "bg-yellow-600 dark:bg-yellow-500 text-white",
|
||||
info: "bg-blue-600 dark:bg-blue-500 text-white",
|
||||
modern: "bg-teal-600 dark:bg-teal-500 text-white",
|
||||
},
|
||||
bgHover: {
|
||||
white: "hover:bg-gray-50",
|
||||
contrast: "hover:bg-gray-900 hover:dark:bg-slate-100",
|
||||
light: "hover:bg-gray-200",
|
||||
success: "hover:bg-emerald-700 hover:border-emerald-700 hover:dark:bg-emerald-600 hover:dark:border-emerald-600",
|
||||
danger: "hover:bg-red-700 hover:border-red-700 hover:dark:bg-red-600 hover:dark:border-red-600",
|
||||
warning: "hover:bg-yellow-700 hover:border-yellow-700 hover:dark:bg-yellow-600 hover:dark:border-yellow-600",
|
||||
info: "hover:bg-blue-700 hover:border-blue-700 hover:dark:bg-blue-600 hover:dark:border-blue-600",
|
||||
modern: "hover:bg-emerald-700 hover:border-emerald-700 hover:dark:bg-emerald-600 hover:dark:border-emerald-600",
|
||||
},
|
||||
borders: {
|
||||
white: "border-gray-100",
|
||||
contrast: "border-gray-900 dark:border-slate-100",
|
||||
light: "border-gray-100 dark:border-slate-700",
|
||||
success: "border-emerald-600 dark:border-emerald-500",
|
||||
danger: "border-red-600 dark:border-red-500",
|
||||
warning: "border-yellow-600 dark:border-yellow-500",
|
||||
info: "border-blue-600 dark:border-blue-500",
|
||||
modern: "border-teal-600 dark:border-teal-500",
|
||||
},
|
||||
text: {
|
||||
white: "text-black dark:text-slate-100",
|
||||
contrast: "dark:text-slate-100",
|
||||
light: "text-gray-700 dark:text-slate-400",
|
||||
success: "text-emerald-600 dark:text-emerald-500",
|
||||
danger: "text-red-600 dark:text-red-500",
|
||||
warning: "text-yellow-600 dark:text-yellow-500",
|
||||
info: "text-blue-600 dark:text-blue-500",
|
||||
modern: "text-teal-600 dark:text-teal-500",
|
||||
},
|
||||
outlineHover: {
|
||||
white: "hover:bg-gray-100 hover:text-gray-900 dark:hover:text-slate-900",
|
||||
contrast: "hover:bg-gray-800 hover:text-gray-100 hover:dark:bg-slate-100 hover:dark:text-black",
|
||||
light: "hover:bg-gray-100 hover:text-gray-900 dark:hover:text-slate-900",
|
||||
success: "hover:bg-emerald-600 hover:text-white hover:text-white hover:dark:text-white hover:dark:border-emerald-600",
|
||||
danger: "hover:bg-red-600 hover:text-white hover:text-white hover:dark:text-white hover:dark:border-red-600",
|
||||
warning: "hover:bg-yellow-600 hover:text-white hover:text-white hover:dark:text-white hover:dark:border-yellow-600",
|
||||
info: "hover:bg-blue-600 hover:text-white hover:dark:text-white hover:dark:border-blue-600",
|
||||
modern: "hover:bg-teal-600 hover:text-teal hover:dark:bg-teal-100 hover:dark:text-black",
|
||||
},
|
||||
};
|
||||
|
||||
if (!colors.bg[color]) {
|
||||
return color;
|
||||
}
|
||||
|
||||
const base = [isOutlined ? colors.text[color] : colors.bg[color], colors.borders[color]];
|
||||
|
||||
if (hasHover) {
|
||||
base.push(isOutlined ? colors.outlineHover[color] : colors.bgHover[color]);
|
||||
}
|
||||
|
||||
return base;
|
||||
};
|
||||
117
src/components/BaseButton.vue
Normal file
117
src/components/BaseButton.vue
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<script setup="ts">
|
||||
import { computed } from "vue";
|
||||
// import { Link } from '@inertiajs/vue3';
|
||||
// import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { getButtonColor } from "@/colors";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
type: [String, Number],
|
||||
default: null,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
href: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
target: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
routeName: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "white",
|
||||
},
|
||||
as: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
small: Boolean,
|
||||
outline: Boolean,
|
||||
active: Boolean,
|
||||
disabled: Boolean,
|
||||
roundedFull: Boolean,
|
||||
});
|
||||
|
||||
const is = computed(() => {
|
||||
if (props.as) {
|
||||
return props.as;
|
||||
}
|
||||
|
||||
// if (props.routeName) {
|
||||
// return Link;
|
||||
// }
|
||||
|
||||
if (props.href) {
|
||||
return "a";
|
||||
}
|
||||
|
||||
return "button";
|
||||
});
|
||||
|
||||
const computedType = computed(() => {
|
||||
if (is.value === "button") {
|
||||
return props.type ?? "button";
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
const labelClass = computed(() => (props.small && props.icon ? "px-1" : "px-2"));
|
||||
|
||||
const componentClass = computed(() => {
|
||||
const base = [
|
||||
"inline-flex",
|
||||
"cursor-pointer",
|
||||
"justify-center",
|
||||
"items-center",
|
||||
"whitespace-nowrap",
|
||||
"focus:outline-none",
|
||||
"transition-colors",
|
||||
"focus:ring-2",
|
||||
"duration-150",
|
||||
"border",
|
||||
props.roundedFull ? "rounded-full" : "rounded",
|
||||
props.active ? "ring ring-black dark:ring-white" : "ring-blue-700",
|
||||
getButtonColor(props.color, props.outline, !props.disabled),
|
||||
];
|
||||
|
||||
if (props.small) {
|
||||
base.push("text-sm", props.roundedFull ? "px-3 py-1" : "p-1");
|
||||
} else {
|
||||
base.push("py-2", props.roundedFull ? "px-6" : "px-3");
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
base.push("cursor-not-allowed", props.outline ? "opacity-50" : "opacity-70");
|
||||
}
|
||||
|
||||
return base;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
v-bind:is="is"
|
||||
v-bind:class="componentClass"
|
||||
v-bind:href="routeName ? routeName : href"
|
||||
v-bind:type="computedType"
|
||||
v-bind:target="target"
|
||||
v-bind:disabled="disabled"
|
||||
>
|
||||
<BaseIcon v-if="icon" v-bind:path="icon" />
|
||||
<span v-if="label" v-bind:class="labelClass">{{ label }}</span>
|
||||
</component>
|
||||
</template>
|
||||
32
src/components/BaseIcon.vue
Normal file
32
src/components/BaseIcon.vue
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
path: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
w: {
|
||||
type: String,
|
||||
default: "w-6",
|
||||
},
|
||||
h: {
|
||||
type: String,
|
||||
default: "h-6",
|
||||
},
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 16,
|
||||
},
|
||||
});
|
||||
|
||||
const spanClass = computed(() => `inline-flex justify-center items-center ${props.w} ${props.h}`);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-bind:class="spanClass">
|
||||
<svg viewBox="0 0 24 24" v-bind:width="size" v-bind:height="size" class="inline-block">
|
||||
<path fill="currentColor" v-bind:d="path" />
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop } from "vue-property-decorator";
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
// import { Prop } from "vue-property-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "HelloWorld",
|
||||
})
|
||||
export default class HelloWorld extends Vue {
|
||||
|
|
|
|||
188
src/components/PaginationComponent.vue
Normal file
188
src/components/PaginationComponent.vue
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
// const nextPageLink = computed(() => {
|
||||
// const url = new URL(document.location);
|
||||
// url.searchParams.set("page", props.data.currentPage + 1);
|
||||
// return url.href;
|
||||
// // return url + '&page=' + (Number(props.data.currentPage) + 1);
|
||||
// });
|
||||
// const prevPageLink = computed(() => {
|
||||
// const url = new URL(document.location);
|
||||
// url.searchParams.set("page", props.data.currentPage - 1);
|
||||
// return url.href;
|
||||
// // return url + '&page=' + (props.data.currentPage - 1);
|
||||
// });
|
||||
const toPage = computed(() => {
|
||||
const currentPage = props.data.currentPage;
|
||||
const perPage = props.data.perPage;
|
||||
|
||||
if (props.data.currentPage == props.data.lastPage) {
|
||||
return props.data.total;
|
||||
} else {
|
||||
return currentPage * perPage;
|
||||
}
|
||||
});
|
||||
const fromPage = computed(() => {
|
||||
const currentPage = props.data.currentPage;
|
||||
const perPage = props.data.perPage;
|
||||
return currentPage * perPage - (perPage - 1);
|
||||
});
|
||||
|
||||
const emit = defineEmits(["menu-click"]);
|
||||
|
||||
const nextClick = () => {
|
||||
const nextPage = props.data.currentPage + 1;
|
||||
emit("menu-click", nextPage);
|
||||
};
|
||||
const prevClick = () => {
|
||||
const prevPage = props.data.currentPage - 1;
|
||||
emit("menu-click", prevPage);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <nav v-if="data.links.length > 3" -->
|
||||
<nav v-if="data.total > 3" role="navigation" aria-label="Pagination Navigation" class="flex items-center justify-between">
|
||||
<div id="mobileMenu" class="flex justify-between flex-1 sm:hidden">
|
||||
<span
|
||||
v-if="data.currentPage <= 1"
|
||||
aria-disabled="true"
|
||||
class="cursor-not-allowed opacity-50 relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md"
|
||||
>
|
||||
Previous
|
||||
</span>
|
||||
<!-- v-bind:href="data.previousPageUrl" -->
|
||||
<a
|
||||
v-else
|
||||
class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150"
|
||||
@click="prevClick"
|
||||
>
|
||||
Previous
|
||||
</a>
|
||||
|
||||
<!-- v-bind:href="data.nextPageUrl" -->
|
||||
<a
|
||||
v-if="data.currentPage < data.lastPage"
|
||||
class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150"
|
||||
@click="nextClick"
|
||||
>
|
||||
Next
|
||||
</a>
|
||||
<span
|
||||
v-else
|
||||
aria-disabled="true"
|
||||
class="cursor-not-allowed opacity-50 relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md"
|
||||
>
|
||||
Next
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div id="frontText" class="w-full text-right mr-4">
|
||||
<p class="text-sm text-gray-700 leading-5">
|
||||
Showing
|
||||
<span class="font-medium">{{ fromPage }}</span>
|
||||
to
|
||||
<span class="font-medium">{{ toPage }}</span>
|
||||
of
|
||||
<span class="font-medium">{{ data.total }}</span>
|
||||
results
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="relative z-0 inline-flex shadow-sm rounded-md">
|
||||
<!-- previous button -->
|
||||
<span v-if="props.data.currentPage <= 1" aria-disabled="true" aria-label="Previous">
|
||||
<span
|
||||
aria-disabled="true"
|
||||
class="bg-gray-300 cursor-not-allowed opacity-30 relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<!-- v-bind:href="prevPageLink" -->
|
||||
<a
|
||||
v-else
|
||||
rel="prev"
|
||||
class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150"
|
||||
aria-label="Previous"
|
||||
@click="prevClick"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<!-- <template v-for="(link, key) in data.links">
|
||||
<template v-if="key > 0 && key < data.lastPage + 1">
|
||||
<span v-if="!link.active && link.url === null" :key="key" aria-disabled="true">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">{{ link.label }}</span>
|
||||
</span>
|
||||
|
||||
<span v-else-if="link.active" :key="`current-${key}`" aria-current="page">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5">{{ link.label }}</span>
|
||||
</span>
|
||||
|
||||
<Link v-else :key="`link-${key}`" :href="link.url" v-html="link.label" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="`Go to page ${link.label}`" />
|
||||
</template>
|
||||
</template> -->
|
||||
|
||||
|
||||
<!-- next button ----------------------------------------------------------------------------- -->
|
||||
<!-- v-bind:href="nextPageLink" -->
|
||||
<a
|
||||
v-if="props.data.currentPage < props.data.lastPage"
|
||||
rel="next"
|
||||
class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150"
|
||||
aria-label="Next"
|
||||
@click="nextClick"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<!-- else disabled link -->
|
||||
<span v-else aria-disabled="true" aria-label="Next">
|
||||
<span
|
||||
aria-disabled="true"
|
||||
class="opacity-30 bg-gray-300 cursor-not-allowed relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
30
src/components/SectionBanner.vue
Normal file
30
src/components/SectionBanner.vue
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { gradientBgPurplePink, gradientBgPinkRed, gradientBgGreenBlue } from "@/colors";
|
||||
|
||||
const props = defineProps({
|
||||
bg: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (value) => ["purplePink", "pinkRed", "greenBlue"].includes(value),
|
||||
},
|
||||
});
|
||||
|
||||
const colorClass = computed(() => {
|
||||
switch (props.bg) {
|
||||
case "purplePink":
|
||||
return gradientBgPurplePink;
|
||||
case "pinkRed":
|
||||
return gradientBgPinkRed;
|
||||
case "greenBlue":
|
||||
return gradientBgGreenBlue;
|
||||
}
|
||||
|
||||
return "";
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div v-bind:class="colorClass" class="mt-6 mb-6 rounded-2xl py-12 px-6 text-center">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
13
src/components/SectionBannerStarOnGitea.vue
Normal file
13
src/components/SectionBannerStarOnGitea.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { mdiGithub } from "@mdi/js";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import SectionBanner from "@/components/SectionBanner.vue";
|
||||
</script>
|
||||
<template>
|
||||
<SectionBanner bg="greenBlue">
|
||||
<h1 class="text-3xl text-white mb-6">Like the project? Please star on <b>Gitea</b>!</h1>
|
||||
<div>
|
||||
<BaseButton href="https://gitea.geologie.ac.at/geolba/tethys" v-bind:icon="mdiGithub" v-bind:roundedFull="true" label="Gitea" target="_blank" />
|
||||
</div>
|
||||
</SectionBanner>
|
||||
</template>
|
||||
|
|
@ -1,23 +1,81 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop, Emit } from "vue-property-decorator";
|
||||
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||
// import { Prop, Emit } from "vue-property-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "ActiveFacetCategory",
|
||||
})
|
||||
export default class ActiveFacetCategory extends Vue {
|
||||
bar = "";
|
||||
|
||||
@Prop([Array])
|
||||
@Prop({
|
||||
type: Array<string>,
|
||||
})
|
||||
filterItems!: string[];
|
||||
|
||||
@Prop([String])
|
||||
@Prop({
|
||||
type: String,
|
||||
required: true,
|
||||
})
|
||||
categoryName!: string;
|
||||
|
||||
|
||||
replacements = new Map<string, string>([
|
||||
["gis", "GIS"],
|
||||
["analysisdata", "Analysis Data"],
|
||||
["models", "Models"],
|
||||
["monitoring", "Monitoring"],
|
||||
["measurementdata", "Measurement Data"],
|
||||
["mixedtype", "Mixed Type"],
|
||||
["de", "Deutsch"],
|
||||
["en", "English"]
|
||||
]);
|
||||
|
||||
// @Prop([String])
|
||||
// alias;
|
||||
|
||||
get alias(): string {
|
||||
return this.categoryName == "doctype" ? "datatype" : this.categoryName;
|
||||
/**
|
||||
* 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"
|
||||
* TODO: This should be corrected directly in the index
|
||||
*/
|
||||
get categoryAlias(): string {
|
||||
// return this.categoryName == "doctype" ? "datatype" : this.categoryName;
|
||||
// console.log("getAlias!");
|
||||
switch (this.categoryName) {
|
||||
case "author":
|
||||
return "creator";
|
||||
case "subjects":
|
||||
return "keyword";
|
||||
case "doctype":
|
||||
return "data type";
|
||||
default:
|
||||
return this.categoryName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* If the category alias is Data Type, the name of the items is set
|
||||
* NOTE: This could be corrected directly in the index
|
||||
*/
|
||||
getFilterItemsAlias(categoryAlias: string): string {
|
||||
console.log(categoryAlias);
|
||||
if (categoryAlias === ("data type") || categoryAlias === ("language")) {
|
||||
/**
|
||||
* Iterate over the filterItems array using the map method to create a new array (updatedItems).
|
||||
* For each item in the array, check if the item exists as a key in the replacements map.
|
||||
* - If the item exists in the replacements map, replace it with the corresponding value from the map.
|
||||
* - If the item does not exist in the replacements map, keep the original item unchanged.
|
||||
* The map method returns a new array where each element is either the original item or its replacement.
|
||||
* */
|
||||
const updatedItems = this.filterItems.map((item) =>
|
||||
this.replacements.get(item) || item
|
||||
);
|
||||
|
||||
return updatedItems.join(" | ");
|
||||
}
|
||||
|
||||
// console.log("other categories");
|
||||
return this.filterItems.join(" | ");
|
||||
}
|
||||
|
||||
// get filterItems(): Array<string> {
|
||||
|
|
@ -45,7 +103,7 @@ export default class ActiveFacetCategory extends Vue {
|
|||
// }
|
||||
// }
|
||||
|
||||
@Emit("clearFacetCategory")
|
||||
@Emit("clear-facet-category")
|
||||
deactivateFacetCategory(): string {
|
||||
// filterItem.Category = this.alias;
|
||||
// filterItem.Active = true;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<div>
|
||||
<input v-bind:id="alias" v-bind:name="alias" type="checkbox" checked="checked" @click.prevent="deactivateFacetCategory()" class="css-checkbox" />
|
||||
<label v-bind:for="alias" class="css-label">
|
||||
<span>{{ alias + ": " }}</span>
|
||||
<a class="gbaterm" v-if="filterItems && filterItems.length > 0">{{ filterItems.join(", ") }}</a>
|
||||
<input v-bind:id="categoryAlias" v-bind:name="categoryAlias" type="checkbox" checked="checked" class="css-checkbox" @click.prevent="deactivateFacetCategory()" />
|
||||
<label v-bind:for="categoryAlias" class="css-label">
|
||||
<span>{{ categoryAlias + ": " }}</span>
|
||||
<!-- <a v-if="filterItems && filterItems.length > 0" class="gsaterm">{{ filterItems.join(" | ") }}</a> -->
|
||||
<a v-if="filterItems && filterItems.length > 0" class="gsaterm">{{ getFilterItemsAlias(categoryAlias) }}</a>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -18,7 +19,7 @@ th,
|
|||
td {
|
||||
border-bottom: 0px solid #e1e1e1;
|
||||
}
|
||||
.gbaterm {
|
||||
.gsaterm {
|
||||
color: #0099cc;
|
||||
border: 1px solid rgb(200, 210, 255);
|
||||
padding: 4px;
|
||||
|
|
@ -42,6 +43,7 @@ input[type="checkbox"].css-checkbox {
|
|||
}
|
||||
|
||||
input[type="checkbox"].css-checkbox + label.css-label {
|
||||
text-transform: capitalize;
|
||||
padding-left: 25px;
|
||||
/* height: 24px;
|
||||
display: inline-block; */
|
||||
|
|
|
|||
144
src/components/datacite/BaseWidget.ts
Normal file
144
src/components/datacite/BaseWidget.ts
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import axios from "axios";
|
||||
import { ComponentBase, Vue, Prop } from "vue-facing-decorator";
|
||||
import testLogo from "@/assets/datacite/testLogo.vue";
|
||||
|
||||
const APIURL = "https://api.datacite.org";
|
||||
|
||||
interface DataciteResponse {
|
||||
// [key: string]: any;
|
||||
views: number;
|
||||
downloads: number;
|
||||
citations: number;
|
||||
datacite: number;
|
||||
}
|
||||
|
||||
@ComponentBase({
|
||||
name: "BaseWidget",
|
||||
components: {
|
||||
testLogo,
|
||||
},
|
||||
})
|
||||
export default class BaseWidget extends Vue {
|
||||
@Prop({
|
||||
type: Object,
|
||||
required: false,
|
||||
validator(value) {
|
||||
const keys = Object.keys(value);
|
||||
return ["citations", "views", "downloads"].some((r) => keys.includes(r));
|
||||
},
|
||||
})
|
||||
dataInput!: DataciteResponse;
|
||||
|
||||
@Prop({
|
||||
type: String,
|
||||
required: true,
|
||||
validator(value) {
|
||||
return value.match(/^10\.\d{4,5}\/[-._;()/:a-zA-Z0-9*~$=]+/);
|
||||
},
|
||||
})
|
||||
doi!: string;
|
||||
|
||||
@Prop({
|
||||
type: String,
|
||||
required: true,
|
||||
validator(value) {
|
||||
return ["small", "medium", "datacite", "regular"].indexOf(value) > -1;
|
||||
},
|
||||
})
|
||||
display!: string;
|
||||
|
||||
public views = "";
|
||||
public citations = "";
|
||||
public downloads = "";
|
||||
private datacite: string | number = "";
|
||||
private loading = false;
|
||||
private errored = false;
|
||||
|
||||
get url() {
|
||||
return `${APIURL}/graphql`;
|
||||
}
|
||||
|
||||
get link() {
|
||||
return `https://commons.datacite.org/doi.org/${this.doi}`;
|
||||
}
|
||||
// get dataInputApi() {
|
||||
// return this.viewsDistribution;
|
||||
// }
|
||||
get alt() {
|
||||
return `${Number(this.views)} Views ${Number(this.downloads)} Downloads ${Number(this.citations)} Citations from DataCite`;
|
||||
}
|
||||
get tooltip() {
|
||||
let message = "";
|
||||
message += `${this.doi} `;
|
||||
message += this.datacite ? `${this.datacite} from DataCite ` : "";
|
||||
return message;
|
||||
}
|
||||
|
||||
getMetrics() {
|
||||
if (this.isLocal() === false) {
|
||||
this.requestMetrics();
|
||||
} else {
|
||||
this.grabMetrics(this.dataInput);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public pluralize(value: number | string = 0, label: string) {
|
||||
if (value === 1) {
|
||||
return `${value.toLocaleString("en-us")} ${label}`;
|
||||
}
|
||||
return `${value.toLocaleString("en-us")} ${label}s`;
|
||||
}
|
||||
|
||||
public formatNumbers(num: number) {
|
||||
if (num < 1e3) return num;
|
||||
if (num >= 1e3 && num < 1e6) return `${+(num / 1e3).toFixed(1)}K`;
|
||||
if (num >= 1e6 && num < 1e9) return `${+(num / 1e6).toFixed(1)}M`;
|
||||
if (num >= 1e9 && num < 1e12) return `${+(num / 1e9).toFixed(1)}B`;
|
||||
if (num >= 1e12) return `${+(num / 1e12).toFixed(1)}T`;
|
||||
return num;
|
||||
}
|
||||
|
||||
private isLocal(): boolean {
|
||||
if (this.dataInput == null && typeof this.doi !== "undefined") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private grabMetrics(data: DataciteResponse) {
|
||||
this.views = (this.formatNumbers(data.views) as string) || "";
|
||||
this.downloads = (this.formatNumbers(data.downloads) as string) || "";
|
||||
this.citations = (this.formatNumbers(data.citations) as string) || "";
|
||||
this.datacite = this.formatNumbers(data.datacite) || "";
|
||||
}
|
||||
|
||||
private requestMetrics() {
|
||||
axios({
|
||||
url: this.url,
|
||||
method: "post",
|
||||
data: {
|
||||
query: `
|
||||
{
|
||||
counts: work(id: "${this.doi}") {
|
||||
id
|
||||
views: viewCount
|
||||
downloads: downloadCount
|
||||
citations: citationCount
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
this.grabMetrics(response.data.data.counts);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
this.errored = true;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
43
src/components/datacite/BaseWidget.vue
Normal file
43
src/components/datacite/BaseWidget.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<script lang="ts">
|
||||
import BaseWidget from "./BaseWidget";
|
||||
export default BaseWidget;
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
/* https://stackoverflow.com/questions/12675622/script1028-expected-identifier-string-or-number */
|
||||
.icon-metrics {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
a {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-family: "Cairo", "Helvetica", Arial, sans-serif;
|
||||
vertical-align: top;
|
||||
}
|
||||
a {
|
||||
color: #222222;
|
||||
-webkit-transition: all 150ms linear;
|
||||
-moz-transition: all 150ms linear;
|
||||
-o-transition: all 150ms linear;
|
||||
-ms-transition: all 150ms linear;
|
||||
transition: all 150ms linear;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: #222222;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:focus,
|
||||
a:active {
|
||||
outline: 0;
|
||||
}
|
||||
a,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
63
src/components/datacite/DataMetricsBadge.vue
Normal file
63
src/components/datacite/DataMetricsBadge.vue
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<div v-bind:title="'Metrics for DOI: ' + doi">
|
||||
<div v-if="doi">
|
||||
<!-- <div v-if="display == 'small'"> -->
|
||||
<SmallWidget v-bind:doi="doi" v-bind:display="display" v-bind:data-input="dataObject" />
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
<a v-else>There is no DOI</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import SmallWidget from "./SmallWidget.vue";
|
||||
// import MediumWidget from "./MediumWidget.vue";
|
||||
// import DataCiteWidget from "./DataCiteWidget.vue";
|
||||
// import RegularWidget from "./RegularWidget.vue";
|
||||
|
||||
import { Vue, Component, Prop } from "vue-facing-decorator";
|
||||
|
||||
@Component({
|
||||
name: "DataMetricsBadge",
|
||||
components: {
|
||||
// MediumWidget,
|
||||
SmallWidget,
|
||||
// DataCiteWidget,
|
||||
// RegularWidget,
|
||||
},
|
||||
})
|
||||
export default class DataMetricsBadge extends Vue {
|
||||
name = "DataMetricsBadge";
|
||||
funtional = true;
|
||||
|
||||
@Prop({
|
||||
type: Object,
|
||||
})
|
||||
dataInput!: object;
|
||||
|
||||
@Prop({
|
||||
type: String,
|
||||
default: "",
|
||||
})
|
||||
doi!: string;
|
||||
|
||||
@Prop({
|
||||
type: String,
|
||||
required: false,
|
||||
validator(value) {
|
||||
return ["small", "medium", "datacite", "regular"].indexOf(value) > -1;
|
||||
},
|
||||
default: "small",
|
||||
})
|
||||
display!: string;
|
||||
|
||||
get dataObject() {
|
||||
// if (typeof this.dataInput !== "undefined") {
|
||||
return this.dataInput;
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
143
src/components/datacite/SmallWidget.vue
Normal file
143
src/components/datacite/SmallWidget.vue
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div class="small-container">
|
||||
<a v-bind:href="link">
|
||||
<div class="d-flex">
|
||||
<!-- <test-logo v-bind:class="'svglogo'" /> -->
|
||||
<div v-bind:class="['', '0', 0].includes(citations) == false ? activeClass : inactiveClass">Citations</div>
|
||||
<div class="p-2 counts" v-bind:title="pluralize(citations, 'Citation')">
|
||||
{{ formatNumbers(["", "0", 0].includes(citations) == false ? citations : " ") }}
|
||||
</div>
|
||||
<div class="p-2 span" />
|
||||
|
||||
<div v-if="parseInt(views) + parseInt(downloads) > 0" class="d-flex">
|
||||
<div v-bind:class="['', '0', 0].includes(views) == false ? activeClass : inactiveClass">Views</div>
|
||||
<div class="p-2 counts" v-bind:title="pluralize(views, 'View')">
|
||||
{{ formatNumbers(["", "0", 0].includes(views) == false ? views : " ") }}
|
||||
</div>
|
||||
<div class="p-2 span" />
|
||||
|
||||
<div v-bind:class="['', '0', 0].includes(downloads) == false ? activeClass : inactiveClass">Downloads</div>
|
||||
<div class="p-2 counts" v-bind:title="pluralize(downloads, 'Download')">
|
||||
{{ formatNumbers(["", "0", 0].includes(downloads) == false ? downloads : " ") }}
|
||||
</div>
|
||||
<div class="p-2 span" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from "vue-facing-decorator";
|
||||
import BaseWidget from "./BaseWidget.vue";
|
||||
// import testLogo from "@/assets/datacite/testLogo.vue";
|
||||
|
||||
@Component({
|
||||
name: "SmallWidget",
|
||||
})
|
||||
export default class SmallWidget extends BaseWidget {
|
||||
public activeClass = "p-2 label";
|
||||
public inactiveClass = "p-2 label-empty";
|
||||
|
||||
public mounted(): void {
|
||||
this.getMetrics();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
div.label {
|
||||
background-color: rgba(0, 89, 173);
|
||||
display: table;
|
||||
width: 8%;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
border-style: solid;
|
||||
/* font-weight: bold; */
|
||||
border-color: rgba(0, 89, 173);
|
||||
border-width: thin;
|
||||
/* text-align: center; */
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
div.logo {
|
||||
min-width: 100px;
|
||||
padding: 0px 0px 0px 0px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.svglogo {
|
||||
color: #455a64;
|
||||
fill: #455a64;
|
||||
display: table;
|
||||
width: 20%;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
div.counts {
|
||||
background-color: white;
|
||||
display: table;
|
||||
/* font-size: 2.5vh; */
|
||||
font-size: 12px;
|
||||
width: 6%;
|
||||
border-style: solid;
|
||||
font-weight: bold;
|
||||
border-color: #78909c;
|
||||
border-width: thin;
|
||||
text-align: center;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
div.span {
|
||||
background-color: white;
|
||||
display: table;
|
||||
font-size: 2.5vh;
|
||||
width: 2%;
|
||||
}
|
||||
|
||||
.small-container {
|
||||
width: 100%;
|
||||
min-width: 400px;
|
||||
max-width: 400px;
|
||||
/*
|
||||
max-height: 15px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px; */
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
/* font-family: Arial, Helvetica, sans-serif; */
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: -ms-flexbox !important;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: 0.1rem !important;
|
||||
}
|
||||
|
||||
.label-empty {
|
||||
background-color: #78909c;
|
||||
display: table;
|
||||
width: 8%;
|
||||
color: white;
|
||||
/* font-size: 2.5vh; */
|
||||
font-size: 12px;
|
||||
border-style: solid;
|
||||
font-weight: bold;
|
||||
border-color: #78909c;
|
||||
border-width: thin;
|
||||
text-align: center;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import { FacetItem } from "@/models/headers";
|
||||
// import { FilterItem } from "@/models/solr";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop, Emit } from "vue-property-decorator";
|
||||
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||
// import { Prop, Emit } from "vue-property-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "FacetCategory",
|
||||
})
|
||||
export default class FacetCategory extends Vue {
|
||||
|
|
@ -14,11 +14,49 @@ export default class FacetCategory extends Vue {
|
|||
@Prop()
|
||||
facetItems!: Array<FacetItem>;
|
||||
|
||||
@Prop([String])
|
||||
@Prop({
|
||||
type: String,
|
||||
})
|
||||
filterName!: string;
|
||||
|
||||
get alias(): string {
|
||||
return this.filterName == "datatype" ? "doctype" : this.filterName;
|
||||
replacements = new Map<string, string>([
|
||||
["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 filterItems(): Array<FilterItem> {
|
||||
|
|
@ -41,19 +79,34 @@ export default class FacetCategory extends Vue {
|
|||
}
|
||||
|
||||
toggle(): void {
|
||||
if (this.collapsed == true) {
|
||||
this.collapsed = false;
|
||||
} else if (this.collapsed == false) {
|
||||
this.collapsed = true;
|
||||
//list.children("li:gt(4)").hide();
|
||||
this.collapsed = !this.collapsed;
|
||||
|
||||
// Scroll to the top of the page only when collapsing
|
||||
if (this.collapsed) {
|
||||
this.scrollTop();
|
||||
}
|
||||
}
|
||||
|
||||
@Emit("filter")
|
||||
activateItem(filterItem: FacetItem): FacetItem {
|
||||
filterItem.category = this.alias;
|
||||
console.log("Emit: ActivateItem");
|
||||
// filterItem.category = this.alias;
|
||||
filterItem.category = this.filterName;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@
|
|||
<div class="card panel-default">
|
||||
<!-- <h3 class="panel-title filterViewModelName">{{ filterName }}</h3> -->
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title titlecase filterViewModelName">{{ filterName }}</h3>
|
||||
<h3 class="panel-title titlecase filterViewModelName">{{ categoryAlias }}</h3>
|
||||
<!-- <h3 class="panel-title titlecase filterViewModelName">{{ filterName }}</h3> -->
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<!-- e.g.language -->
|
||||
<ul class="filter-items list-unstyled" v-bind:class="{ limited: facetItems.length > 1 && collapsed }">
|
||||
<li v-for="(item, index) in facetItems" :key="index" class="list-group-item titlecase">
|
||||
<li v-for="(item, index) in facetItems" v-bind:key="index" class="list-group-item titlecase">
|
||||
<!-- <span :class="item.Active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span> -->
|
||||
<span :class="item.active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span>
|
||||
<!-- <span v-bind:class="item.active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span> -->
|
||||
<span v-bind:class="item.active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ itemAlias(item.val) }} ({{ item.count }}) </span>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- <ul class="overflowing" v-if="overflowing == true">
|
||||
|
|
@ -18,7 +20,7 @@
|
|||
</li>
|
||||
</ul> -->
|
||||
</div>
|
||||
<div class="card-footer" v-if="facetItems.length > 2">
|
||||
<div v-if="facetItems.length > 2" class="card-footer">
|
||||
<p class="card-footer-item">
|
||||
<!-- <span @click="toggle()">{{ uncollapseLabelText }}</span> -->
|
||||
<span v-if="collapsed" @click="toggle()">
|
||||
|
|
@ -74,7 +76,10 @@ export default FacetCategory;
|
|||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
/* padding: 0.75rem; */
|
||||
padding: 0.75em 2em;
|
||||
padding-top: 0em;
|
||||
padding-right: 2em;
|
||||
padding-bottom: 0.75em;
|
||||
padding-left: 2em;
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +92,7 @@ export default FacetCategory;
|
|||
}
|
||||
.panel-body {
|
||||
padding: 0 2em;
|
||||
padding-bottom: 0.75em; /* Increase padding at the bottom */
|
||||
}
|
||||
|
||||
.disabled {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
// import { Prop, Emit } from "vue-property-decorator";
|
||||
import { Prop } from "vue-property-decorator";
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
import { LatLng, LatLngBounds, Map, MapOptions, Rectangle, tileLayer, TileLayer, CRS } from "leaflet";
|
||||
// import { LayerOptions } from "./map-options";
|
||||
import DatasetService from "../../services/dataset.service";
|
||||
// import DatasetService from "../../services/dataset.service";
|
||||
import { Subscription } from "rxjs";
|
||||
import { OaiDataset } from "@/models/oai";
|
||||
|
||||
const DEFAULT_BASE_LAYER_NAME = "BaseLayer";
|
||||
// const DEFAULT_BASE_LAYER_URL = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
|
||||
const DEFAULT_BASE_LAYER_ATTRIBUTION = '© <a href="http://basemap.at" target="_blank">Basemap.at</a>, <a href="http://www.geologie.ac.at" target="_blank">Geologie.ac.at</a>';
|
||||
const DEFAULT_BASE_LAYER_ATTRIBUTION =
|
||||
'© <a href="http://basemap.at" target="_blank">Basemap.at</a>, <a href="http://www.geologie.ac.at" target="_blank">Geologie.ac.at</a>';
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
// selector: "app-map",
|
||||
// templateUrl: "map.component.html",
|
||||
name: "MapComponent",
|
||||
|
|
|
|||
112
src/components/minimap/Minimap.ts
Normal file
112
src/components/minimap/Minimap.ts
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import { Component, Prop, Vue } from 'vue-facing-decorator';
|
||||
import * as L from 'leaflet';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
|
||||
@Component({
|
||||
name: 'Minimap',
|
||||
})
|
||||
export default class Minimap extends Vue {
|
||||
@Prop({ type: Array, required: true }) bounds!: L.LatLngBoundsLiteral;
|
||||
|
||||
// private originalCenter: L.LatLngExpression = [47.71, 13.55]; // Original center
|
||||
// private originalZoom: number = 6; // Original zoom level
|
||||
|
||||
/**
|
||||
* Lifecycle hook called when the component is mounted.
|
||||
* Initializes the Leaflet map, sets up base layers, and adds either a circle or rectangle
|
||||
* based on the `bounds` prop passed to the component.
|
||||
*/
|
||||
mounted() {
|
||||
// Initialize the map with specific center and zoom
|
||||
const map = L.map('map', {
|
||||
center: [47.71, 13.55], // Initial center coordinates
|
||||
zoomControl: true, // Enable zoom controls
|
||||
zoom: 6, // Initial zoom level
|
||||
minZoom: 5, // Minimum zoom level allowed
|
||||
maxBounds: [
|
||||
[44.0, 9.0], // Southwest corner of the bounding box
|
||||
[51.0, 18.0] // Northeast corner of the bounding box
|
||||
],
|
||||
maxBoundsViscosity: 1.0 // Prevent map from being dragged outside the defined bounds
|
||||
});
|
||||
|
||||
// Remove Leaflet logo and text
|
||||
map.attributionControl.setPrefix(false);
|
||||
|
||||
// Add basemap.at tile layer to the map
|
||||
const basemapAtLayer = L.tileLayer('https://maps{s}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png', {
|
||||
attribution: '<a href="https://www.basemap.at">basemap.at</a>',
|
||||
noWrap: true,
|
||||
subdomains: ['', '1', '2', '3', '4']
|
||||
}).addTo(map);
|
||||
|
||||
// Add Esri imagery tile layer
|
||||
const esriImageryLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © <a href="https://www.esri.com/" target="_blank">Esri</a>'
|
||||
});
|
||||
|
||||
// Add Esri topo map tile layer
|
||||
const esriTopoLayer = L.tileLayer('https://server.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © <a href="https://www.esri.com/" target="_blank">Esri</a>'
|
||||
});
|
||||
|
||||
// Define available base maps for the user to toggle between
|
||||
const baseMaps = {
|
||||
// "OpenStreetMap": openStreetMapLayer,
|
||||
"basemap.at": basemapAtLayer,
|
||||
"ESRI Imagery": esriImageryLayer,
|
||||
"ESRI Topo": esriTopoLayer
|
||||
};
|
||||
|
||||
// Define available base maps for the user to toggle between
|
||||
L.control.layers(baseMaps).addTo(map);
|
||||
|
||||
const [southWest, northEast] = this.bounds;
|
||||
|
||||
if (southWest[0] === northEast[0] || southWest[1] === northEast[1]) {
|
||||
// If y_min and y_max (and x_min and x_max) are equal, generate a circle
|
||||
const center = [southWest[0], southWest[1]] as [number, number];
|
||||
// Add a CircleMarker to the map at the center of the bounds. This kind of marker is used to maintain constant size regardless of zoom level
|
||||
const circleMarker = L.circleMarker(center, {
|
||||
color: '#30D5C8', // Outline color
|
||||
fillColor: '#336699', // Fill color
|
||||
fillOpacity: 1, // Opacity of the fill
|
||||
opacity: 0.5, // Outline opacity
|
||||
weight: 10, // Outline weight (thickness)
|
||||
radius: 10 // Radius in pixels
|
||||
}).addTo(map);
|
||||
|
||||
// Manually create a small bounding box around the marker's center to fit bounds
|
||||
const buffer = 0.01; // Buffer size around the marker. Adjust this value to control the area around the marker
|
||||
const markerBounds = L.latLngBounds(
|
||||
[center[0] - buffer, center[1] - buffer], // Southwest corner of the bounding box
|
||||
[center[0] + buffer, center[1] + buffer] // Northeast corner of the bounding box
|
||||
);
|
||||
|
||||
// Add a click event handler to the CircleMarker
|
||||
circleMarker.on('click', () => {
|
||||
map.fitBounds(markerBounds, { padding: [10, 10] }); // Adjust map to fit within marker bounds
|
||||
});
|
||||
|
||||
// Automatically adjust the map's view to fit the marker's bounds
|
||||
map.fitBounds(markerBounds, { padding: [10, 10] });
|
||||
|
||||
} else {
|
||||
// If bounds are not equal, draw a rectangle
|
||||
const rectangle = L.rectangle(this.bounds, {
|
||||
color: '#30D5C8', // Rectangle outline color //Alternative color: 336699
|
||||
weight: 2, // Outline thickness
|
||||
opacity: 1 // Opacity of the rectangle outline
|
||||
}).addTo(map);
|
||||
|
||||
// Add a click event handler to the Rectangle
|
||||
rectangle.on('click', () => {
|
||||
map.fitBounds(this.bounds, { padding: [18, 18] }); // Adjust map to fit within rectangle bounds
|
||||
});
|
||||
|
||||
// Automatically adjust the map's view to fit the rectangle's bounds with padding
|
||||
map.fitBounds(this.bounds, { padding: [18, 18] });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
16
src/components/minimap/Minimap.vue
Normal file
16
src/components/minimap/Minimap.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!-- Contains the template and references the TypeScript logic. -->
|
||||
<template>
|
||||
<div id="map" style="height: 300px;"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Minimap from './Minimap';
|
||||
export default Minimap;
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#map {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "SimpleSearchComponent",
|
||||
})
|
||||
export default class SimpleSearchComponent extends Vue {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="search-box mx-auto">
|
||||
<div class="field has-addons main-search-from-bg">
|
||||
<div class="control is-expanded">
|
||||
<input id="search_query" class="input is-medium" type="text" name="q" autocomplete="off" v-model="display" />
|
||||
<input id="search_query" v-model="display" class="input is-medium" type="text" name="q" autocomplete="off" />
|
||||
<!-- <p>Message is: {{ display }}</p> v-on:input="searchChanged"-->
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,60 @@
|
|||
// import Vue from "vue";
|
||||
// import { Component, Prop } from 'vue-property-decorator';
|
||||
// import debounce from 'lodash/debounce';
|
||||
// import { DatasetService } from "../../services/dataset.service";
|
||||
import DatasetService from "../../services/dataset.service";
|
||||
import { SolrSettings } from "@/models/solr";
|
||||
// import { ref } from "vue";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop, Emit } from "vue-property-decorator";
|
||||
import { Dataset, Suggestion, SearchType } from "@/models/dataset";
|
||||
import { SOLR_HOST, SOLR_CORE } from "@/constants";
|
||||
// import { SolrSettings } from "@/models/solr"; // PENDING USE
|
||||
|
||||
@Options({
|
||||
import { OpenSettings } from "@/models/solr";
|
||||
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||
import { Dataset, Suggestion, SearchType } from "@/models/dataset";
|
||||
// import { SOLR_HOST, SOLR_CORE } from "@/constants";
|
||||
|
||||
import { OPEN_HOST, OPEN_CORE } from "@/constants"; // PENDING USE
|
||||
import { HitHighlight } from "@/models/headers";
|
||||
|
||||
import DOMPurify from 'dompurify'; // To sanitize the HTML content to prevent XSS attacks!
|
||||
|
||||
@Component({
|
||||
name: "VsInput",
|
||||
})
|
||||
export default class VsInput extends Vue {
|
||||
// @Prop()
|
||||
// private title!: string;
|
||||
|
||||
// Define the placeholder text for the input field
|
||||
@Prop({ default: "Search" })
|
||||
readonly placeholder!: string;
|
||||
|
||||
private display = "";
|
||||
private display = ""; // Input display value
|
||||
|
||||
@Prop()
|
||||
private propDisplay = "";
|
||||
|
||||
private value!: Suggestion | string;
|
||||
private error = "";
|
||||
private results: Array<Dataset> = [];
|
||||
private loading = false;
|
||||
private selectedIndex = 0;
|
||||
private selectedDisplay = "";
|
||||
private solr: SolrSettings = {
|
||||
core: SOLR_CORE, //"rdr_data", // SOLR.core;
|
||||
host: SOLR_HOST, //"tethys.at",
|
||||
private results: Array<Dataset> = []; // Array to store search results
|
||||
private highlights: Array<HitHighlight> = [];
|
||||
|
||||
private loading = false; // Loading state indicator
|
||||
private selectedIndex = -1; // Index of the currently selected suggestion
|
||||
|
||||
// private solr: SolrSettings = {
|
||||
// core: SOLR_CORE, //"rdr_data", // SOLR.core;
|
||||
// host: SOLR_HOST, //"tethys.at",
|
||||
// };
|
||||
|
||||
private openSearch: OpenSettings = {
|
||||
core: OPEN_CORE, //"rdr_data", // SOLR.core;
|
||||
host: OPEN_HOST, //"tethys.at",
|
||||
// core: "test_data", // SOLR.core;
|
||||
// host: "repository.geologie.ac.at",
|
||||
};
|
||||
// private rdrAPI!: DatasetService;
|
||||
itemRefs!: Array<Element>;
|
||||
emits = ["filter"];
|
||||
|
||||
// private rdrAPI!: DatasetService;
|
||||
itemRefs!: Array<Element>; // Array to store references to suggestion items
|
||||
emits = ["filter"]; // Emits filter event
|
||||
|
||||
// Set reference for each item
|
||||
setItemRef(el: Element): void {
|
||||
this.itemRefs.push(el);
|
||||
}
|
||||
|
|
@ -69,53 +83,143 @@ export default class VsInput extends Vue {
|
|||
return this.error !== null;
|
||||
}
|
||||
|
||||
// Computed property to generate suggestions based on search results
|
||||
get suggestions(): Suggestion[] {
|
||||
// const suggestion = {
|
||||
// titles: new Array<string>(),
|
||||
// authors: new Array<string>(),
|
||||
// subjects: new Array<string>(),
|
||||
// };
|
||||
|
||||
const suggestions = new Array<Suggestion>();
|
||||
|
||||
this.results.forEach((dataset) => {
|
||||
// const del = dataset.title_output?.toLowerCase();
|
||||
if (dataset.title_output.toLowerCase().includes(this.display.toLowerCase())) {
|
||||
const title = dataset.title_output;
|
||||
// if (!suggestion["titles"].find((value) => value === title)) {
|
||||
// suggestion.titles.push(title);
|
||||
// }
|
||||
const hasTitleSuggestion = suggestions.some((suggestion) => suggestion.value === title && suggestion.type == SearchType.Title);
|
||||
if (!hasTitleSuggestion) {
|
||||
const suggestion = new Suggestion(title, SearchType.Title);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
if (this.find(dataset.author, this.display.toLowerCase()) !== "") {
|
||||
const author = this.find(dataset.author, this.display.toLowerCase());
|
||||
// console.log("getSuggestions > Display:", this.display);
|
||||
// console.log("results:", this.results );
|
||||
// console.log("highlights:", this.highlights);
|
||||
|
||||
//The method checks if there are any highlighted titles in the highlight object. If found, it joins the highlighted fragments into a single string
|
||||
// Generate suggestions based on search results
|
||||
this.results.forEach((dataset, index) => {
|
||||
|
||||
const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.value === author && suggestion.type == SearchType.Author);
|
||||
const highlight = this.highlights[index];
|
||||
|
||||
// console.log("get suggestions:id", dataset.id);
|
||||
// console.log("get suggestions:title_output", dataset.title_output);
|
||||
// console.log("get suggestions:author", dataset.author);
|
||||
// console.log("get suggestions:subjects", dataset.subjects);
|
||||
|
||||
// Checks if a suggestion with the same title and type already exists in the suggestions array. If not, it creates a new Suggestion object and adds it to the suggestions array.
|
||||
if (highlight.title && highlight.title.length > 0) {
|
||||
/** This line checks if the highlight object has a title property and if that property is an array with at least one element.
|
||||
* The highlight object contains highlighted fragments of the search term in various fields (e.g., title, author, subjects) as returned by the OpenSearch API.
|
||||
* This check ensures that we only process results that have highlighted titles. */
|
||||
const highlightedTitle = highlight.title.join(" ");
|
||||
/**
|
||||
* The highlight.title property is an array of strings, where each string is a highlighted fragment of the title. join(" ") combines these fragments into a single string with spaces between them.
|
||||
* This step constructs a full highlighted title from the individual fragments.
|
||||
* OpenSearch can return multiple fragments of a field (like the title) in its response, especially when the field contains multiple terms that match the search query.
|
||||
* This can happen because OpenSearch's highlighting feature is designed to provide context around each match within the field, which can result in multiple highlighted fragments.
|
||||
*/
|
||||
const hasTitleSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedTitle.toLowerCase() && suggestion.type == SearchType.Title);
|
||||
if (!hasTitleSuggestion) {
|
||||
const suggestion = new Suggestion(dataset.title_output, highlightedTitle, SearchType.Title);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
if (highlight.author && highlight.author.length > 0) {
|
||||
const highlightedAuthor = highlight.author.join(" ");
|
||||
const datasetAuthor = this.find(dataset.author, this.display.toLowerCase());
|
||||
const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedAuthor.toLowerCase() && suggestion.type == SearchType.Author);
|
||||
if (!hasAuthorSuggestion) {
|
||||
const suggestion = new Suggestion(author, SearchType.Author);
|
||||
const suggestion = new Suggestion(datasetAuthor, highlightedAuthor, SearchType.Author);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
if (this.find(dataset.subject, this.display.toLowerCase()) != "") {
|
||||
const subject = this.find(dataset.subject, this.display.toLowerCase());
|
||||
const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.value === subject && suggestion.type == SearchType.Subject);
|
||||
if (highlight.subjects && highlight.subjects.length > 0) {
|
||||
const highlightedSubject = highlight.subjects.join(" ");
|
||||
const datasetSubject = this.find(dataset.subjects, this.display.toLowerCase());
|
||||
const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedSubject.toLowerCase() && suggestion.type == SearchType.Subject);
|
||||
if (!hasSubjectSuggestion) {
|
||||
const suggestion = new Suggestion(subject, SearchType.Subject);
|
||||
const suggestion = new Suggestion(datasetSubject, highlightedSubject, SearchType.Subject);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
// To allow search by doctype
|
||||
if (highlight.doctype && highlight.doctype.length > 0) {
|
||||
const highlightedDoctype = highlight.doctype.join(" ");
|
||||
|
||||
const hasDoctypeSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedDoctype.toLowerCase() && suggestion.type == SearchType.Doctype);
|
||||
if (!hasDoctypeSuggestion) {
|
||||
const suggestion = new Suggestion(dataset.doctype, highlightedDoctype, SearchType.Doctype);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
// ORIGINAL SOLR ===================================================================================================
|
||||
// if (dataset.title_output.toLowerCase().includes(this.display.toLowerCase())) {
|
||||
// const title = dataset.title_output;
|
||||
// // Check if there is already a suggestion with this title and type
|
||||
// const hasTitleSuggestion = suggestions.some((suggestion) => suggestion.value === title && suggestion.type == SearchType.Title);
|
||||
// if (!hasTitleSuggestion) {
|
||||
// // If there is no such suggestion, create a new one and add it to the suggestions array
|
||||
// const suggestion = new Suggestion(title, SearchType.Title);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
// if (this.find(dataset.author, this.display.toLowerCase()) !== "") {
|
||||
// const author = this.find(dataset.author, this.display.toLowerCase());
|
||||
// // Check if there is already a suggestion with this author and type
|
||||
// const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.value === author && suggestion.type == SearchType.Author);
|
||||
// if (!hasAuthorSuggestion) {
|
||||
// const suggestion = new Suggestion(author, SearchType.Author);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
// if (this.find(dataset.subjects, this.display.toLowerCase()) != "") {
|
||||
// const subject = this.find(dataset.subjects, this.display.toLowerCase());
|
||||
// const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.value === subject && suggestion.type == SearchType.Subject);
|
||||
// if (!hasSubjectSuggestion) {
|
||||
// const suggestion = new Suggestion(subject, SearchType.Subject);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
|
||||
});
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method combines the suggestion value and type into a single HTML string. It also sanitizes the HTML content using DOMPurify to prevent XSS attacks.
|
||||
* The vue file uses the v-html directive to bind the combined HTML string to the label element. This ensures that the HTML content (e.g., <em>Wien</em>) is rendered correctly in the browser.
|
||||
*/
|
||||
formatSuggestion(result: Suggestion): string {
|
||||
const sanitizedValue = DOMPurify.sanitize(result.highlight);
|
||||
// Replacing the predefined format for highlights given by OpenSearch from <em> emphasys to <b> bold
|
||||
const replacedValue = sanitizedValue.replace(/<em>/g, '<b>').replace(/<\/em>/g, '</b>');
|
||||
// return `${replacedValue} <em>| ${result.type}</em>`;
|
||||
return `${replacedValue} <em>| ${this.getTypeAlias(result.type)}</em>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The alias for the result 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all values, results and errors
|
||||
**/
|
||||
clear(): void {
|
||||
console.log("clear");
|
||||
this.display = "";
|
||||
// this.value = null;
|
||||
this.results = [];
|
||||
|
|
@ -123,16 +227,21 @@ export default class VsInput extends Vue {
|
|||
// this.$emit("clear");
|
||||
}
|
||||
|
||||
/* When the search button is clicked or the search input is changed, it updates the value property of the component with the current value of display,
|
||||
and emits a search-change event with the current value of display as the argument. */
|
||||
@Emit("search-change")
|
||||
search(): string {
|
||||
console.log("search");
|
||||
this.results = [];
|
||||
// this.$emit("search", this.display)
|
||||
this.value = this.display; //(obj["title_output"]) ? obj["title_output"] : obj.id
|
||||
return this.display;
|
||||
}
|
||||
|
||||
// Handler for search input change
|
||||
searchChanged(): void {
|
||||
this.selectedIndex = 0;
|
||||
// console.log("Search changed!");
|
||||
this.selectedIndex = -1;
|
||||
// Let's warn the parent that a change was made
|
||||
// this.$emit("input", this.display);
|
||||
if (this.display.length >= 2) {
|
||||
|
|
@ -143,7 +252,9 @@ export default class VsInput extends Vue {
|
|||
}
|
||||
}
|
||||
|
||||
// Perform the search request
|
||||
private resourceSearch() {
|
||||
// console.log("resourceSearch");
|
||||
if (!this.display) {
|
||||
this.results = [];
|
||||
return;
|
||||
|
|
@ -153,23 +264,29 @@ export default class VsInput extends Vue {
|
|||
this.request();
|
||||
}
|
||||
|
||||
// Make the API request to search for datasets
|
||||
private request(): void {
|
||||
DatasetService.searchTerm(this.display, this.solr.core, this.solr.host).subscribe(
|
||||
(res: Dataset[]) => this.dataHandler(res),
|
||||
(error: string) => this.errorHandler(error),
|
||||
() => (this.loading = false),
|
||||
);
|
||||
console.log("request()");
|
||||
// DatasetService.searchTerm(this.display, this.solr.core, this.solr.host).subscribe({
|
||||
DatasetService.searchTerm(this.display, this.openSearch.core, this.openSearch.host).subscribe({
|
||||
// next: (res: Dataset[]) => this.dataHandler(res),
|
||||
next: (res: { datasets: Dataset[], highlights: HitHighlight[] }) => this.dataHandler(res.datasets, res.highlights),
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
complete: () => (this.loading = false),
|
||||
});
|
||||
}
|
||||
|
||||
private dataHandler(datasets: Dataset[]): void {
|
||||
// Handle the search results
|
||||
private dataHandler(datasets: Dataset[], highlights: HitHighlight[]): void {
|
||||
this.results = datasets;
|
||||
// this.$emit("search", this.display);
|
||||
// this.loading = false;
|
||||
this.highlights = highlights; // Store highlights
|
||||
// console.log(datasets);
|
||||
|
||||
}
|
||||
|
||||
// Handle errors from the search request
|
||||
private errorHandler(err: string): void {
|
||||
this.error = err;
|
||||
// this.loading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -181,9 +298,11 @@ export default class VsInput extends Vue {
|
|||
return key === this.selectedIndex;
|
||||
}
|
||||
|
||||
// Handle arrow down key press to navigate suggestions
|
||||
onArrowDown(ev: Event): void {
|
||||
console.log("onArrowDown");
|
||||
ev.preventDefault();
|
||||
if (this.selectedIndex === null) {
|
||||
if (this.selectedIndex === -1) {
|
||||
this.selectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
|
@ -191,6 +310,7 @@ export default class VsInput extends Vue {
|
|||
this.fixScrolling();
|
||||
}
|
||||
|
||||
// Scroll the selected suggestion into view
|
||||
private fixScrolling() {
|
||||
const currentElement = this.itemRefs[this.selectedIndex];
|
||||
currentElement.scrollIntoView({
|
||||
|
|
@ -200,9 +320,11 @@ export default class VsInput extends Vue {
|
|||
});
|
||||
}
|
||||
|
||||
// Handle arrow up key press to navigate suggestions
|
||||
onArrowUp(ev: Event): void {
|
||||
console.log("onArrowUp");
|
||||
ev.preventDefault();
|
||||
if (this.selectedIndex === null) {
|
||||
if (this.selectedIndex === -1) {
|
||||
this.selectedIndex = this.suggestions.length - 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -210,29 +332,34 @@ export default class VsInput extends Vue {
|
|||
this.fixScrolling();
|
||||
}
|
||||
|
||||
// Handle enter key press to select a suggestion
|
||||
onEnter(): void {
|
||||
if (this.selectedIndex === null) {
|
||||
console.log("onEnter");
|
||||
|
||||
if (this.selectedIndex === -1) {
|
||||
// this.$emit("nothingSelected", this.display);
|
||||
return;
|
||||
this.display && this.search();
|
||||
} else {
|
||||
this.select(this.suggestions[this.selectedIndex]);
|
||||
}
|
||||
this.select(this.suggestions[this.selectedIndex]);
|
||||
|
||||
// this.$emit("enter", this.display);
|
||||
}
|
||||
|
||||
@Emit("search-change")
|
||||
private select(obj: Suggestion): Suggestion {
|
||||
// if (!obj) {
|
||||
// return;
|
||||
// }
|
||||
this.value = obj; //(obj["title_output"]) ? obj["title_output"] : obj.id
|
||||
this.display = obj.value; // this.formatDisplay(obj)
|
||||
// this.selectedDisplay = this.display;
|
||||
console.log("select:");
|
||||
this.value = obj;
|
||||
console.log(obj);
|
||||
|
||||
this.display = obj.value;
|
||||
|
||||
this.close();
|
||||
// this.$emit("update", this.value);
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
// Find a search term in an array
|
||||
private find(myarray: Array<string>, searchterm: string): string {
|
||||
for (let i = 0, len = myarray.length; i < len; i += 1) {
|
||||
if (typeof myarray[i] === "string" && myarray[i].toLowerCase().indexOf(searchterm) !== -1) {
|
||||
|
|
@ -247,15 +374,11 @@ export default class VsInput extends Vue {
|
|||
* Close the results list. If nothing was selected clear the search
|
||||
*/
|
||||
close(): void {
|
||||
console.log("close");
|
||||
if (!this.value) {
|
||||
this.clear();
|
||||
}
|
||||
// if (this.selectedDisplay !== this.display && this.value) {
|
||||
// this.display = this.selectedDisplay;
|
||||
// }
|
||||
this.results = [];
|
||||
this.error = "";
|
||||
//this.removeEventListener()
|
||||
// this.$emit("close");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +1,63 @@
|
|||
<template>
|
||||
<!-- Parent container with multiple rows -->
|
||||
<div class="is-multiline">
|
||||
<!-- <div class="content column is-half is-offset-one-quarter" style="margin-top: 30px; padding-bottom: 0; margin-bottom: 0px"> -->
|
||||
<!-- Search input wrapper -->
|
||||
<div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen mx-auto">
|
||||
|
||||
<!-- Search box -->
|
||||
<div class="search-box mx-auto">
|
||||
<!-- Search field -->
|
||||
<div class="field has-addons main-search-from-bg">
|
||||
<div class="control is-expanded">
|
||||
<!-- Input field for search query -->
|
||||
<input
|
||||
v-on:input="searchChanged"
|
||||
id="search_query"
|
||||
v-model="display"
|
||||
class="input is-medium"
|
||||
type="text"
|
||||
name="q"
|
||||
autocomplete="off"
|
||||
v-model="display"
|
||||
v-bind:placeholder="placeholder"
|
||||
v-on:keydown.down="onArrowDown"
|
||||
v-on:keydown.up="onArrowUp"
|
||||
v-on:keydown.enter="onEnter"
|
||||
@input="searchChanged"
|
||||
@keydown.down="onArrowDown"
|
||||
@keydown.up="onArrowUp"
|
||||
@keydown.enter="onEnter"
|
||||
@keydown.tab="close"
|
||||
v-on:focus="focus"
|
||||
@focus="focus"
|
||||
/>
|
||||
<!-- <p>Message is: {{ display }}</p> v-on:input="searchChanged"-->
|
||||
</div>
|
||||
|
||||
<!-- Search button -->
|
||||
<div class="control">
|
||||
<button class="button input is-medium search-button-icon" @click="search()">
|
||||
<!-- <img src="../../assets/fa/search.svg" style="height: 22px; width: 22px" /> -->
|
||||
<!-- Search icon -->
|
||||
<i class="fas fa-search text-white"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="column is-half is-offset-one-quarter"> -->
|
||||
<div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen mx-auto">
|
||||
<ul class="autocomplete-results pure-u-23-24" v-show="showResults">
|
||||
<li class="loading" v-if="isLoading">Loading results...</li>
|
||||
|
||||
<!-- Suggestions list -->
|
||||
<div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen mx-auto">
|
||||
<ul v-show="showResults" class="autocomplete-results pure-u-23-24">
|
||||
<!-- Loading indicator -->
|
||||
<li v-if="isLoading" class="loading">Loading results...</li>
|
||||
|
||||
<!-- Iterating over suggestions -->
|
||||
<li
|
||||
v-else
|
||||
v-for="(result, i) in suggestions"
|
||||
:key="i"
|
||||
v-else
|
||||
v-bind:key="i"
|
||||
v-bind:ref="setItemRef"
|
||||
class="autocomplete-result-item"
|
||||
:class="{ 'is-active': isSelected(i) }"
|
||||
v-bind:class="{ 'is-active': isSelected(i) }"
|
||||
@click.prevent="select(result)"
|
||||
:ref="setItemRef"
|
||||
>
|
||||
<!-- Displaying suggestion result -->
|
||||
<div class="small-label">
|
||||
<label>{{ result.value }} ({{ result.type }})</label>
|
||||
<!-- <label>{{ result.value }} ({{ result.type }})</label> -->
|
||||
<label v-html="formatSuggestion(result)"></label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -126,7 +136,7 @@ input {
|
|||
list-style-type: none;
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
max-height: 200px;
|
||||
max-height: 192px;
|
||||
overflow-y: auto;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
|
|
@ -139,15 +149,17 @@ input {
|
|||
.autocomplete-result-item {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
/* padding: 7px 10px; */
|
||||
padding: 0px 0px 0px 5px; // top,right,bottom,left
|
||||
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: rgba(0, 180, 255, 0.075);
|
||||
background: #baedf1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { Dataset } from "@/models/dataset";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop } from "vue-property-decorator";
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "VsResult",
|
||||
})
|
||||
export default class VsResult extends Vue {
|
||||
|
|
@ -15,6 +14,16 @@ 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(".");
|
||||
|
||||
|
|
@ -24,13 +33,15 @@ export default class VsResult extends Vue {
|
|||
.join(".");
|
||||
}
|
||||
|
||||
private convert(unixtimestamp: number): string {
|
||||
// private convert(unixtimestamp: number): string { // SOLR
|
||||
private convert(unixtimestamp: string): string { // OpenSearch
|
||||
// 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);
|
||||
// const date = new Date(unixtimestamp * 1000); // SOLR
|
||||
const date = new Date(Number(unixtimestamp) * 1000); // OpenSearch
|
||||
// Year
|
||||
const year = date.getFullYear();
|
||||
// Month
|
||||
|
|
|
|||
|
|
@ -1,47 +1,48 @@
|
|||
<template>
|
||||
<div v-for="document in results" :key="document.id">
|
||||
<div v-for="document in results" v-bind:key="document.id">
|
||||
<div class="card result-list-container">
|
||||
<div class="card-content record-elem">
|
||||
<p v-if="document.identifier && document.identifier.length > 0">
|
||||
<!-- <span>Author: {{ document.identifier.join(', ') }}</span> -->
|
||||
<!-- <span v-for="(author,index) in document.author" :key="index">{{ author }}; </span> -->
|
||||
<!-- <span>'https://doi.org/' + {{ document.identifier[0] }}</span> -->
|
||||
<a target="_blank" v-bind:href="'https://doi.org/' + document.identifier[0]"> {{ "https://doi.org/" + document.identifier[0] + " ➤" }} </a>
|
||||
<span class="disabled" v-if="document.author && document.author.length > 0">{{ document.author[0] }}</span>
|
||||
<a target="_blank" v-bind:href="'https://doi.org/' + document.identifier[0]">
|
||||
{{ "https://doi.org/" + document.identifier[0] + " ➤" }} </a
|
||||
>
|
||||
|
||||
|
||||
<!-- Display authors conditionally -->
|
||||
<span v-if="document.author && document.author.length > 0">
|
||||
<!-- For one author, just display the author's name -->
|
||||
<span v-if="document.author.length === 1" class="disabled">
|
||||
{{ simplifyAuthor(document.author[0]) }}
|
||||
</span>
|
||||
<!-- For 2-3 authors, display them all -->
|
||||
<span v-if="document.author.length > 1 && document.author.length < 3">
|
||||
<span v-for="(author, index) in document.author" :key="index" class="disabled">
|
||||
{{ simplifyAuthor(author) }}<span v-if="index < document.author.length - 1" class="disabled">; </span>
|
||||
</span>
|
||||
</span>
|
||||
<!-- For 4 or more authors, display the first three and add "et al." -->
|
||||
<span v-if="document.author.length >= 3" class="disabled">
|
||||
<span v-for="(author, index) in document.author.slice(0, 2)" :key="index" class="disabled">
|
||||
{{ simplifyAuthor(author) }}<span v-if="index < 1" class="disabled">; </span>
|
||||
</span>
|
||||
et al.
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<!-- <span class="label label-info" data-container="div" data-title="Publication date">
|
||||
{{ convert(document.server_date_published) }}
|
||||
</span>
|
||||
<span class="label label-default ng-binding">{{ document.doctype }}</span>
|
||||
<span v-if="openAccessLicences.includes(document.licence)" class="label label-success titlecase">Open Access</span> -->
|
||||
|
||||
<h4>
|
||||
<!-- <a
|
||||
v-if="document.identifier && document.identifier.length > 0"
|
||||
target="_self"
|
||||
v-bind:href="'https://doi.' + getDomainWithoutSubdomain() + '/' + document.identifier[0]"
|
||||
class="ng-binding"
|
||||
>
|
||||
<router-link class="ng-binding" v-bind:to="{ name: 'dataset', params: { datasetId: document.id } }">
|
||||
{{ document.title_output }}
|
||||
</a> -->
|
||||
<!-- <a target="_self" v-bind:href="'dataset/' + document.id" class="ng-binding">
|
||||
{{ document.title_output }}
|
||||
</a> -->
|
||||
<router-link class="ng-binding" :to="{ name: 'dataset', params: { datasetId: document.id } }">{{ document.title_output }}</router-link>
|
||||
</router-link>
|
||||
</h4>
|
||||
|
||||
<!-- <p v-if="document.author && document.author.length > 0">
|
||||
<span>Author: {{ document.author.join(', ') }}</span>
|
||||
<span v-for="(author, index) in document.author" :key="index">{{ author }}; </span>
|
||||
</p> -->
|
||||
|
||||
<p class="clamped clamped-2">
|
||||
<span class="disabled" data-container="div" data-title="Publication date">
|
||||
{{ convert(document.server_date_published) + ": " }}
|
||||
</span>
|
||||
<span class="text">
|
||||
{{ document.abstract_output }}
|
||||
<!-- {{ document.abstract_output }} -->
|
||||
{{ document.abstract[0] }}
|
||||
<span class="ellipsis">...</span>
|
||||
<span class="fill"></span>
|
||||
</span>
|
||||
|
|
@ -49,11 +50,9 @@
|
|||
|
||||
<p>
|
||||
<span class="label"><i class="fas fa-file"></i> {{ document.doctype }}</span>
|
||||
<!-- <span>Licence: {{ document.licence }}</span> -->
|
||||
<span v-if="openAccessLicences.includes(document.licence)" class="label titlecase"><i class="fas fa-lock-open"></i> Open Access</span>
|
||||
</p>
|
||||
|
||||
<!-- <span class="label label-keyword titlecase" v-for="(item, index) in document.subject" :key="index"> #{{ item }} </span> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,26 @@
|
|||
// declare const POINT_URL: string;
|
||||
// declare const EDGE_URL: string;
|
||||
declare const VUE_APP_PORTAL: string;
|
||||
declare const SOLR_HOST: string;
|
||||
declare const SOLR_CORE: string;
|
||||
declare const APP_URL: string;
|
||||
declare const VUE_API: string;
|
||||
// declare const SOLR_HOST: string;
|
||||
// declare const SOLR_CORE: string;
|
||||
|
||||
// const _EDGE_URL = EDGE_URL;
|
||||
// const _POINT_URL = POINT_URL;
|
||||
const _VUE_APP_PORTAL = VUE_APP_PORTAL;
|
||||
const _SOLR_HOST = SOLR_HOST;
|
||||
const _SOLR_CORE = SOLR_CORE;
|
||||
// OPENSEARCH
|
||||
declare const OPEN_HOST: string;
|
||||
declare const OPEN_CORE: string;
|
||||
|
||||
// export { _EDGE_URL as EDGE_URL };
|
||||
// export { _POINT_URL as POINT_URL };
|
||||
export { _VUE_APP_PORTAL as VUE_APP_PORTAL };
|
||||
export { _SOLR_HOST as SOLR_HOST };
|
||||
export { _SOLR_CORE as SOLR_CORE };
|
||||
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;
|
||||
|
||||
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 };
|
||||
|
|
|
|||
3
src/index.css
Normal file
3
src/index.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
|
@ -1,18 +1,21 @@
|
|||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import App2 from "./App2.vue";
|
||||
// add bulma style
|
||||
import "./assets/scss/main-styles.scss";
|
||||
// import FontAwesomeIcon from "@/utilities/fontawesome";
|
||||
import index from "./router/index";
|
||||
import route1 from "./router/route1";
|
||||
import "@fortawesome/fontawesome-free/css/all.css";
|
||||
import VueMatomo from "vue-matomo";
|
||||
// // add tailwind style
|
||||
// import "@/index.css";
|
||||
|
||||
const host = window.location.host;
|
||||
const parts = host.split(".");
|
||||
// const domainLength = 2; // route1.example.com => domain length = 3
|
||||
let router, app;
|
||||
// let routes;
|
||||
// exmample change
|
||||
if (parts[0] === "doi") {
|
||||
router = route1;
|
||||
app = App2;
|
||||
|
|
@ -21,6 +24,7 @@ if (parts[0] === "doi") {
|
|||
router = index;
|
||||
app = App;
|
||||
}
|
||||
// const app = App;
|
||||
|
||||
createApp(app)
|
||||
.use(VueMatomo, {
|
||||
|
|
|
|||
|
|
@ -1,69 +1,92 @@
|
|||
// import moment from "moment";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
// // SOLR Dataset original
|
||||
// export interface Dataset {
|
||||
// abstract_additional: Array<string>;// OpenSearch: abstract: Array<string>
|
||||
// abstract_output: string;// -----
|
||||
// author: Array<string>;// EQUAL
|
||||
// author_sort: Array<string>;// -----
|
||||
// belongs_to_bibliography: boolean;// EQUAL
|
||||
// creating_corporation: string;// EQUAL
|
||||
// doctype: string;// EQUAL
|
||||
// geo_location: string;// EQUAL
|
||||
// id: number;// EQUAL
|
||||
// identifier: Identifier;// OpenSearch: identifier: Array<string>
|
||||
// language: string;// EQUAL
|
||||
// licence: string;// EQUAL
|
||||
// publisher_name: string;// EQUAL
|
||||
// server_date_published: Array<number>;// OpenSearch not array!
|
||||
// subject: Array<string>;// OpenSearch: subjectS
|
||||
// title_output: string;// EQUAL
|
||||
// year: number;// EQUAL
|
||||
// year_inverted: number;// EQUAL
|
||||
// }
|
||||
|
||||
// OpenSearch Dataset
|
||||
export interface Dataset {
|
||||
abstract_additional: Array<string>;
|
||||
abstract_output: string;
|
||||
author: Array<string>;
|
||||
author_sort: Array<string>;
|
||||
belongs_to_bibliography: boolean;
|
||||
creating_corporation: string;
|
||||
doctype: string;
|
||||
geo_location: string;
|
||||
id: number;
|
||||
identifier: Array<string>;
|
||||
language: string;
|
||||
licence: string;
|
||||
publisher_name: string;
|
||||
server_date_published: Array<number>;
|
||||
subject: Array<string>;
|
||||
title_output: string;
|
||||
year: number;
|
||||
year_inverted: number;
|
||||
abstract: Array<string>;// OpenSearch: abstract: Array<string>
|
||||
// abstract_output: string;// ----- NOT in OpenSearch
|
||||
author: Array<string>;// EQUAL
|
||||
// author_sort: Array<string>;// ----- 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<string>
|
||||
identifier: Array<string>// DIFF DATATYPE
|
||||
language: string;// EQUAL
|
||||
licence: string;// EQUAL
|
||||
publisher_name: string;// EQUAL
|
||||
// server_date_published: Array<number>;// OpenSearch string!
|
||||
server_date_published: string;// DIFF DATATYPE
|
||||
// subject: Array<string>;// OpenSearch: subjectS
|
||||
subjects: Array<string>;// DIFF DATATYPE
|
||||
title_output: string;// EQUAL
|
||||
year: number;// EQUAL
|
||||
year_inverted: number;// EQUAL
|
||||
|
||||
title: string // Unique in OpenSearch
|
||||
title_additional: Array<string> // 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<string> // Unique in OpenSearch
|
||||
abstract_additional: Array<string>;// Unique in OpenSearch
|
||||
}
|
||||
|
||||
|
||||
export class Suggestion {
|
||||
constructor(public value: string, public type: SearchType) {}
|
||||
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
|
||||
) {}
|
||||
// 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 = "subject",
|
||||
Subject = "subjects", // ** !! The field has this name in OpenSearch!!
|
||||
Doctype = "doctype"
|
||||
}
|
||||
|
||||
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<Title>;
|
||||
// public abstracts!: Array<Abstract>;
|
||||
// public authors!: Array<Author>;
|
||||
// public contributors!: Array<Author>;
|
||||
// public user!: Person;
|
||||
// public subjects!: Array<Subject>;
|
||||
|
||||
constructor(
|
||||
public id: string,
|
||||
|
|
@ -96,7 +119,10 @@ export class DbDataset {
|
|||
public user: Person,
|
||||
public subjects: Array<Subject>,
|
||||
public licenses: Array<License>,
|
||||
public references: Array<Reference>,
|
||||
public files: Array<DbFile>,
|
||||
public identifier: Identifier,
|
||||
public referenced_by: Array<Reference>,
|
||||
private coverage?: Coverage,
|
||||
public project?: Project,
|
||||
) {}
|
||||
|
|
@ -209,8 +235,32 @@ 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: " + yMin + "\n" + "* WEST-BOUND LONGITUDE: " + xMin + "\n" + "* NORTH-BOUND LATITUDE: " + yMax + "\n" + "* EAST-BOUND LONGITUDE: " + xMax;
|
||||
// "- SOUTH-BOUND LATITUDE: " +
|
||||
"- South-bound Latitude: " +
|
||||
yMin +
|
||||
"\n" +
|
||||
"- West-bound Longitude: " +
|
||||
xMin +
|
||||
"\n" +
|
||||
"- North-bound Latitude: " +
|
||||
yMax +
|
||||
"\n" +
|
||||
"- East-bound Longitude: " +
|
||||
xMax;
|
||||
|
||||
// geoLocation += elevationAbsolut != null ? ` * ELEVATION ABSOLUT: ${elevationAbsolut}\n` : "";
|
||||
|
||||
|
|
@ -218,36 +268,83 @@ export class DbDataset {
|
|||
|
||||
let elevation = "";
|
||||
if (this.coverage.elevation_max != null && this.coverage.elevation_min != null) {
|
||||
elevation += "\n* ELEVATION MIN: " + this.coverage.elevation_min + " *\nELEVATION MAX: " + this.coverage.elevation_max;
|
||||
// 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";
|
||||
}
|
||||
if (this.coverage.elevation_absolut != null) {
|
||||
elevation += "\n* ELEVATION ABSOLUT: " + this.coverage.elevation_absolut;
|
||||
elevation += "\n- Elevation Absolut: " + this.coverage.elevation_absolut + " m";
|
||||
}
|
||||
if (elevation != "") geoLocation += elevation;
|
||||
// if (elevation != "") geoLocation += ("\n---" + 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;
|
||||
depth += "\n- Depth Min.: " + this.coverage.depth_min + " m\n- Depth Max.: " + this.coverage.depth_max + " m";
|
||||
}
|
||||
if (this.coverage.elevation_absolut != null) {
|
||||
depth += "\n* DEPTH ABSOLUT: " + this.coverage.depth_absolut;
|
||||
depth += "\n- Depth Absolut: " + this.coverage.depth_absolut + " m";
|
||||
}
|
||||
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;
|
||||
|
||||
return geoLocation;
|
||||
// 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;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/* Provides the bounds of the publication for the Leaflet minimap */
|
||||
public get Bounds(): L.LatLngBoundsLiteral | string {
|
||||
if (this.coverage != undefined) {
|
||||
return [
|
||||
[Number(this.coverage.y_min), Number(this.coverage.x_min)], // Southwest corner
|
||||
[Number(this.coverage.y_max), Number(this.coverage.x_max)] // Northeast corner
|
||||
];
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
type Nullable<T> = T | undefined;
|
||||
|
||||
|
|
@ -341,6 +438,16 @@ export interface License {
|
|||
sort_order: number;
|
||||
}
|
||||
|
||||
export interface Reference {
|
||||
id: number;
|
||||
document_id: number;
|
||||
type: string;
|
||||
relation: string;
|
||||
value: string;
|
||||
label: string;
|
||||
dataset: Dataset;
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: number;
|
||||
label: string; // "ALLG_FACHLICH"
|
||||
|
|
@ -350,18 +457,41 @@ export interface Project {
|
|||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface DbFile {
|
||||
id: number;
|
||||
document_id: number;
|
||||
path_name: string;
|
||||
label: string;
|
||||
comment?: string;
|
||||
mime_type: string;
|
||||
language?: string;
|
||||
file_size: bigint;
|
||||
visible_in_frontdoor: boolean;
|
||||
visible_in_oai: boolean;
|
||||
sort_order: Int16Array;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
export class DbFile {
|
||||
constructor(
|
||||
public id: number,
|
||||
public document_id: number,
|
||||
public path_name: string,
|
||||
public label: string,
|
||||
public mime_type: string,
|
||||
public file_size: number,
|
||||
public visible_in_frontdoor: boolean,
|
||||
public visible_in_oai: boolean,
|
||||
public sort_order: Int16Array,
|
||||
public created_at: string,
|
||||
public updated_at: string,
|
||||
public hashvalues: Array<HashValue>,
|
||||
public comment?: string,
|
||||
public language?: string,
|
||||
) {}
|
||||
|
||||
public get HashValue(): Nullable<HashValue> {
|
||||
return this.hashvalues.find((e) => e.type === "md5");
|
||||
}
|
||||
}
|
||||
|
||||
export interface HashValue {
|
||||
file_id: number;
|
||||
type: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Identifier {
|
||||
created_at: string;
|
||||
dataset_id: number;
|
||||
id: number;
|
||||
status: string; //'findable'
|
||||
type: string; //'doi'
|
||||
updated_at: string; //'2023-03-09T09:48:28.000Z'
|
||||
value: string; //'10.24341/tethys.209'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,19 +18,6 @@ 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 {
|
||||
|
|
@ -39,36 +26,21 @@ export interface ResponseContent {
|
|||
docs: Array<Dataset>;
|
||||
}
|
||||
|
||||
// export interface FacetCount {
|
||||
// facet_fields: FacetCategory<any>;
|
||||
// }
|
||||
|
||||
// export class FacetCategory<T> {
|
||||
|
||||
// [key: string]: {
|
||||
// values: T[];
|
||||
// };
|
||||
// }
|
||||
|
||||
//Used
|
||||
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;
|
||||
|
|
@ -83,3 +55,85 @@ 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>;
|
||||
// }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { Dataset } from "./dataset";
|
||||
|
||||
export interface Pagination {
|
||||
export interface IPagination {
|
||||
total: number;
|
||||
per_page?: number;
|
||||
current_page: number;
|
||||
last_page?: number;
|
||||
perPage: number;
|
||||
currentPage: number;
|
||||
lastPage?: number;
|
||||
data: Array<Dataset>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
export interface SolrSettings {
|
||||
// export interface SolrSettings {
|
||||
// core: string;
|
||||
// host: string;
|
||||
// }
|
||||
|
||||
export interface OpenSettings {
|
||||
core: string;
|
||||
host: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
|
|||
configureWebpack: {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
VUE_APP_PORTAL: JSON.stringify(process.env.VUE_APP_PORTAL),
|
||||
VUE_API: JSON.stringify(process.env.VUE_API),
|
||||
SOLR_HOST: JSON.stringify(process.env.SOLR_HOST),
|
||||
SOLR_CORE: JSON.stringify(process.env.SOLR_CORE),
|
||||
}),
|
||||
|
|
@ -138,4 +138,19 @@ https://prettier.io/docs/en/cli.html
|
|||
|
||||
|
||||
=================================== xslt3
|
||||
npm install xslt3 --save
|
||||
npm install xslt3 --save
|
||||
|
||||
|
||||
|
||||
=================================== vue-facing-decorator
|
||||
npm install --save vue-facing-decorator
|
||||
|
||||
npm uninstall --save vue-class-component
|
||||
package.json:
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
|
||||
npm uninstall --save vue-property-decorator
|
||||
package.json:
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
|
||||
npm uninstall --save xml2js
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { createWebHistory, createRouter } from "vue-router";
|
||||
import { createWebHistory, createRouter, Router } from "vue-router";
|
||||
import HomeViewComponent from "@/views/home-view/home-view-component.vue";
|
||||
import HelpViewComponent from "@/views/help-view/help-view-component.vue";
|
||||
import MapViewComponent from "@/views/map-view/map-view.component.vue";
|
||||
// import MapViewComponent from "@/views/map-view/map-view.component.vue";
|
||||
import SearchViewComponent from "@/views/search-view/search-view-component";
|
||||
import ServiceViewComponent from "@/views/services-view/service-view-component.vue";
|
||||
import OaiViewComponent from "@/views/oai-view/oai-view-component.vue";
|
||||
|
|
@ -22,11 +22,11 @@ const routes = [
|
|||
name: "Help",
|
||||
component: HelpViewComponent,
|
||||
},
|
||||
{
|
||||
path: "/map",
|
||||
name: "Map",
|
||||
component: MapViewComponent,
|
||||
},
|
||||
// {
|
||||
// path: "/map",
|
||||
// name: "Map",
|
||||
// component: MapViewComponent,
|
||||
// },
|
||||
{
|
||||
path: "/search/:display?/:type?",
|
||||
name: "Search",
|
||||
|
|
@ -77,7 +77,7 @@ const routes = [
|
|||
},
|
||||
];
|
||||
|
||||
const index = createRouter({
|
||||
const index: Router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
// scrollBehavior(to, from, savedPosition) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
// import Vue from 'vue';
|
||||
// import Router from 'vue-router';
|
||||
import { createWebHistory, createRouter } from "vue-router";
|
||||
import { createWebHistory, createRouter, Router } from "vue-router";
|
||||
import DatasetDetailComponent from "@/views/dataset-detail.component/dataset-detail.component";
|
||||
|
||||
// Vue.use(Router);
|
||||
|
||||
// export default new Router({
|
||||
// mode: 'history',
|
||||
// routes: [
|
||||
|
|
@ -16,20 +12,21 @@ import DatasetDetailComponent from "@/views/dataset-detail.component/dataset-det
|
|||
// ],
|
||||
// });
|
||||
|
||||
const route1 = createRouter({
|
||||
const route1: Router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
// {
|
||||
// path: '/',
|
||||
// name: 'Route1',
|
||||
// component: Route1,
|
||||
// },
|
||||
{
|
||||
path: "/10.24341/tethys.:datasetId",
|
||||
name: "dataset2",
|
||||
name: "dataset3",
|
||||
component: DatasetDetailComponent,
|
||||
props: true,
|
||||
},
|
||||
// {
|
||||
// path: "/10.24341/:identifier",
|
||||
// name: "dataset2",
|
||||
// component: DatasetDetailComponent,
|
||||
// props: true,
|
||||
// },
|
||||
],
|
||||
// scrollBehavior(to, from, savedPosition) {
|
||||
scrollBehavior() {
|
||||
|
|
|
|||
|
|
@ -1,698 +0,0 @@
|
|||
<div class="columns">
|
||||
|
||||
<div class="column is-9 results_column" style="padding-top: 1.2rem; padding-right: 0.5rem">
|
||||
<div class="column" id="loading_bar" style="padding-top: 0px; display: none">
|
||||
<div class="column" style="padding-top: 0; padding-bottom: 0; margin-bottom: 0"></div>
|
||||
<div class="card" style="margin-bottom: 0px">
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<noscript>It appears that your Javascript is disabled. To view results on
|
||||
this page, you will need to enable it. You might want to visit our
|
||||
<a href="/lite/results">lite results</a>.
|
||||
</noscript>
|
||||
<progress class="progress is-large" max="100">60%</progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="results">
|
||||
<div class="column" style="padding-top: 0">
|
||||
<div class="card" style="margin-bottom: 0px">
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
It looks like you're not logged in right now. you will need to
|
||||
<a href="/login" target="_self">login to Pro</a> or become a
|
||||
<a href="https://coil.com/?ref=InfinitySearch2229" target="_self">Coil Member</a>
|
||||
to access the results.
|
||||
<div class="block"></div>
|
||||
<div class="columns" style="text-align: center">
|
||||
<div class="column is-one-third">
|
||||
<a class="button" style="width: 100%" href="/login" target="_self">Login</a>
|
||||
</div>
|
||||
<div class="column is-one-third">
|
||||
<a class="button" style="width: 100%" href="/pro" target="_self">Learn more about
|
||||
Infinity Pro</a>
|
||||
</div>
|
||||
<div class="column is-one-third">
|
||||
<a class="button" style="width: 100%"
|
||||
href="https://coil.com/?ref=InfinitySearch2229" target="_self">Learn more about
|
||||
Coil</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div hidden="" id="id-custom-tab-page">
|
||||
<div class="columns" style="margin-top: 1rem">
|
||||
<div class="column is-one-quarter is-offset-2">
|
||||
<p class="heading">Current Tabs</p>
|
||||
<div id="id-current-tab-list">
|
||||
<nav class="level is-mobile" id="id-web-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">web</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-web" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-images-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
images
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-images" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-videos-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
videos
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-videos" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-homepages-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
homepages
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-homepages" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-food-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
food
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-food" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-books-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
books
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-books" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="level is-mobile" id="id-movies-tab">
|
||||
<div class="level-item has-text-centered is-capitalized">
|
||||
movies
|
||||
</div>
|
||||
<div class="level-item has-text-centered is-one-quarter">
|
||||
<div style="order: 2; margin-left: auto; margin-right: 0.5rem">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
<img class="handle trash" src="/static/images/fa/trash-alt.svg"
|
||||
id="id-remove-tab-icon-movies" style="
|
||||
cursor: pointer;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 0.5rem;
|
||||
" onclick="removeTab(this);" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-one-quarter is-offset-1">
|
||||
<p class="heading">Add New Tabs</p>
|
||||
<nav class="level">
|
||||
<div class="level-item">
|
||||
<div class="select">
|
||||
<select id="id-add-tab-selector" style="
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI',
|
||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans',
|
||||
'Droid Sans', 'Helvetica Neue', Helvetica, Arial,
|
||||
sans-serif;
|
||||
">
|
||||
<option id="id-tab-selector-web" value="web" style="display: none">
|
||||
Web
|
||||
</option>
|
||||
<option id="id-tab-selector-images" value="images" style="display: none">
|
||||
Images
|
||||
</option>
|
||||
<option id="id-tab-selector-videos" value="videos" style="display: none">
|
||||
Videos
|
||||
</option>
|
||||
<option id="id-tab-selector-homepages" value="homepages" style="display: none">
|
||||
Homepages
|
||||
</option>
|
||||
<option id="id-tab-selector-general" value="general">
|
||||
General
|
||||
</option>
|
||||
<option id="id-tab-selector-food" value="food" style="display: none">
|
||||
Food
|
||||
</option>
|
||||
<option id="id-tab-selector-books" value="books" style="display: none">
|
||||
Books
|
||||
</option>
|
||||
<option id="id-tab-selector-movies" value="movies" style="display: none">
|
||||
Movies
|
||||
</option>
|
||||
<option id="id-tab-selector-music" value="music">
|
||||
Music
|
||||
</option>
|
||||
<option id="id-tab-selector-infinity" value="infinity">
|
||||
Infinity
|
||||
</option>
|
||||
<option id="id-tab-selector-edu" value="edu">Edu</option>
|
||||
<option id="id-tab-selector-pdf" value="pdf">Pdf</option>
|
||||
<option id="id-tab-selector-qa" value="qa">Qa</option>
|
||||
<option id="id-tab-selector-reddit" value="reddit">
|
||||
Reddit
|
||||
</option>
|
||||
<option id="id-tab-selector-fandom" value="fandom">
|
||||
Fandom
|
||||
</option>
|
||||
<option id="id-tab-selector-coil" value="coil">Coil</option>
|
||||
<option id="id-tab-selector-no_js" value="no_js">
|
||||
No Javascript
|
||||
</option>
|
||||
<option id="id-tab-selector-decentralized" value="decentralized">
|
||||
Decentralized
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<button class="button" id="id-add-tab-button" onclick="addTab();" style="
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI',
|
||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<br />
|
||||
<nav class="level">
|
||||
<div class="level-item">
|
||||
<button class="button" id="id-update-tabs-button" style="
|
||||
order: 2;
|
||||
margin-left: auto;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI',
|
||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
" onclick="resetTabsToOriginal();">
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="id-custom-tabs-error"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div id="id-side-bar" class="column is-3 sidebar_column" style="padding-top: 1.2rem; padding-right: 1.5rem">
|
||||
<div id="externals" class="">
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://en.wikipedia.org/w/index.php?search="
|
||||
href="https://en.wikipedia.org/w/index.php?search=test" name="external_link_0"
|
||||
style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/wikipedia.ico"
|
||||
name="external_icon_0'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_0"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Wikipedia Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://duckduckgo.com/?q=" href="https://duckduckgo.com/?q=test" name="external_link_1"
|
||||
style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/duckduckgo.ico"
|
||||
name="external_icon_1'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_1"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
DuckDuckGo Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://www.google.com/search?q=" href="https://www.google.com/search?q=test"
|
||||
name="external_link_2" style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/google.ico"
|
||||
name="external_icon_2'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_2"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Google Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://www.youtube.com/results?search_query="
|
||||
href="https://www.youtube.com/results?search_query=test" name="external_link_3"
|
||||
style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/youtube.svg"
|
||||
name="external_icon_3'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_3"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Youtube Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://www.amazon.com/s?k=" href="https://www.amazon.com/s?k=test"
|
||||
name="external_link_4" style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/amazon.ico"
|
||||
name="external_icon_4'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_4"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Amazon Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://twitter.com/search?q=" href="https://twitter.com/search?q=test"
|
||||
name="external_link_5" style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/twitter.png"
|
||||
name="external_icon_5'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_5"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Twitter Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://www.reddit.com/search/?q=" href="https://www.reddit.com/search/?q=test"
|
||||
name="external_link_6" style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/reddit.ico"
|
||||
name="external_icon_6'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_6"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Reddit Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://github.com/search?q=" href="https://github.com/search?q=test"
|
||||
name="external_link_7" style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/github.ico"
|
||||
name="external_icon_7'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_7"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
GitHub Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a id="https://www.reuters.com/search/news?blob="
|
||||
href="https://www.reuters.com/search/news?blob=test" name="external_link_8"
|
||||
style="display: block" rel="noreferrer noopener" target="_self">
|
||||
<img onerror="imgError(this)" src="/static/images/favicons/reuters.ico"
|
||||
name="external_icon_8'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_8"
|
||||
style="font-size: 0.95rem; display: inline">
|
||||
Reuters Results
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<span class="clickableIcon" onclick="removeExternalClickable(this)" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 6px;
|
||||
min-width: 0.5em;
|
||||
">
|
||||
<img class="handle fa-ellipsis-v" src="/static/images/fa/ellipsis-v.svg" style="
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-right: 12px;
|
||||
min-width: 0.5em;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
" />
|
||||
</span>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
<div id="externals_menu">
|
||||
<div class="card is-fullwidth" id="plus-minus-info" style="
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0px;
|
||||
height: 2.5rem;
|
||||
padding: 0.7rem;
|
||||
">
|
||||
<div class="columns is-vcentered is-mobile">
|
||||
<div class="column" style="text-align: center">
|
||||
<button class="button is-small" id="external_add" style="
|
||||
border-color: transparent;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI',
|
||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
<img src="/static/images/fa/plus.svg" class="cl-external-link-img" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-narrow" style="text-align: center">|</div>
|
||||
<div class="column" style="text-align: center">
|
||||
<button class="button is-small" id="external_minus" style="
|
||||
border-color: transparent;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI',
|
||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
<img src="/static/images/fa/minus.svg" class="cl-external-link-img" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-narrow" style="text-align: center">|</div>
|
||||
<div class="column" style="text-align: center">
|
||||
<div id="external-info-button" style="text-align: center">
|
||||
<div style="cursor: pointer" id="externals_layout_button"
|
||||
onclick="toggleExternalsLayout();">
|
||||
<img id="id-externals-layout-img" class="cl-external-link-img"
|
||||
src="/static/images/fa/list.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="external_link_add_box" style="margin: 0.5rem" hidden="">
|
||||
<div class="box is-fullwidth is" style="margin: 0; padding: 0.5rem">
|
||||
<input class="input is-small" id="new_external_label" placeholder="Search Label" style="
|
||||
margin: 0.25rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
" />
|
||||
<input class="input is-small" id="new_external_link"
|
||||
placeholder="Search Link (https://is.com/results?q=)" style="
|
||||
margin: 0.25rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
" />
|
||||
<input class="input is-small" id="new_external_icon"
|
||||
placeholder="Icon Link (https://is.com/img.png)" style="
|
||||
margin: 0.25rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
" />
|
||||
</div>
|
||||
<button class="button is-small is-outlined" id="external_input_add" style="
|
||||
float: right;
|
||||
margin: 0.5rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
Add
|
||||
</button>
|
||||
<button class="button is-small is-outlined is-danger" id="external_input_cancel" style="
|
||||
float: right;
|
||||
margin-top: 0.5rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
<div id="external_input_defaults" hidden="">
|
||||
<button class="button is-small is-outlined is-danger" id="external_input_defaults_button" style="
|
||||
float: right;
|
||||
margin-top: 0.5rem;
|
||||
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
">
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
161
src/services/dataset.service - Tests with OpenSearch
Normal file
161
src/services/dataset.service - Tests with OpenSearch
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// 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;
|
||||
// }
|
||||
|
|
@ -1,323 +1,386 @@
|
|||
import api from "../api/api";
|
||||
// import { Observable, of } from "rxjs";
|
||||
import { Observable } from "rxjs";
|
||||
import { map } from "rxjs/operators";
|
||||
import { tap, map } from "rxjs/operators";
|
||||
import { Dataset, DbDataset, Suggestion } from "@/models/dataset";
|
||||
import { SolrResponse } from "@/models/headers";
|
||||
import { HitHighlight, OpenSearchResponse, SolrResponse } from "@/models/headers";
|
||||
import { ActiveFilterCategories } from "@/models/solr";
|
||||
import { VUE_APP_PORTAL } from "@/constants";
|
||||
// import { deserialize, instanceToInstance } from "class-transformer";
|
||||
import { VUE_API } from "@/constants";
|
||||
import { deserialize } from "class-transformer";
|
||||
// import { OAI_DATASETS } from "./mock-oai-datasets";
|
||||
import { OaiDataset, OaiPerson } from "@/models/oai";
|
||||
import xml2js from "xml2js";
|
||||
|
||||
class DatasetService {
|
||||
// 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;
|
||||
/**
|
||||
* 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[] }> {
|
||||
|
||||
//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",
|
||||
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 stations = api.get<SolrResponse>(base, q_params).pipe(map((res: SolrResponse) => res.response.docs));
|
||||
|
||||
return stations;
|
||||
/**
|
||||
* 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)
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
// // 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,
|
||||
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?";
|
||||
openCore: string,
|
||||
openHost: string,
|
||||
start?: string, // Starting page
|
||||
): Observable<OpenSearchResponse> {
|
||||
const host = openHost;
|
||||
const path = "/" + openCore + "/_search";
|
||||
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", "identifier", "title_output", "title_additional", "author", "subject", "doctype"].toString();
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
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 } }));
|
||||
}
|
||||
// filterFields += '"]';
|
||||
}
|
||||
// const query = "&sort=server_date_published desc" + "&q=" + term;
|
||||
}).flat();
|
||||
|
||||
// const api =
|
||||
// base + params + limit + start + query + filterFields + facetFields;
|
||||
// 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
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// 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" }',
|
||||
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 stations = api.get<SolrResponse>(base, q_params);
|
||||
// .pipe(map((res) => res.response.docs));
|
||||
|
||||
|
||||
// API call and return observable of search results
|
||||
const stations = api.post<OpenSearchResponse>(base, body);
|
||||
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_APP_PORTAL;
|
||||
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_APP_PORTAL;
|
||||
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_APP_PORTAL;
|
||||
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');
|
||||
const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res)));
|
||||
return dataset;
|
||||
}
|
||||
|
||||
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");
|
||||
// Method to fetch a dataset by its DOI
|
||||
public getDatasetByDoi(doi: string): Observable<DbDataset> {
|
||||
const host = VUE_API;
|
||||
const path = "/api/dataset/10.24341/tethys." + doi;
|
||||
const apiUrl = host + path;
|
||||
|
||||
// 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;
|
||||
const dataset = api.get<DbDataset>(apiUrl).pipe(map((res) => this.prepareDataset(res)));
|
||||
return dataset;
|
||||
}
|
||||
|
||||
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 {
|
||||
// Prepare dataset object by deserializing it and adding a URL
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "ContactViewComponent",
|
||||
// components: {
|
||||
// VsInput,
|
||||
|
|
|
|||
|
|
@ -6,28 +6,55 @@
|
|||
<p class="lead">Want to keep updated or need further information?</p>
|
||||
<hr class="center-line" />
|
||||
</div>
|
||||
<div class="column is-half contact-us-details" style="padding-top: 0; margin-top: 0">
|
||||
<h3>Our Location</h3>
|
||||
<h5>
|
||||
Geologische Bundesanstalt <br />
|
||||
Neulinggasse 38 <br />
|
||||
1030 Wien <br />
|
||||
<!-- <i class="fas fa-mobile-alt"></i> +43-1-7125674 <br />
|
||||
<div class="columns">
|
||||
<div class="column contact-us-details" style="padding-top: 0; margin-top: 0">
|
||||
<h3>Our Location</h3>
|
||||
<h5>
|
||||
GeoSphere Austria <br />
|
||||
Neulinggasse 38 <br />
|
||||
1030 Wien <br />
|
||||
<!-- <i class="fas fa-mobile-alt"></i> +43-1-7125674 <br />
|
||||
<i class="fas fa-envelope-open-text"></i>
|
||||
<a class="social-media" href="mailto:repository@geologie.ac.at"> repository@geologie.ac.at</a><br /> -->
|
||||
</h5>
|
||||
<ul class="social-links">
|
||||
<li><i class="fas fa-phone-alt pr-2"></i> +43-1-7125674 <br /></li>
|
||||
<li>
|
||||
<a class="social-media" href="mailto:repository@geologie.ac.at"><i class="fas fa-envelope pr-2"></i> repository(at)geologie.ac.at </a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://twitter.com/GeologischeBA" target="_blank"> <i class="fab fa-twitter"></i> twitter.com/GeologischeBA </a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://www.facebook.com/geologie.ac.at" target="_blank"> <i class="fab fa-facebook"></i> www.facebook.com/geologie.ac.at </a>
|
||||
</li>
|
||||
</ul>
|
||||
</h5>
|
||||
|
||||
<ul class="social-links">
|
||||
<li><i class="fas fa-phone-alt pr-2"></i> +43-1-7125674 <br /></li>
|
||||
<li>
|
||||
<a class="social-media" href="mailto:kontakt@geosphere.at"><i class="fas fa-envelope pr-2"></i> kontakt(at)geosphere.at </a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://twitter.com/GeoSphere_AT" target="_blank">
|
||||
<i class="fab fa-twitter"></i> twitter.com/GeoSphere_AT
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://www.facebook.com/GeoSphere.at" target="_blank">
|
||||
<i class="fab fa-facebook"></i> www.facebook.com/GeoSphere.at
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://www.instagram.com/GeoSphere_AT" target="_blank">
|
||||
<i class="fab fa-instagram"></i> www.instagram.com/GeoSphere_AT
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="social-media" href="https://at.linkedin.com/company/geosphereaustria" target="_blank">
|
||||
<i class="fa-brands fa-linkedin"></i> at.linkedin.com/company/geosphereaustria
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="column contact-us-details" style="padding-top: 0; margin-top: 0">
|
||||
<h3>Contact Person</h3>
|
||||
<h5>
|
||||
Viktoria Haider <br />
|
||||
<a class="social-media" href="mailto:repository@geosphere.at"><i class="fas fa-envelope pr-2"></i> repository(at)geosphere.at </a>
|
||||
<!-- <i class="fas fa-mobile-alt"></i> +43-1-7125674 <br />
|
||||
<i class="fas fa-envelope-open-text"></i>
|
||||
<a class="social-media" href="mailto:repository@geologie.ac.at"> repository@geologie.ac.at</a><br /> -->
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,51 +1,81 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
// detail-dataset.component.ts
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
import { DbDataset } from "@/models/dataset";
|
||||
import { Prop } from "vue-property-decorator";
|
||||
import DatasetService from "../../services/dataset.service";
|
||||
import { Subscription } from "rxjs";
|
||||
import dayjs from "dayjs";
|
||||
import advancedFormat from "dayjs/plugin/advancedFormat";
|
||||
// import SimpleSearchComponent from "@/components/simple-search/simple-search-component.vue";
|
||||
import VsInput from "@/components/vs-input/vs-input.vue";
|
||||
import { Suggestion } from "@/models/dataset";
|
||||
import { VUE_APP_PORTAL } from "@/constants";
|
||||
import { VUE_API } from "@/constants";
|
||||
// import DataMetricsBadge from "data-metrics-badge/dist/data-metrics-badge.js";
|
||||
// import DataMetricsBadge from "@/components/datacite/DataMetricsBadge.vue";
|
||||
import Minimap from '@/components/minimap/Minimap.vue';
|
||||
import * as L from 'leaflet';
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "DatasetDetailComponent",
|
||||
components: {
|
||||
VsInput,
|
||||
Minimap
|
||||
// DataMetricsBadge, // Commented out but prepared for future use
|
||||
},
|
||||
})
|
||||
export default class DatasetDetailComponent extends Vue {
|
||||
@Prop()
|
||||
datasetId!: number;
|
||||
datasetId!: string; // datasetId is passed as a prop and is required.
|
||||
|
||||
searchTerm: string | Suggestion = "";
|
||||
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.
|
||||
|
||||
private subscriptions: Array<Subscription> = [];
|
||||
public dataset = {} as DbDataset;
|
||||
private error = "";
|
||||
public loaded = false;
|
||||
public openAccessLicences: Array<string> = ["CC-BY-4.0", "CC-BY-SA-4.0"];
|
||||
public portal = VUE_APP_PORTAL + "/file/download/";
|
||||
// If needed for stats
|
||||
// public post = {
|
||||
// views: 25, // Number of views for the dataset
|
||||
// downloads: 1262, // Number of downloads
|
||||
// citations: 2424, // Number of citations
|
||||
// };
|
||||
|
||||
/**
|
||||
* 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);
|
||||
this.getDataset(this.datasetId);
|
||||
dayjs.extend(advancedFormat); // Adds advanced date formatting options to dayjs.
|
||||
if (!this.datasetId.includes(".")) {
|
||||
// Fetch dataset by publish_id (numeric ID)
|
||||
this.getDataset(Number(this.datasetId));
|
||||
} else {
|
||||
// Fetch dataset by DOI (alphanumeric ID)
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
onSearch(suggestion: Suggestion | string): void {
|
||||
/**
|
||||
* 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 {
|
||||
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;
|
||||
|
|
@ -56,6 +86,7 @@ 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;
|
||||
|
|
@ -65,63 +96,125 @@ 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(
|
||||
(res: DbDataset) => {
|
||||
this.dataset = res;
|
||||
this.loaded = true;
|
||||
const newSub = DatasetService.getDataset(id).subscribe({
|
||||
next: (res: DbDataset) => {
|
||||
this.dataset = res; // Store dataset in component state.
|
||||
this.loaded = true; // Mark as loaded.
|
||||
},
|
||||
(error: string) => this.errorHandler(error),
|
||||
);
|
||||
this.subscriptions.push(newSub);
|
||||
error: (error: string) => {
|
||||
this.error = error; // Capture any errors during fetch.
|
||||
},
|
||||
});
|
||||
|
||||
this.subscriptions.push(newSub); // Add subscription to array to manage unsubscribing later.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
},
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
});
|
||||
|
||||
this.subscriptions.push(newSub); // Add subscription to array.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles errors and updates the error message in the component.
|
||||
* @param err - Error message.
|
||||
*/
|
||||
private errorHandler(err: string): void {
|
||||
this.error = err;
|
||||
// this.loading = false;
|
||||
this.error = err; // Update error message.
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates back by one page in the router history, similar to browser back.
|
||||
*/
|
||||
public goBack(): void {
|
||||
// go back by one record, the same as history.back()
|
||||
// router.go(-1);
|
||||
this.$router.go(-1);
|
||||
this.$router.go(-1); // Go back one step in the browser history.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"];
|
||||
const unit = ["Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; // Units for size.
|
||||
let i;
|
||||
for (i = 0; size >= 1024 && i < unit.length - 1; i++) {
|
||||
size = size / 1024;
|
||||
size = size / 1024; // Convert size to appropriate unit.
|
||||
}
|
||||
// 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) => {
|
||||
|
|
@ -130,14 +223,27 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,133 +1,141 @@
|
|||
<!-- 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">
|
||||
<!-- <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen mx-auto">
|
||||
<div class="search-box mx-auto">
|
||||
<div class="field has-addons main-search-from-bg">
|
||||
<div class="control is-expanded">
|
||||
<input
|
||||
v-on:input="searchChanged"
|
||||
id="search_query"
|
||||
class="input is-medium"
|
||||
type="text"
|
||||
name="q"
|
||||
autocomplete="off"
|
||||
v-model="display"
|
||||
v-bind:placeholder="placeholder"
|
||||
v-on:keydown.down="onArrowDown"
|
||||
v-on:keydown.up="onArrowUp"
|
||||
v-on:keydown.enter="onEnter"
|
||||
@keydown.tab="close"
|
||||
v-on:focus="focus"
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button input is-medium search-button-icon" @click="search()">
|
||||
<i class="fas fa-search text-white"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <simple-search-component></simple-search-component> -->
|
||||
<vs-input v-on:search-change="onSearch" v-bind:placeholder="'Enter your search term...'"></vs-input>
|
||||
<!-- 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 class="section" v-if="loaded">
|
||||
|
||||
<!-- 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">
|
||||
{{ reference.type }}:
|
||||
<!-- Link to the newer version's DOI -->
|
||||
<a
|
||||
v-if="reference.type === 'DOI'"
|
||||
target="_blank"
|
||||
class="link-label"
|
||||
v-bind:href="'https://doi.org/' + reference.dataset.identifier.value"
|
||||
>
|
||||
{{ "https://doi.org/" + reference.dataset.identifier.value }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card displaying dataset titles -->
|
||||
<div class="card record-elem">
|
||||
<div class="columns" v-if="dataset.hasOwnProperty('titles')">
|
||||
<!-- 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>
|
||||
<p>{{ dataset.MainTitle?.value }}</p>
|
||||
<br />
|
||||
<p v-if="dataset.hasTranslatedTitle()">
|
||||
{{ dataset.TranslatedTitle.value }}
|
||||
{{ dataset.TranslatedTitle?.value }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns" v-if="dataset.hasOwnProperty('abstracts')">
|
||||
|
||||
<!-- Section for dataset abstracts -->
|
||||
<div v-if="dataset.hasOwnProperty('abstracts')" class="columns">
|
||||
<div class="column is-3-desktop is-4-tablet label">
|
||||
Zusammenfassung/<br />
|
||||
abstract:
|
||||
</div>
|
||||
<div class="column is-9-desktop is-8-tablet">
|
||||
<p>{{ dataset.MainAbstract.value }}</p>
|
||||
<p>{{ dataset.MainAbstract?.value }}</p>
|
||||
<br />
|
||||
<p v-if="dataset.hasTranslatedAbstract()">
|
||||
{{ dataset.TranslatedAbstract.value }}
|
||||
{{ dataset.TranslatedAbstract?.value }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns" v-if="dataset.hasOwnProperty('abstracts')">
|
||||
<!-- 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 class="column is-9-desktop is-8-tablet" v-if="dataset.hasSeriesInformationAbstract()">
|
||||
<div v-if="dataset.hasSeriesInformationAbstract()" class="column is-9-desktop is-8-tablet">
|
||||
<p>{{ dataset.SeriesInformationAbstract?.value }}</p>
|
||||
<br />
|
||||
<p v-if="dataset.hasTranslatedSeriesInformationAbstract()">
|
||||
{{ dataset.TranslatedSeriesInformationAbstract?.value }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="column is-9-desktop is-8-tablet" v-else>-</div>
|
||||
</div>
|
||||
<div class="columns" v-if="dataset.hasOwnProperty('abstracts')">
|
||||
<div class="column is-3-desktop is-4-tablet label">Methodik/<br />method:</div>
|
||||
<div class="column is-9-desktop is-8-tablet" v-if="dataset.hasMethodsAbstract()">
|
||||
{{ dataset.MethodsAbstract.value }}
|
||||
</div>
|
||||
<div class="column is-9-desktop is-8-tablet" v-else>-</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">
|
||||
{{ dataset.MethodsAbstract?.value }}
|
||||
</div>
|
||||
<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 class="column is-9-desktop is-8-tablet" v-if="dataset.files.length > 0">
|
||||
<table id="items" v-if="dataset.hasEmbargoPassed()" class="table is-bordered is-striped">
|
||||
<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>
|
||||
<th class="table-header">Path Name</th>
|
||||
<th class="table-header">File Extension</th>
|
||||
<th class="table-header">File Ext.</th>
|
||||
<th class="table-header">File Size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="file in dataset.files" :key="file.id">
|
||||
<tr v-for="file in dataset.files" v-bind:key="file.id">
|
||||
<td>
|
||||
<a class="link-label" target="_blank" v-bind:href="portal + file.id"> {{ file.label }} </a>
|
||||
<br />
|
||||
</td>
|
||||
<td>
|
||||
<span>{{ getExtension(file.path_name) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{ formatSize(file.file_size, 2) }}</span>
|
||||
<span>{{ formatSize(file.file_size) }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -137,6 +145,7 @@
|
|||
</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">
|
||||
|
|
@ -150,30 +159,52 @@
|
|||
</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>
|
||||
<!-- <data-metrics-badge doi="10.7272/q6g15xs4" display="regular"></data-metrics-badge> -->
|
||||
<!-- <data-metrics-badge doi="10.24341/tethys.209" display="small" v-bind:data-input="post"></data-metrics-badge> -->
|
||||
<!-- <data-metrics-badge v-bind:doi="dataset.identifier.value" display="small"></data-metrics-badge> -->
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<!-- <h3 class="label uppercase">MAP</h3> -->
|
||||
<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')">
|
||||
{{ dataset.subjects.map((u) => u.value).join(", ") }}
|
||||
<!-- 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>
|
||||
</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>
|
||||
|
|
@ -194,7 +225,7 @@
|
|||
<div class="column">
|
||||
<h3 class="label uppercase">Sprache/Language</h3>
|
||||
<p>
|
||||
{{ dataset.language }}
|
||||
{{ getLanguage(dataset.language) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -206,15 +237,25 @@
|
|||
</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" :key="license.id">
|
||||
<label v-for="license in dataset.licenses" v-bind:key="license.id">
|
||||
<!-- Link to the appropriate Creative Commons license -->
|
||||
<span class="normal label">
|
||||
{{ license.name }}
|
||||
<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
|
||||
>
|
||||
</span>
|
||||
<span v-if="openAccessLicences.includes(license.name)" class="normal label uppercase"><i class="fas fa-lock-open"></i> Open Access</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
|
||||
>
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -223,11 +264,37 @@
|
|||
<div class="column">
|
||||
<h3 class="label uppercase">Projekt/Project</h3>
|
||||
<p v-if="dataset.project != null">
|
||||
<span>{{ dataset.project.name }}</span>
|
||||
<span>{{ dataset.project.label }}</span>
|
||||
</p>
|
||||
<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"
|
||||
class="link-label"
|
||||
v-bind:href="reference.value"
|
||||
>
|
||||
{{ `${reference.relation} (${reference.type}): ${reference.label}` }}
|
||||
</a>
|
||||
<span v-else class="normal label">
|
||||
{{ `${reference.relation} (${reference.type}): ${reference.value}` }}
|
||||
</span>
|
||||
<span v-if="dataset.references.length > 0 && i < dataset.references.length - 1" class="normal label">--</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>
|
||||
|
|
@ -237,25 +304,51 @@
|
|||
<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 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 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>
|
||||
<div class="column col-sm text-center">
|
||||
<a target="_blank" href="http://www.geologie.ac.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="Geologische Bundesanstalt logo" />
|
||||
</a>
|
||||
<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>
|
||||
<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 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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -263,35 +356,43 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Minimap from "@/components/Minimap.vue";
|
||||
import DatasetDetailComponent from "./dataset-detail.component";
|
||||
export default DatasetDetailComponent;
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// @import 'leaflet/dist/leaflet.css';
|
||||
.section {
|
||||
font-size: 0.8rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 0;
|
||||
/* rempve box-shadow */
|
||||
/* Remove box-shadow for a flat design */
|
||||
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;
|
||||
}
|
||||
|
|
@ -302,27 +403,4 @@ 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>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
// import { Prop } from "vue-property-decorator";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import SectionBannerStarOnGitHub from "@/components/SectionBannerStarOnGitea.vue";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "HelpViewComponent",
|
||||
components: {
|
||||
SectionBannerStarOnGitHub,
|
||||
},
|
||||
})
|
||||
export default class HelpViewComponent extends Vue {
|
||||
// results: Array<any> = [];
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@
|
|||
</div>
|
||||
<div class="card-content">
|
||||
<p class="card-text">
|
||||
Tethys RDR ist ein Datenverlag der Geologischen Bundesanstalt (GBA), der ausschließlich an der GBA generierte geowissenschaftliche Forschungsdat en
|
||||
publiziert. Die Datenpublikationen können sowohl in deutscher, als auch in englischer Sprache publiziert werden. Durch die Bereitstellung der
|
||||
Datenpublikation zusammen mit Metadaten nach standardisierten Schemata werden die Publikationen auffindbar und zitierbar.
|
||||
TETHYS RDR ist ein publizierendes Forschungsdatenrepositorium der GeoSphere Austria, das darauf spezialisiert ist,
|
||||
geowissenschaftliche Forschungsdaten zu sammeln, zu speichern und der Öffentlichkeit zugänglich zu machen. Die Datenpublikationen
|
||||
können sowohl in deutscher, als auch in englischer Sprache publiziert werden. Durch die Bereitstellung der Datenpublikation zusammen
|
||||
mit Metadaten nach standardisierten Schemata werden die Publikationen auffindbar und zitierbar.
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
|
|
@ -34,8 +35,8 @@
|
|||
</div>
|
||||
<div class="card-content">
|
||||
<p class="card-text">
|
||||
GBA-Angehörigkeit oder in Kooperation mit der GBA gemeinsame Publikation der Daten. Im Besitz eines eigenen Zugangscodes zu sein bzw. um den Zugangscode
|
||||
anzufragen (Kontakt).
|
||||
Angehörigkeit als MitarbeiterIn von GeoSphere Austria oder die gemeinsame Publikation der Daten in Kooperation mit GeoSphere
|
||||
Austria. Im Besitz eines eigenen Zugangscodes zu sein bzw. um den Zugangscode anzufragen (Kontakt).
|
||||
</p>
|
||||
<p class="card-text">Die Datenpublikationsrichtlinien gelesen, verstanden und akzeptiert zu haben.</p>
|
||||
<p class="card-text">Die Datensätze vollständig und fachlich korrekt hochladen.</p>
|
||||
|
|
@ -59,11 +60,15 @@
|
|||
</div>
|
||||
<div class="card-content">
|
||||
<p class="card-text">
|
||||
Wird eine Datenpublikation erwünscht, so kann der Verfasser der Publikation sich direkt bei Tethys RDR einloggen und den Publikationsablauf starten.
|
||||
<a href="docs/HandbuchTethys.pdf" target="_blank" class="text-secondary"> Datenpublikationsrichtlinien, Terms & Conditions, Anleitung </a>
|
||||
Wird eine Datenpublikation erwünscht, so kann der Verfasser der Publikation sich direkt bei Tethys RDR einloggen und den
|
||||
Publikationsablauf starten.
|
||||
<a href="docs/HandbuchTethys.pdf" target="_blank" class="text-secondary">
|
||||
Datenpublikationsrichtlinien, Terms & Conditions, Anleitung
|
||||
</a>
|
||||
</p>
|
||||
<p class="card-text">
|
||||
Wurde noch kein <a href="" class="text-secondary">account</a> angelegt, steht das Tethys RDR-Team bereit, um die weiteren Schritte zu klären (Kontakt).
|
||||
Wurde noch kein <a href="" class="text-secondary">account</a> angelegt, steht das Tethys RDR-Team bereit, um die weiteren Schritte
|
||||
zu klären (Kontakt).
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
|
|
@ -77,6 +82,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SectionBannerStarOnGitHub />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -80,3 +80,28 @@ input{
|
|||
.partner-logos {
|
||||
padding: 3em 0;
|
||||
}
|
||||
|
||||
|
||||
a.text-secondary {
|
||||
color: #494f54 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a.text-secondary:focus,
|
||||
a.text-secondary:hover {
|
||||
color: #494f54 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a.text-secondary2 {
|
||||
color: #fff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a.text-secondary2:focus,
|
||||
a.text-secondary2:hover {
|
||||
color: #fff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import VsInput from "@/components/vs-input/vs-input.vue";
|
||||
import { Suggestion } from "@/models/dataset";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "HomeViewComponent",
|
||||
components: {
|
||||
VsInput,
|
||||
|
|
@ -11,6 +11,9 @@ 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") {
|
||||
|
|
@ -22,6 +25,7 @@ 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 } });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,6 @@
|
|||
</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>
|
||||
|
|
@ -47,7 +40,7 @@
|
|||
<img src="https://bulma.io/images/placeholders/256x256.png" />
|
||||
</figure> -->
|
||||
<!-- class="columns help u-full-width featured-bg-image"> -->
|
||||
<section data-sr id="help" class="header-image align-items-center h-100">
|
||||
<section id="help" data-sr class="header-image align-items-center h-100">
|
||||
<!-- <div class="column is-two-thirds-tablet is-half-desktop is-one-third-widescreen mx-auto">
|
||||
<div class="search-box mx-auto">
|
||||
<div class="field has-addons main-search-from-bg">
|
||||
|
|
@ -62,7 +55,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<vs-input v-on:search-change="onSearch" v-bind:placeholder="'Enter your search term...'"></vs-input>
|
||||
<vs-input v-bind:placeholder="'Enter your search term...'" @search-change="onSearch"></vs-input>
|
||||
</section>
|
||||
|
||||
<div class="container">
|
||||
|
|
@ -74,18 +67,25 @@
|
|||
</div>
|
||||
<div class="column is-full text-left">
|
||||
<p>
|
||||
TETHYS RDR ist ein publizierendes Forschungsdatenrepositorium der Geologischen Bundesanstalt (GBA), das an der GBA generierte geowissenschaftliche
|
||||
Forschungsdaten veröffentlicht.
|
||||
TETHYS RDR ist ein publizierendes Forschungsdatenrepositorium der GeoSphere Austria, das darauf spezialisiert ist, geowissenschaftliche
|
||||
Forschungsdaten zu sammeln, zu speichern und der Öffentlichkeit zugänglich zu machen.
|
||||
</p>
|
||||
<p>
|
||||
Zum derzeitigen Stand wird TETHYS RDR in deutscher Sprache bereitgestellt. Die englische Version befindet sich in Vorbereitung und wird sukzessive ebenfalls
|
||||
zur Verfügung gestellt. Die Forschungsdatenpublikationen und die dazugehörigen Metadaten können in Deutsch und in Englisch veröffentlicht werden. Tethys RDR
|
||||
hat den Anspruch, publizierte Datensätze unverändert, langfristig und nachhaltig bereitzustellen. Dadurch ist Tethys ein Forschungsdatenrepositorium, das
|
||||
ein permanentes Referenzieren ermöglicht und somit die darin publizierten Datensätze zitierfähig macht.
|
||||
Zum derzeitigen Stand wird TETHYS RDR in deutscher Sprache bereitgestellt. Die englische Version befindet sich in Vorbereitung und wird
|
||||
sukzessive ebenfalls zur Verfügung gestellt. Die Forschungsdatenpublikationen und die dazugehörigen Metadaten können in Deutsch und in
|
||||
Englisch veröffentlicht werden. Tethys RDR hat den Anspruch, publizierte Datensätze unverändert, langfristig und nachhaltig
|
||||
bereitzustellen. Dadurch ist Tethys ein Forschungsdatenrepositorium, das ein permanentes Referenzieren ermöglicht und somit die darin
|
||||
publizierten Datensätze zitierfähig macht.
|
||||
</p>
|
||||
<p>
|
||||
Der Name Tethys kommt ursprünglich aus der griechischen Mythologie und benennt eine Titanin und Meeresgöttin. Ende des 19. Jahrhunderts entdeckte Eduard
|
||||
Suess (1831–1914), ein bedeutender österreichischer Geologe, den mesozoischen Ozean und benannte ihn nach dieser Tethys.
|
||||
Der Erhaltungsplan
|
||||
<a href="docs/PreservationPlanTethys.pdf" target="_blank" class="text-secondary"> (Preservation Plan) </a> beschreibt den Ansatz von
|
||||
Tethys zur Definition und Umsetzung von Erhaltungsmaßnahmen.
|
||||
</p>
|
||||
<p>
|
||||
Der Name Tethys kommt ursprünglich aus der griechischen Mythologie und benennt eine Titanin und Meeresgöttin. Ende des 19. Jahrhunderts
|
||||
entdeckte Eduard Suess (1831-1914), ein bedeutender österreichischer Geologe, den mesozoischen Ozean und benannte ihn nach dieser
|
||||
Tethys.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -102,8 +102,11 @@
|
|||
<img src="@/assets/site/img/box-1-hover.jpg" alt="Datenarchivierung" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Tethys RDR publiziert und archiviert nach den FAIR Prinzipien* nachhaltig so wie sicher geowissenschaftliche Datensätze in offenen, frei
|
||||
lesbaren Formaten. * FAIR data
|
||||
Tethys RDR publiziert und archiviert nach den FAIR Prinzipien* nachhaltig so wie sicher geowissenschaftliche Datensätze in
|
||||
offenen, frei lesbaren Formaten. * FAIR data
|
||||
</p>
|
||||
<p class="text-white">
|
||||
<a href="docs/PreservationPlanTethys.pdf" target="_blank" class="text-secondary2">Preservation Plan</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -120,8 +123,8 @@
|
|||
<img src="@/assets/site/img/box-2-hover.jpg" alt="DATENPUBLIKATION" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Die Datensätze werden mit standardisierten Metadatenschemen publiziert und sind somit nicht nur auffindbar, wiederverwendbar und auch
|
||||
maschinenlesbar, sondern können dadurch auch einfach zitiert werden.
|
||||
Die Datensätze werden mit standardisierten Metadatenschemen publiziert und sind somit nicht nur auffindbar, wiederverwendbar
|
||||
und auch maschinenlesbar, sondern können dadurch auch einfach zitiert werden.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -138,8 +141,8 @@
|
|||
<img src="@/assets/site/img/box-3-hover.jpg" alt="BEGUTACHTUNG" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Alle im Tethys RDR publizierten Datensätze werden auf technische sowie inhaltliche Vollständigkeit geprüft und werden bei Bedarf auch einer
|
||||
fachlichen Begutachtung unterworfen. Ein klassischer Peer Review-Prozess ist in Vorbereitung.
|
||||
Alle im Tethys RDR publizierten Datensätze werden auf technische sowie inhaltliche Vollständigkeit geprüft und werden bei
|
||||
Bedarf auch einer fachlichen Begutachtung unterworfen. Ein klassischer Peer Review-Prozess ist in Vorbereitung.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -162,9 +165,10 @@
|
|||
<h1 class="text-white">HABEN SIE FRAGEN?</h1>
|
||||
|
||||
<p class="text-white text center p-5">
|
||||
Tethys RDR ist ein Datenverlag der Geologischen Bundesanstalt (GBA), der ausschließlich an der GBA generierte geowissenschaftliche Forschungsdaten
|
||||
publiziert. Die Datenpublikationen können sowohl in deutscher, als auch in englischer Sprache publiziert werden. Durch die Bereitstellung der
|
||||
Datenpublikation zusammen mit Metadaten nach standardisierten Schemata werden die Publikationen auffindbar und zitierbar.
|
||||
TETHYS RDR ist ein publizierendes Forschungsdatenrepositorium der GeoSphere Austria, das darauf spezialisiert ist, geowissenschaftliche
|
||||
Forschungsdaten zu sammeln, zu speichern und der Öffentlichkeit zugänglich zu machen. Die Datenpublikationen können sowohl in deutscher,
|
||||
als auch in englischer Sprache publiziert werden. Durch die Bereitstellung der Datenpublikation zusammen mit Metadaten nach
|
||||
standardisierten Schemata werden die Publikationen auffindbar und zitierbar.
|
||||
</p>
|
||||
|
||||
<div class="mx-auto my-5" style="width: 170px">
|
||||
|
|
@ -178,15 +182,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<!-- <div class="container-fluid">
|
||||
<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>
|
||||
<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.geologie.ac.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="Geologische Bundesanstalt logo" />
|
||||
<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">
|
||||
|
|
@ -195,6 +200,39 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="container-fluid">
|
||||
<!-- <div class="columns is-mobile partner-logos"> -->
|
||||
<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">
|
||||
<!-- <h5 class="card-title">About TETHYS</h5> -->
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
// import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "ImprintViewComponent",
|
||||
// components: {
|
||||
// VsInput,
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="column is-full text-left">
|
||||
<p class="lead">Für den Inhalt verantwortlich</p>
|
||||
<p>
|
||||
<span>Geologische Bundesanstalt</span><br />
|
||||
<span>GeoSphere Austria</span><br />
|
||||
<span>Neulinggasse 38, 1030 Wien</span><br />
|
||||
<span>office@geologie.ac.at</span><br />
|
||||
<span>kontakt@geosphere.at</span><br />
|
||||
<span>Telefon: +43-1-7125674</span><br />
|
||||
<span>Fax: +43-1-7125674-56</span><br />
|
||||
</p>
|
||||
|
||||
<p class="lead">Technische Umsetzung und Betreuung</p>
|
||||
<p>
|
||||
<span>Geologische Bundesanstalt</span><br />
|
||||
<span>GeoSphere Austria</span><br />
|
||||
<span>Hauptabteilung Informationsdienste</span><br />
|
||||
<span>Neulinggasse 38, 1030 Wien</span><br />
|
||||
<span>repository@geologie.ac.at</span><br />
|
||||
<span>Bei technischen Problemen steht Ihnen das RDR-Team, erreichbar unter repository@geologie.ac.at, gerne zur Seite.</span>
|
||||
<span>repository@geosphere.at</span><br />
|
||||
<span>Bei technischen Problemen steht Ihnen das RDR-Team, erreichbar unter repository@geosphere.at, gerne zur Seite.</span>
|
||||
</p>
|
||||
|
||||
<p class="lead">Hinweise und Haftungsausschluss</p>
|
||||
<p>Eine Haftung oder Garantie für Aktualität, Richtigkeit und Vollständigkeit der zur Verfügung gestellten Daten ist ausgeschlossen.</p>
|
||||
<p>
|
||||
Dieser Hinweis gilt auch für alle anderen Webseiten, auf die durch Hyperlinks verwiesen wird. Die Geologische Bundesanstalt ist für den Inhalt von Webseiten,
|
||||
die mittels einer solchen Verbindung erreicht werden, nicht verantwortlich.
|
||||
Dieser Hinweis gilt auch für alle anderen Webseiten, auf die durch Hyperlinks verwiesen wird. Die GeoSphere Austria ist für den Inhalt von
|
||||
Webseiten, die mittels einer solchen Verbindung erreicht werden, nicht verantwortlich.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import MapComponent from "@/components/map/map.component.vue";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import { defineAsyncComponent } from "vue";
|
||||
// import MapComponent from "@/components/map/map.component.vue";
|
||||
// import { Marker, MapOptions, Control, icon, LatLngBoundsExpression } from "leaflet";
|
||||
import { MapOptions } from "leaflet";
|
||||
|
||||
|
|
@ -7,11 +8,14 @@ import { MapOptions } from "leaflet";
|
|||
// const DEFAULT_BASE_LAYER_URL = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
|
||||
// const DEFAULT_BASE_LAYER_ATTRIBUTION = '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors';
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "MapViewComponent",
|
||||
components: {
|
||||
MapComponent,
|
||||
MapComponent: defineAsyncComponent(() => import("@/components/map/map.component.vue")),
|
||||
},
|
||||
// components: {
|
||||
// MapComponent,
|
||||
// },
|
||||
})
|
||||
export default class MapViewComponent extends Vue {
|
||||
public mapOptions: MapOptions = {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
<li><a href="javascript:window.open(window.location.href.split('?')[0]+'?layer=geofast','_self')">Geofast Datensätze</a></li> -->
|
||||
<li><a href="javascript:window.open(window.location.href.split('?')[0],'_self')">alle Datenpublikationen</a></li>
|
||||
<li><a href="javascript:window.open(window.location.href.split('?')[0]+'?layer=gk50','_self')">GK50 Kartendaten</a></li>
|
||||
<li><a href="javascript:window.open(window.location.href.split('?')[0]+'?layer=geofast','_self')">Geofast Datensätze</a></li>
|
||||
<li>
|
||||
<a href="javascript:window.open(window.location.href.split('?')[0]+'?layer=geofast','_self')">Geofast Datensätze</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "OaiViewComponent",
|
||||
})
|
||||
export default class OaiViewComponent extends Vue {}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@
|
|||
</div>
|
||||
<div class="column is-full text-left">
|
||||
<p class="paragraph-justify">
|
||||
Die Open Archives Initiative (OAI; http://www.openarchives.org) dient der Entwicklung und Förderung von Interoperabilitätsstandards für die Auffindbarkeit von
|
||||
elektronischen Publikationen im Internet. Das dazu entwickelte Protokoll OAI-PMH (OAI Protocol for Metadata Harvesting) wird zum globalen „Ernten“ der durch
|
||||
Metadaten beschriebenen Publikationen im Internet herangezogen. Eine Liste aller OAI-Provider wird unter folgender Adresse zur Verfügung gestellt:
|
||||
Die Open Archives Initiative (OAI; http://www.openarchives.org) dient der Entwicklung und Förderung von Interoperabilitätsstandards für die
|
||||
Auffindbarkeit von elektronischen Publikationen im Internet. Das dazu entwickelte Protokoll OAI-PMH (OAI Protocol for Metadata Harvesting) wird
|
||||
zum globalen „Ernten“ der durch Metadaten beschriebenen Publikationen im Internet herangezogen. Eine Liste aller OAI-Provider wird unter
|
||||
folgender Adresse zur Verfügung gestellt:
|
||||
<a href="https://www.openarchives.org/Register/BrowseSites" target="_blank">www.openarchives.org/Register/BrowseSites</a>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -18,10 +19,10 @@
|
|||
</div>
|
||||
<div class="column is-full text-left">
|
||||
<p class="paragraph-justify">
|
||||
Die OAI-PMH Basis URL für das Research Data Repository der Geologischen Bundesanstalt lautet
|
||||
Die OAI-PMH Basis URL für das Research Data Repository der GeoSphere Austria lautet
|
||||
<a href="https://tethys.at/oai">https://tethys.at/oai</a> <br />
|
||||
Derzeit unterstützt das OAI-Service den Metadatenstandard DC (OAI-PMH Dublin Core) und eingeschränkt den Standard DataCite (aktuell in dieser Testkonfiguration noch
|
||||
ohne Vergabe einer im Schema verpflichtenden DOI).
|
||||
Derzeit unterstützt das OAI-Service den Metadatenstandard DC (OAI-PMH Dublin Core) und eingeschränkt den Standard DataCite (aktuell in dieser
|
||||
Testkonfiguration noch ohne Vergabe einer im Schema verpflichtenden DOI).
|
||||
</p>
|
||||
<ul class="quicklinks">
|
||||
<li><a href="?verb=Identify">Identify</a> | </li>
|
||||
|
|
|
|||
|
|
@ -1,69 +1,106 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Prop } from "vue-property-decorator";
|
||||
// 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 { SolrSettings } from "@/models/solr";
|
||||
// import { DatasetService } from "@/services/dataset.service";
|
||||
|
||||
// Import models and services
|
||||
// import { SolrSettings } from "@/models/solr";
|
||||
import { OpenSettings } from "@/models/solr";
|
||||
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 } from "@/models/headers";
|
||||
// import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers";
|
||||
import { FacetItem, FacetResults, OpenSearchResponse } from "@/models/headers";
|
||||
import { ActiveFilterCategories } from "@/models/solr";
|
||||
import { SOLR_HOST, SOLR_CORE } from "@/constants";
|
||||
import { Pagination } from "@/models/pagination";
|
||||
// import { SOLR_HOST, SOLR_CORE } from "@/constants";
|
||||
import { IPagination } from "@/models/pagination";
|
||||
import PaginationComponent from "@/components/PaginationComponent.vue";
|
||||
|
||||
@Options({
|
||||
import { OPEN_HOST, OPEN_CORE } from "@/constants";
|
||||
|
||||
// Define the Vue component, its name, and child components
|
||||
@Component({
|
||||
name: "SearchViewComponent",
|
||||
components: {
|
||||
VsInput,
|
||||
VsResult,
|
||||
FacetCategory,
|
||||
ActiveFacetCategory,
|
||||
PaginationComponent,
|
||||
},
|
||||
})
|
||||
|
||||
// Export the default class for the component
|
||||
export default class SearchViewComponent extends Vue {
|
||||
@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: Pagination = {
|
||||
// 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
|
||||
total: 0,
|
||||
per_page: 2,
|
||||
current_page: 0,
|
||||
// last_page: 0,
|
||||
perPage: 10,
|
||||
currentPage: 1,
|
||||
data: [],
|
||||
};
|
||||
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",
|
||||
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",
|
||||
};
|
||||
// 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.searchTerm.type + ")";
|
||||
return this.searchTerm.value + " (" + this.getTypeAlias(this.searchTerm.type) + ")";
|
||||
// return this.searchTerm.value + " (" + this.searchTerm.type + ")";
|
||||
// Default to empty string
|
||||
} 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;
|
||||
|
|
@ -73,21 +110,22 @@ export default class SearchViewComponent extends Vue {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// getKeyName(value: string) {
|
||||
// return Object.entries(Suggestion).find(([key, val]) => val === value)?.[0];
|
||||
// }
|
||||
|
||||
// Method to get enum key by enum value
|
||||
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 {
|
||||
// this.rdrAPI = new DatasetService();
|
||||
// Trigger search based on provided display and type props
|
||||
if (this.display != "" && this.type != undefined) {
|
||||
const enumKey = this.getEnumKeyByEnumValue(SearchType, this.type);
|
||||
const enumKey: "Title" | "Author" | "Subject" | "Doctype" | null = this.getEnumKeyByEnumValue(SearchType, this.type);
|
||||
if (enumKey) {
|
||||
const suggestion = new Suggestion(this.display, SearchType[enumKey]);
|
||||
const suggestion = new Suggestion(this.display, "NO-IDEA", SearchType[enumKey]);
|
||||
// const suggestion = new Suggestion(this.display, "" , SearchType[enumKey]);
|
||||
this.onSearch(suggestion);
|
||||
} else {
|
||||
this.onSearch(this.display);
|
||||
|
|
@ -99,199 +137,294 @@ export default class SearchViewComponent extends Vue {
|
|||
}
|
||||
}
|
||||
|
||||
// onSearch(term: string): void {
|
||||
// Method to trigger a search
|
||||
onSearch(suggestion: Suggestion | string): void {
|
||||
// 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*";
|
||||
// }
|
||||
|
||||
// console.log("ONSEARCH");
|
||||
|
||||
// Reset active filter categories and facet results
|
||||
this.activeFilterCategories = new ActiveFilterCategories();
|
||||
this.facets = new FacetResults();
|
||||
|
||||
// this.facets = {};
|
||||
this.searchTerm = suggestion;
|
||||
DatasetService.facetedSearch(suggestion, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe(
|
||||
(res: SolrResponse) => this.dataHandler(res),
|
||||
(error: string) => this.errorHandler(error),
|
||||
);
|
||||
|
||||
// /* 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),
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private dataHandler(res: SolrResponse, filterItem?: FacetItem): void {
|
||||
// this.results = datasets;
|
||||
this.results = res.response.docs;
|
||||
this.numFound = res.response.numFound;
|
||||
// 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;
|
||||
this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // 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");
|
||||
|
||||
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),
|
||||
});
|
||||
}
|
||||
|
||||
// Method to handle facet filtering
|
||||
onFilter(facetItem: FacetItem): void {
|
||||
// console.log(facetItem.val);
|
||||
// if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) {
|
||||
console.log("onFilter");
|
||||
|
||||
// Reset current page
|
||||
this.pagination.currentPage = 1;
|
||||
|
||||
// Check if filter item already exists
|
||||
if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) {
|
||||
this.activeFilterCategories[facetItem.category] = new Array<string>();
|
||||
}
|
||||
// if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) {
|
||||
|
||||
// Check if filter item is not already applied
|
||||
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.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;
|
||||
// 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),
|
||||
// );
|
||||
|
||||
// // 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;
|
||||
// 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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// // // 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 {
|
||||
// alert(categoryName);
|
||||
// console.log("onClearFacetCategory");
|
||||
delete this.activeFilterCategories[categoryName];
|
||||
|
||||
DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe(
|
||||
(res: SolrResponse) => {
|
||||
this.results = res.response.docs;
|
||||
this.numFound = res.response.numFound;
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
} else {
|
||||
rObj = new FacetItem(facetItem.val, facetItem.count);
|
||||
}
|
||||
return rObj;
|
||||
});
|
||||
this.facets[prop] = facetValues;
|
||||
return rObj;
|
||||
}).filter(el => el.count > 0); // Filter out items with count <= 0
|
||||
|
||||
this.facets[prop] = facetValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
(error: string) => this.errorHandler(error),
|
||||
);
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
complete: () => console.log("Clear facet category completed"),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,141 +1,100 @@
|
|||
<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-on:search-change="onSearch" v-bind:propDisplay="searchTerm" v-bind:placeholder="'Enter your search term...'"></vs-input>
|
||||
</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 class="resultheader" v-if="hasSearchTerm()">
|
||||
Your search term {{ "'" + stringSearchTerm + "'" }} yielded <strong>{{ numFound }}</strong> results:
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="results.length == 0">
|
||||
<div class="resultheader">
|
||||
Your search yielded
|
||||
<strong> 0</strong> results:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div id="id-pro-sign-in" class="notification" style="">
|
||||
<button
|
||||
class="delete"
|
||||
onclick="dismissProNotification();"
|
||||
></button>
|
||||
It appears that you're not signed in. You'll need to
|
||||
<a href="/pro" target="_self">signup for Pro</a> or become a
|
||||
<a
|
||||
href="https://coil.com/?ref=InfinitySearch2229"
|
||||
target="_self"
|
||||
>Coil member</a
|
||||
>
|
||||
to access our results.
|
||||
</div> -->
|
||||
<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">
|
||||
<div id="id-side-bar" class="column is-4 sidebar_column" style="padding-top: 1.2rem; padding-right: 1.5rem; padding-left: 1.5rem">
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
</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="externals" class="">
|
||||
<div v-for="(facetItems, key, index) in facets" :key="index" name="external_card" style="margin-bottom: 0px">
|
||||
<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>
|
||||
</div>
|
||||
<!-- <div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a
|
||||
id="https://en.wikipedia.org/w/index.php?search="
|
||||
href="https://en.wikipedia.org/w/index.php?search=test"
|
||||
name="external_link_0"
|
||||
style="display: block"
|
||||
rel="noreferrer noopener"
|
||||
target="_self"
|
||||
>
|
||||
<img src="/static/images/favicons/wikipedia.ico" name="external_icon_0'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_0" style="font-size: 0.95rem; display: inline"> Wikipedia Results </span>
|
||||
</a>
|
||||
</p>
|
||||
</header>
|
||||
</div>
|
||||
<div class="card" name="external_card" style="margin-bottom: 0px">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" style="font-weight: normal; padding-right: 5px">
|
||||
<a
|
||||
id="https://duckduckgo.com/?q="
|
||||
href="https://duckduckgo.com/?q=test"
|
||||
name="external_link_1"
|
||||
style="display: block"
|
||||
rel="noreferrer noopener"
|
||||
target="_self"
|
||||
>
|
||||
<img src="/static/images/favicons/duckduckgo.ico" name="external_icon_1'" class="external-icon" />
|
||||
<span hidden="" class="external-text" name="external_text_1" style="font-size: 0.95rem; display: inline"> DuckDuckGo Results </span>
|
||||
</a>
|
||||
</p>
|
||||
<span
|
||||
class="clickableIcon"
|
||||
onclick="removeExternalClickable(this)"
|
||||
style="cursor: pointer; display: block; margin: auto; margin-right: 6px; min-width: 0.5em"
|
||||
>
|
||||
<img
|
||||
class="handle fa-ellipsis-v"
|
||||
src="/static/images/fa/ellipsis-v.svg"
|
||||
style="cursor: pointer; display: block; margin: auto; margin-right: 12px; min-width: 0.5em; width: 16px; height: 16px"
|
||||
/>
|
||||
</span>
|
||||
</header>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col col-8 column is-8 results_column" style="padding-top: 1.2rem; padding-right: 1rem; padding-left: 1rem">
|
||||
<div class="column" v-if="activeFilterCategories && Object.keys(activeFilterCategories).length > 0">
|
||||
<span class="active-filter-items" v-for="(values, key, index) in activeFilterCategories" :key="index">
|
||||
<active-facet-category v-bind:filterItems="values" :categoryName="key" @clearFacetCategory="onClearFacetCategory"></active-facet-category>
|
||||
<!-- 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 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"
|
||||
@clear-facet-category="onClearFacetCategory"
|
||||
></active-facet-category>
|
||||
</span>
|
||||
</div>
|
||||
<div class="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 -->
|
||||
<PaginationComponent class="mt-5" v-bind:data="pagination" @menu-click="onMenuClick"></PaginationComponent>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<!-- Partner logos section -->
|
||||
<div class="container-fluid">
|
||||
<!-- <div class="columns is-mobile partner-logos"> -->
|
||||
<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">
|
||||
<!-- <h5 class="card-title">About TETHYS</h5> -->
|
||||
<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>
|
||||
<div class="column col-sm text-center">
|
||||
<a target="_blank" href="http://www.geologie.ac.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="Geologische Bundesanstalt logo" />
|
||||
</a>
|
||||
<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>
|
||||
<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 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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -145,6 +104,8 @@
|
|||
<script lang="ts">
|
||||
import SearchViewComponent from "./search-view-component";
|
||||
export default SearchViewComponent;
|
||||
// import tailwind ss
|
||||
import "@/index.css";
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped></style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "ServiceViewComponent",
|
||||
})
|
||||
export default class ServiceViewComponent extends Vue {}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
<img src="@/assets/site/img/box-1-hover.jpg" alt="Datenarchivierung" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Tethys RDR publiziert und archiviert nach den FAIR Prinzipien* nachhaltig so wie sicher geowissenschaftliche Datensätze in offenen, frei lesbaren
|
||||
Formaten. * FAIR data
|
||||
Tethys RDR publiziert und archiviert nach den FAIR Prinzipien* nachhaltig so wie sicher geowissenschaftliche Datensätze in
|
||||
offenen, frei lesbaren Formaten. * FAIR data
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
<img src="@/assets/site/img/box-2-hover.jpg" alt="DATENPUBLIKATION" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Die Datensätze werden mit standardisierten Metadatenschemen publiziert und sind somit nicht nur auffindbar, wiederverwendbar und auch
|
||||
maschinenlesbar, sondern können dadurch auch einfach zitiert werden.
|
||||
Die Datensätze werden mit standardisierten Metadatenschemen publiziert und sind somit nicht nur auffindbar, wiederverwendbar und
|
||||
auch maschinenlesbar, sondern können dadurch auch einfach zitiert werden.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -48,8 +48,8 @@
|
|||
<img src="@/assets/site/img/box-3-hover.jpg" alt="BEGUTACHTUNG" />
|
||||
<div class="card-body box-1-hover">
|
||||
<p class="text-white">
|
||||
Alle im Tethys RDR publizierten Datensätze werden auf technische sowie inhaltliche Vollständigkeit geprüft und werden bei Bedarf auch einer
|
||||
fachlichen Begutachtung unterworfen. Ein klassischer Peer Review-Prozess ist in Vorbereitung.
|
||||
Alle im Tethys RDR publizierten Datensätze werden auf technische sowie inhaltliche Vollständigkeit geprüft und werden bei Bedarf
|
||||
auch einer fachlichen Begutachtung unterworfen. Ein klassischer Peer Review-Prozess ist in Vorbereitung.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { Subscription } from "rxjs";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import DatasetService from "../../services/dataset.service";
|
||||
import { DbDataset } from "@/models/dataset";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "SitelinkViewComponent",
|
||||
})
|
||||
export default class SitelinkViewComponent extends Vue {
|
||||
|
|
@ -25,11 +25,11 @@ export default class SitelinkViewComponent extends Vue {
|
|||
}
|
||||
|
||||
getYears(): void {
|
||||
const newSubs: Subscription = DatasetService.getYears().subscribe(
|
||||
(res: string[]) => this.dataHandler(res),
|
||||
(error: string) => this.errorHandler(error),
|
||||
() => newSubs.unsubscribe(),
|
||||
);
|
||||
const newSubs: Subscription = DatasetService.getYears().subscribe({
|
||||
next: (res: string[]) => this.dataHandler(res),
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
complete: () => newSubs.unsubscribe(),
|
||||
});
|
||||
// this.subscriptions.push(newSubs);
|
||||
}
|
||||
|
||||
|
|
@ -43,13 +43,14 @@ export default class SitelinkViewComponent extends Vue {
|
|||
|
||||
select(year: string): void {
|
||||
this.selected = year;
|
||||
const newSubs = DatasetService.getDocuments(year).subscribe(
|
||||
(res: Array<DbDataset>) => {
|
||||
const newSubs: Subscription = DatasetService.getDocuments(year).subscribe({
|
||||
next: (res: Array<DbDataset>) => {
|
||||
this.datasets = res;
|
||||
},
|
||||
(error: string) => this.errorHandler(error),
|
||||
);
|
||||
this.subscriptions.push(newSubs);
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
complete: () => newSubs.unsubscribe(),
|
||||
});
|
||||
// this.subscriptions.push(newSubs);
|
||||
}
|
||||
|
||||
private dataHandler(res: string[]): void {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
<section class="section">
|
||||
<div class="title has-text-centered">
|
||||
<h1 class="title">Sitelinks for Web Crawlers</h1>
|
||||
<!-- <p class="lead">Want to keep updated or need further information?</p> -->
|
||||
<hr class="center-line" />
|
||||
</div>
|
||||
<!-- <div class="column">
|
||||
|
|
@ -15,9 +14,9 @@
|
|||
</div> -->
|
||||
<div class="columns is-centered">
|
||||
<div class="column is-6-desktop">
|
||||
<div class="list" v-if="years.length > 0">
|
||||
<div v-if="years.length > 0" class="list">
|
||||
<ul class="block-list has-radius is-primary">
|
||||
<li v-for="(year, index) in years" :key="index" :class="{ highlight: year == selected }" @click="select(year)">
|
||||
<li v-for="(year, index) in years" v-bind:key="index" v-bind:class="{ highlight: year == selected }" @click="select(year)">
|
||||
{{ year }}
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -27,7 +26,7 @@
|
|||
<div class="columns is-centered">
|
||||
<div class="column is-6-desktop">
|
||||
<ol v-if="datasets.length > 0">
|
||||
<li v-for="(dataset, index) in datasets" :key="index">
|
||||
<li v-for="(dataset, index) in datasets" v-bind:key="index">
|
||||
<div class="post">
|
||||
<header class="post-header">
|
||||
<h2 class="post-title">
|
||||
|
|
@ -39,11 +38,11 @@
|
|||
</div>
|
||||
<div class="post-description">
|
||||
<!-- @foreach ($document->authors as $author) -->
|
||||
<div v-for="(author, index) in dataset.authors" :key="index">
|
||||
<div v-for="(author, index_a) in dataset.authors" v-bind:key="index_a">
|
||||
<em>Author: {{ author.full_name }}</em>
|
||||
<br />
|
||||
</div>
|
||||
<div v-for="(title, index) in dataset.titles" :key="index">
|
||||
<div v-for="(title, index_t) in dataset.titles" v-bind:key="index_t">
|
||||
<em>{{ title.type }}: {{ title.value }}</em>
|
||||
<br />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Options({
|
||||
@Component({
|
||||
name: "TermsViewComponent",
|
||||
// components: {
|
||||
// VsInput,
|
||||
|
|
|
|||
|
|
@ -9,68 +9,71 @@
|
|||
<!-- <div class="column is-half contact-us-details" style="padding-top: 0; margin-top: 0"> -->
|
||||
<div class="column is-full text-left">
|
||||
<p>
|
||||
Die Domain-Inhaberin (die GBA), explizit aber die Autoren der Website Tethys RDR (www.tethys.at), übernehmen keine Gewähr für die Aktualität, Richtigkeit und
|
||||
Vollständigkeit der bereitgestellten Informationen. Haftungsansprüche gegen die Autoren, die sich auf Schäden materieller oder ideeller Art beziehen, die durch
|
||||
die Nutzung oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung fehlerhafter und unvollständiger Informationen verursacht wurden, werden
|
||||
ausdrücklich ausgeschlossen, soweit nicht Vorsatz oder grobe Fahrlässigkeit der Autoren vorliegt. Die Autoren behalten es sich ausdrücklich vor, Teile der
|
||||
Seiten oder das gesamte Angebot ohne gesonderte Ankündigung zu verändern, zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig
|
||||
einzustellen.
|
||||
Die Domain-Inhaberin (die GBA), explizit aber die Autoren der Website Tethys RDR (www.tethys.at), übernehmen keine Gewähr für die
|
||||
Aktualität, Richtigkeit und Vollständigkeit der bereitgestellten Informationen. Haftungsansprüche gegen die Autoren, die sich auf Schäden
|
||||
materieller oder ideeller Art beziehen, die durch die Nutzung oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung
|
||||
fehlerhafter und unvollständiger Informationen verursacht wurden, werden ausdrücklich ausgeschlossen, soweit nicht Vorsatz oder grobe
|
||||
Fahrlässigkeit der Autoren vorliegt. Die Autoren behalten es sich ausdrücklich vor, Teile der Seiten oder das gesamte Angebot ohne
|
||||
gesonderte Ankündigung zu verändern, zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.
|
||||
</p>
|
||||
|
||||
<h2 class="lead">Für den Inhalt verantwortlich</h2>
|
||||
<p>
|
||||
Bei direkten oder indirekten Verweisen auf fremde Internetseiten (Links), die außerhalb des Verantwortungsbereichs der Autoren liegen, wird eine Haftung nur
|
||||
dann übernommen, wenn die Autoren von den Inhalten Kenntnis haben, dies zumutbar ist und diese über die technischen Mittel verfügen, um deren Verwendung bei
|
||||
rechtswidrigen Inhalten zu verhindern. Die Autoren erklären hiermit ausdrücklich, dass zum Zeitpunkt der Linksetzung keine illegalen Inhalte auf den zu
|
||||
verlinkenden Seiten erkennbar waren. Die Autoren haben keinerlei Einfluss auf die aktuelle und zukünftige Gestaltung und auf die Inhalte der verknüpften Seiten.
|
||||
Deshalb distanzieren sie sich hiermit ausdrücklich von allen Inhalten aller gelinkten/verknüpften Seiten, die nach der Linksetzung verändert wurden. Diese
|
||||
Feststellung gilt auch für alle innerhalb des eigenen Internetangebotes gesetzten Links und Verweise. Für illegale, fehlerhafte oder unvollständige Inhalte und
|
||||
insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, haftet allein der Anbieter der Seite, auf die
|
||||
verwiesen wurde, nicht derjenige, der via Link auf die betreffende Seite verwiesen wurde.
|
||||
Bei direkten oder indirekten Verweisen auf fremde Internetseiten (Links), die außerhalb des Verantwortungsbereichs der Autoren liegen, wird
|
||||
eine Haftung nur dann übernommen, wenn die Autoren von den Inhalten Kenntnis haben, dies zumutbar ist und diese über die technischen Mittel
|
||||
verfügen, um deren Verwendung bei rechtswidrigen Inhalten zu verhindern. Die Autoren erklären hiermit ausdrücklich, dass zum Zeitpunkt der
|
||||
Linksetzung keine illegalen Inhalte auf den zu verlinkenden Seiten erkennbar waren. Die Autoren haben keinerlei Einfluss auf die aktuelle
|
||||
und zukünftige Gestaltung und auf die Inhalte der verknüpften Seiten. Deshalb distanzieren sie sich hiermit ausdrücklich von allen Inhalten
|
||||
aller gelinkten/verknüpften Seiten, die nach der Linksetzung verändert wurden. Diese Feststellung gilt auch für alle innerhalb des eigenen
|
||||
Internetangebotes gesetzten Links und Verweise. Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus
|
||||
der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, haftet allein der Anbieter der Seite, auf die verwiesen
|
||||
wurde, nicht derjenige, der via Link auf die betreffende Seite verwiesen wurde.
|
||||
</p>
|
||||
|
||||
<h2 class="lead">Urheber- und Kennzeichenrecht</h2>
|
||||
<p>
|
||||
Die Autoren sind bestrebt, in allen Publikationen die Urheberrechte aller verwendeten Grafiken und Texte zu beachten, von ihnen selbst erstellte Grafiken und
|
||||
Texte zu nutzen oder auf lizenzfreie Grafiken und Texte zurückzugreifen. Alle innerhalb des Internetangebotes genannten und von Dritten registrierten Marken-
|
||||
und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts und den Besitzrechten der jeweiligen eingetragenen
|
||||
Eigentümer. Allein aufgrund der bloßen Nennung ist nicht der Schluss zu ziehen, dass Markenzeichen nicht den Rechten Dritter unterliegen. Sofern nicht anders
|
||||
angegeben, wird der Inhalt dieser Website unter einer Creative Commons Attribution 3.0-Lizenz lizenziert.
|
||||
Die Autoren sind bestrebt, in allen Publikationen die Urheberrechte aller verwendeten Grafiken und Texte zu beachten, von ihnen selbst
|
||||
erstellte Grafiken und Texte zu nutzen oder auf lizenzfreie Grafiken und Texte zurückzugreifen. Alle innerhalb des Internetangebotes
|
||||
genannten und von Dritten registrierten Marken- und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen
|
||||
Kennzeichenrechts und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung ist nicht der Schluss zu
|
||||
ziehen, dass Markenzeichen nicht den Rechten Dritter unterliegen. Sofern nicht anders angegeben, wird der Inhalt dieser Website unter einer
|
||||
Creative Commons Attribution 3.0-Lizenz lizenziert.
|
||||
</p>
|
||||
<h2 class="lead">Datenschutz-Bestimmungen</h2>
|
||||
<p>
|
||||
Mit dieser Datenschutzerklärung möchte unsere gastgebende Einrichtung, die „Geologische Bundesanstalt“, die Öffentlichkeit über Art, Umfang und Zweck der von
|
||||
uns erhobenen, verwendeten und verarbeiteten personenbezogenen Daten informieren. Darüber hinaus werden betroffene Personen mittels dieser Datenschutzerklärung
|
||||
über die ihnen zustehenden Rechte informiert.
|
||||
Mit dieser Datenschutzerklärung möchte unsere gastgebende Einrichtung, die „GeoSphere Austria“, die Öffentlichkeit über Art, Umfang und
|
||||
Zweck der von uns erhobenen, verwendeten und verarbeiteten personenbezogenen Daten informieren. Darüber hinaus werden betroffene Personen
|
||||
mittels dieser Datenschutzerklärung über die ihnen zustehenden Rechte informiert.
|
||||
</p>
|
||||
<p>
|
||||
Die Nutzung der Internetseiten von Tethys RDR ist ohne Angabe personenbezogener Daten möglich. Wenn eine betroffene Person jedoch unsere Dienste wie das
|
||||
Übermitteln von Datensätzen nutzen oder mit uns in Kontakt treten möchte, ist die Verarbeitung personenbezogener Daten erforderlich. Wenn die Verarbeitung
|
||||
personenbezogener Daten notwendig ist und keine gesetzliche Grundlage für eine solche Verarbeitung besteht, holen wir in der Regel die Zustimmung der
|
||||
betroffenen Person ein. Wir erfassen Informationen von Ihnen, wenn Sie sich auf unserer Website anmelden.
|
||||
Die Nutzung der Internetseiten von Tethys RDR ist ohne Angabe personenbezogener Daten möglich. Wenn eine betroffene Person jedoch unsere
|
||||
Dienste wie das Übermitteln von Datensätzen nutzen oder mit uns in Kontakt treten möchte, ist die Verarbeitung personenbezogener Daten
|
||||
erforderlich. Wenn die Verarbeitung personenbezogener Daten notwendig ist und keine gesetzliche Grundlage für eine solche Verarbeitung
|
||||
besteht, holen wir in der Regel die Zustimmung der betroffenen Person ein. Wir erfassen Informationen von Ihnen, wenn Sie sich auf unserer
|
||||
Website anmelden.
|
||||
</p>
|
||||
<p>
|
||||
Die Verarbeitung personenbezogener Daten von datenpublizierenden Autoren, deren Co-Autoren sowie Beitragende, wie Name, E-Mail-Adresse und optional die ORCID ID
|
||||
erfolgt stets durch die datenpublizierenden Autoren im Einklang mit der Allgemeinen Datenschutzgrundverordnung (DSGVO) nach Artikel 6, Absatz 1b. Diese
|
||||
Informationen werden zum Zwecke der Anmeldung der datenpublizierenden Autoren und zum Zwecke der Umsetzung der guten wissenschaftlichen Praxis gesammelt. Damit
|
||||
einher geht, dass nach erfolgreichem Publizieren der Daten keine Löschung oder Veränderung der Daten und Metadaten inklusive aller personenbezogenen Daten
|
||||
möglich ist.
|
||||
Die Verarbeitung personenbezogener Daten von datenpublizierenden Autoren, deren Co-Autoren sowie Beitragende, wie Name, E-Mail-Adresse und
|
||||
optional die ORCID ID erfolgt stets durch die datenpublizierenden Autoren im Einklang mit der Allgemeinen Datenschutzgrundverordnung (DSGVO)
|
||||
nach Artikel 6, Absatz 1b. Diese Informationen werden zum Zwecke der Anmeldung der datenpublizierenden Autoren und zum Zwecke der Umsetzung
|
||||
der guten wissenschaftlichen Praxis gesammelt. Damit einher geht, dass nach erfolgreichem Publizieren der Daten keine Löschung oder
|
||||
Veränderung der Daten und Metadaten inklusive aller personenbezogenen Daten möglich ist.
|
||||
</p>
|
||||
<p>
|
||||
Als für die Verarbeitung Verantwortlicher hat Tethys RDR zahlreiche technische und organisatorische Maßnahmen getroffen, um den bestmöglichen Schutz der über
|
||||
diese Website verarbeiteten personenbezogenen Daten sicherzustellen. Internetbasierte Datenübertragungen können jedoch grundsätzlich Sicherheitslücken
|
||||
aufweisen, so dass ein absoluter Schutz möglicherweise nicht gewährleistet ist.
|
||||
Als für die Verarbeitung Verantwortlicher hat Tethys RDR zahlreiche technische und organisatorische Maßnahmen getroffen, um den
|
||||
bestmöglichen Schutz der über diese Website verarbeiteten personenbezogenen Daten sicherzustellen. Internetbasierte Datenübertragungen
|
||||
können jedoch grundsätzlich Sicherheitslücken aufweisen, so dass ein absoluter Schutz möglicherweise nicht gewährleistet ist.
|
||||
</p>
|
||||
<p>
|
||||
Sie haben grundsätzlich das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit und Widerspruch. Dafür wenden Sie sich bitte an die
|
||||
Datenschutzbeauftragte:
|
||||
Sie haben grundsätzlich das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit und Widerspruch. Dafür wenden
|
||||
Sie sich bitte an die Datenschutzbeauftragte:
|
||||
</p>
|
||||
<span>Dr. Viktoria Haider</span><br />
|
||||
<span>E-Mail: <a href="mailto:datenschutz@geologie.ac.at">datenschutz@geologie.ac.at</a></span
|
||||
><br />
|
||||
<p>
|
||||
Wenn Sie glauben, dass die Verarbeitung Ihrer Daten gegen das Datenschutzrecht verstößt oder Ihre datenschutzrechtlichen Ansprüche sonst in einer Weise verletzt
|
||||
worden sind, können Sie bei der dafür zuständigen Aufsichtsbehörde eine Beschwerde einlegen:
|
||||
Wenn Sie glauben, dass die Verarbeitung Ihrer Daten gegen das Datenschutzrecht verstößt oder Ihre datenschutzrechtlichen Ansprüche sonst in
|
||||
einer Weise verletzt worden sind, können Sie bei der dafür zuständigen Aufsichtsbehörde eine Beschwerde einlegen:
|
||||
</p>
|
||||
<span>Österreichische Datenschutzbehörde</span><br />
|
||||
<span>Barichgasse 40–42, 1030 Wien</span><br />
|
||||
|
|
@ -79,112 +82,123 @@
|
|||
><br />
|
||||
<h3 class="lead">Erfassung allgemeiner Daten und Informationen</h3>
|
||||
<p>
|
||||
Die Website von Tethys RDR sammelt eine Reihe von allgemeinen Daten und Informationen, wenn eine betroffene Person oder ein automatisiertes System die Website
|
||||
aufruft. Diese allgemeinen Daten und Informationen werden in den Server-Protokolldateien gespeichert. Gesammelt werden (1) die verwendeten Browsertypen und
|
||||
-versionen, (2) das vom zugreifenden System verwendete Betriebssystem, (3) die Website, von der aus ein zugreifendes System auf unsere Website gelangt
|
||||
(sogenannte Referrer), (4) die Sub-websites, (5) Datum und Uhrzeit des Zugriffs auf die Internetseite, (6) eine Internetprotokolladresse (IP-Adresse), (7) der
|
||||
Internetdienstanbieter des zugreifenden Systems und (8) alle anderen ähnlichen Daten und Informationen, die im Falle von Angriffen auf unsere
|
||||
Informationstechnologiesysteme verwendet werden können.
|
||||
Die Website von Tethys RDR sammelt eine Reihe von allgemeinen Daten und Informationen, wenn eine betroffene Person oder ein automatisiertes
|
||||
System die Website aufruft. Diese allgemeinen Daten und Informationen werden in den Server-Protokolldateien gespeichert. Gesammelt werden
|
||||
(1) die verwendeten Browsertypen und -versionen, (2) das vom zugreifenden System verwendete Betriebssystem, (3) die Website, von der aus ein
|
||||
zugreifendes System auf unsere Website gelangt (sogenannte Referrer), (4) die Sub-websites, (5) Datum und Uhrzeit des Zugriffs auf die
|
||||
Internetseite, (6) eine Internetprotokolladresse (IP-Adresse), (7) der Internetdienstanbieter des zugreifenden Systems und (8) alle anderen
|
||||
ähnlichen Daten und Informationen, die im Falle von Angriffen auf unsere Informationstechnologiesysteme verwendet werden können.
|
||||
</p>
|
||||
<p>
|
||||
Bei Verwendung dieser allgemeinen Daten und Informationen kann Tethys RDR keine Rückschlüsse auf die betroffene Person ziehen. Diese Informationen werden
|
||||
vielmehr benötigt, um (1) den Inhalt unserer Website korrekt bereitzustellen, (2) den Inhalt unserer Website sowie deren Werbung zu optimieren, (3) die
|
||||
langfristige Überlebensfähigkeit unserer Informationstechnologiesysteme und der Website-Technologie sicherzustellen und (4) den Strafverfolgungsbehörden, welche
|
||||
für die strafrechtliche Verfolgung im Falle eines Cyberangriffs erforderlichen Informationen zur Verfügung stellen. Daher analysiert Tethys RDR anonym erhobene
|
||||
Daten und Informationen statistisch mit dem Ziel, den Datenschutz und die Datensicherheit unserer Institution zu erhöhen und ein optimales Schutzniveau für die
|
||||
von uns verarbeiteten personenbezogenen Daten zu gewährleisten. Die anonymen Daten der Server-Logfiles werden getrennt von allen personenbezogenen Daten einer
|
||||
Bei Verwendung dieser allgemeinen Daten und Informationen kann Tethys RDR keine Rückschlüsse auf die betroffene Person ziehen. Diese
|
||||
Informationen werden vielmehr benötigt, um (1) den Inhalt unserer Website korrekt bereitzustellen, (2) den Inhalt unserer Website sowie
|
||||
deren Werbung zu optimieren, (3) die langfristige Überlebensfähigkeit unserer Informationstechnologiesysteme und der Website-Technologie
|
||||
sicherzustellen und (4) den Strafverfolgungsbehörden, welche für die strafrechtliche Verfolgung im Falle eines Cyberangriffs erforderlichen
|
||||
Informationen zur Verfügung stellen. Daher analysiert Tethys RDR anonym erhobene Daten und Informationen statistisch mit dem Ziel, den
|
||||
Datenschutz und die Datensicherheit unserer Institution zu erhöhen und ein optimales Schutzniveau für die von uns verarbeiteten
|
||||
personenbezogenen Daten zu gewährleisten. Die anonymen Daten der Server-Logfiles werden getrennt von allen personenbezogenen Daten einer
|
||||
betroffenen Person gespeichert.
|
||||
</p>
|
||||
<h3 class="lead">Anmeldung/Registrierung auf unserer Website</h3>
|
||||
<p>
|
||||
Die betroffene Person hat die Möglichkeit, sich auf der Website des für die Verarbeitung Verantwortlichen unter Angabe personenbezogener Daten anzumelden (zu
|
||||
registrieren). Welche personenbezogenen Daten an die Steuerung übermittelt werden, bestimmt die jeweilige Eingabemaske des Anmeldeformulars. Die von der
|
||||
betroffenen Person eingegebenen personenbezogenen Daten werden ausschließlich für den internen Gebrauch durch den für die Verarbeitung Verantwortlichen und für
|
||||
eigene Zwecke erhoben und gespeichert. Der Controller kann die Übertragung an einen oder mehrere Prozessoren (z.B. einen wissenschaftlichen Herausgeber)
|
||||
anfordern, die personenbezogene Daten auch für einen internen Zweck verwenden, der dem Controller zuzuordnen ist.
|
||||
Die betroffene Person hat die Möglichkeit, sich auf der Website des für die Verarbeitung Verantwortlichen unter Angabe personenbezogener
|
||||
Daten anzumelden (zu registrieren). Welche personenbezogenen Daten an die Steuerung übermittelt werden, bestimmt die jeweilige Eingabemaske
|
||||
des Anmeldeformulars. Die von der betroffenen Person eingegebenen personenbezogenen Daten werden ausschließlich für den internen Gebrauch
|
||||
durch den für die Verarbeitung Verantwortlichen und für eigene Zwecke erhoben und gespeichert. Der Controller kann die Übertragung an einen
|
||||
oder mehrere Prozessoren (z.B. einen wissenschaftlichen Herausgeber) anfordern, die personenbezogene Daten auch für einen internen Zweck
|
||||
verwenden, der dem Controller zuzuordnen ist.
|
||||
</p>
|
||||
<p>
|
||||
Durch die Registrierung auf der Website des Controllers werden auch die vom Internet Service Provider (ISP) zugewiesene und vom Betroffenen verwendete
|
||||
IP-Adresse – Datum und Uhrzeit der Registrierung – gespeichert. Die Speicherung dieser Daten erfolgt vor dem Hintergrund, dass nur so ein Missbrauch unserer
|
||||
Dienste verhindert und gegebenenfalls eine Aufklärung der begangenen Verstöße ermöglicht wird. Insofern ist die Speicherung dieser Daten erforderlich, um die
|
||||
Steuerung abzusichern. Diese Daten werden ohne Ihre ausdrückliche Zustimmung nicht an Dritte weitergegeben, es sei denn, es besteht eine gesetzliche
|
||||
Verpflichtung zur Weitergabe der Daten oder die Übermittlung dient der strafrechtlichen Verfolgung.
|
||||
Durch die Registrierung auf der Website des Controllers werden auch die vom Internet Service Provider (ISP) zugewiesene und vom Betroffenen
|
||||
verwendete IP-Adresse – Datum und Uhrzeit der Registrierung – gespeichert. Die Speicherung dieser Daten erfolgt vor dem Hintergrund, dass
|
||||
nur so ein Missbrauch unserer Dienste verhindert und gegebenenfalls eine Aufklärung der begangenen Verstöße ermöglicht wird. Insofern ist
|
||||
die Speicherung dieser Daten erforderlich, um die Steuerung abzusichern. Diese Daten werden ohne Ihre ausdrückliche Zustimmung nicht an
|
||||
Dritte weitergegeben, es sei denn, es besteht eine gesetzliche Verpflichtung zur Weitergabe der Daten oder die Übermittlung dient der
|
||||
strafrechtlichen Verfolgung.
|
||||
</p>
|
||||
<p>
|
||||
Die Registrierung der betroffenen Person mit der freiwilligen Angabe personenbezogener Daten soll es dem für die Verarbeitung Verantwortlichen ermöglichen, die
|
||||
betroffenen Inhalte oder Dienste anzubieten, die aufgrund der Art der betreffenden Angelegenheit nur registrierten Nutzern angeboten werden dürfen. Registrierte
|
||||
Personen können die bei der Registrierung angegebenen personenbezogenen Daten jederzeit ändern oder vollständig aus dem Datenbestand des Verantwortlichen
|
||||
löschen lassen.
|
||||
Die Registrierung der betroffenen Person mit der freiwilligen Angabe personenbezogener Daten soll es dem für die Verarbeitung
|
||||
Verantwortlichen ermöglichen, die betroffenen Inhalte oder Dienste anzubieten, die aufgrund der Art der betreffenden Angelegenheit nur
|
||||
registrierten Nutzern angeboten werden dürfen. Registrierte Personen können die bei der Registrierung angegebenen personenbezogenen Daten
|
||||
jederzeit ändern oder vollständig aus dem Datenbestand des Verantwortlichen löschen lassen.
|
||||
</p>
|
||||
<p>
|
||||
Der für die Verarbeitung Verantwortliche teilt jeder betroffenen Person auf Anfrage jederzeit mit, welche personenbezogenen Daten über die betroffene Person
|
||||
gespeichert sind. Darüber hinaus berichtigt oder löscht der für die Datenverarbeitung Verantwortliche personenbezogene Daten auf Verlangen oder unter Angabe der
|
||||
betroffenen Person, sofern keine gesetzlichen Aufbewahrungspflichten bestehen. Ein in dieser Datenschutzerklärung ausdrücklich benannter Datenschutzbeauftragter
|
||||
sowie die gesamten Mitarbeiter des für die Verarbeitung Verantwortlichen stehen der betroffenen Person als Ansprechpartner zur Verfügung.
|
||||
Der für die Verarbeitung Verantwortliche teilt jeder betroffenen Person auf Anfrage jederzeit mit, welche personenbezogenen Daten über die
|
||||
betroffene Person gespeichert sind. Darüber hinaus berichtigt oder löscht der für die Datenverarbeitung Verantwortliche personenbezogene
|
||||
Daten auf Verlangen oder unter Angabe der betroffenen Person, sofern keine gesetzlichen Aufbewahrungspflichten bestehen. Ein in dieser
|
||||
Datenschutzerklärung ausdrücklich benannter Datenschutzbeauftragter sowie die gesamten Mitarbeiter des für die Verarbeitung Verantwortlichen
|
||||
stehen der betroffenen Person als Ansprechpartner zur Verfügung.
|
||||
</p>
|
||||
<h3 class="lead">Kontaktmöglichkeit über die Website</h3>
|
||||
<p>
|
||||
Die Website von Tethys RDR enthält Informationen, die einen schnellen elektronischen Kontakt zu unserer Einrichtung sowie eine direkte Kommunikation mit uns
|
||||
ermöglichen. Dazu gehört auch eine allgemeine Adresse der sogenannten elektronischen Post (E-Mail-Adresse). Wenn eine betroffene Person den für die Verarbeitung
|
||||
Verantwortlichen per E-Mail über das Kontaktformular kontaktiert, werden die von der betroffenen Person übermittelten personenbezogenen Daten automatisch
|
||||
gespeichert. Diese von einer betroffenen Person freiwillig übermittelten personenbezogenen Daten werden zum Zwecke der Verarbeitung oder Kontaktaufnahme mit der
|
||||
betroffenen Person gespeichert. Bei Nutzung des Kontaktformulars erfolgt keine Weitergabe dieser personenbezogenen Daten an Dritte.
|
||||
Die Website von Tethys RDR enthält Informationen, die einen schnellen elektronischen Kontakt zu unserer Einrichtung sowie eine direkte
|
||||
Kommunikation mit uns ermöglichen. Dazu gehört auch eine allgemeine Adresse der sogenannten elektronischen Post (E-Mail-Adresse). Wenn eine
|
||||
betroffene Person den für die Verarbeitung Verantwortlichen per E-Mail über das Kontaktformular kontaktiert, werden die von der betroffenen
|
||||
Person übermittelten personenbezogenen Daten automatisch gespeichert. Diese von einer betroffenen Person freiwillig übermittelten
|
||||
personenbezogenen Daten werden zum Zwecke der Verarbeitung oder Kontaktaufnahme mit der betroffenen Person gespeichert. Bei Nutzung des
|
||||
Kontaktformulars erfolgt keine Weitergabe dieser personenbezogenen Daten an Dritte.
|
||||
</p>
|
||||
<h3 class="lead">Übermittlung wissenschaftlicher Daten über die Website</h3>
|
||||
<p>
|
||||
Die Website von Tethys RDR enthält eine Webanwendung zum Einreichen von wissenschaftlichen Datensätzen, die in der Tethys -Datenbank gespeichert werden, um sie
|
||||
zu veröffentlichen. Wenn eine betroffene Person mit dem Antrag auf Einreichung wissenschaftlicher Daten Kontakt zum für die Verarbeitung Verantwortlichen
|
||||
aufnimmt, werden die von der betroffenen Person übermittelten personenbezogenen Daten automatisch gespeichert. Diese von einer betroffenen Person freiwillig
|
||||
übermittelten personenbezogenen Daten werden zum Zwecke der Verarbeitung oder Kontaktaufnahme mit der betroffenen Person gespeichert.
|
||||
Die Website von Tethys RDR enthält eine Webanwendung zum Einreichen von wissenschaftlichen Datensätzen, die in der Tethys -Datenbank
|
||||
gespeichert werden, um sie zu veröffentlichen. Wenn eine betroffene Person mit dem Antrag auf Einreichung wissenschaftlicher Daten Kontakt
|
||||
zum für die Verarbeitung Verantwortlichen aufnimmt, werden die von der betroffenen Person übermittelten personenbezogenen Daten automatisch
|
||||
gespeichert. Diese von einer betroffenen Person freiwillig übermittelten personenbezogenen Daten werden zum Zwecke der Verarbeitung oder
|
||||
Kontaktaufnahme mit der betroffenen Person gespeichert.
|
||||
</p>
|
||||
<p>
|
||||
Um wissenschaftliche Datensätze erfolgreich bei Tethys RDR einzureichen, muss die betroffene Person einige zusätzliche personenbezogene Daten (z.B. Name der
|
||||
Autoren, der Mitautoren und Beitragende) bereitstellen, damit diese Datensätze in der wissenschaftlichen Gemeinschaft korrekt zitiert werden können. Diese
|
||||
Informationen werden der Öffentlichkeit nach dem Einreichungsprozess über Datensatz-Metadaten (im XML- oder JSON-Format und über die Tethys-Website) zur
|
||||
Verfügung gestellt. Dies ist eine Voraussetzung für das wissenschaftliche Publizieren. Veröffentlichungen zu wissenschaftlichen Daten, einschließlich der oben
|
||||
genannten personenbezogenen Daten, können von Dritten (z.B. Bibliotheken, Datenportalen) unter Verwendung der Metadaten und Datendienste von Tethys RDR
|
||||
verwendet werden.
|
||||
Um wissenschaftliche Datensätze erfolgreich bei Tethys RDR einzureichen, muss die betroffene Person einige zusätzliche personenbezogene
|
||||
Daten (z.B. Name der Autoren, der Mitautoren und Beitragende) bereitstellen, damit diese Datensätze in der wissenschaftlichen Gemeinschaft
|
||||
korrekt zitiert werden können. Diese Informationen werden der Öffentlichkeit nach dem Einreichungsprozess über Datensatz-Metadaten (im XML-
|
||||
oder JSON-Format und über die Tethys-Website) zur Verfügung gestellt. Dies ist eine Voraussetzung für das wissenschaftliche Publizieren.
|
||||
Veröffentlichungen zu wissenschaftlichen Daten, einschließlich der oben genannten personenbezogenen Daten, können von Dritten (z.B.
|
||||
Bibliotheken, Datenportalen) unter Verwendung der Metadaten und Datendienste von Tethys RDR verwendet werden.
|
||||
</p>
|
||||
<h3 class="lead">Nutzung von Content Delivery Networks (CDN)</h3>
|
||||
<p>
|
||||
Auf dieser Website hat der Controller Javascript, Schriftarten und Bilder integriert, die von Content Delivery Networks bereitgestellt werden. Ein Content
|
||||
Delivery Network (CDN) ist ein geografisch verteiltes Netzwerk von Proxy-Servern und deren Rechenzentren. Ziel ist es, den Service räumlich auf die Endbenutzer
|
||||
zu verteilen, um eine hohe Verfügbarkeit und Leistung zu gewährleisten. Während dieses technischen Verfahrens können Dritte Kenntnis von personenbezogenen
|
||||
Daten, wie der IP-Adresse der betroffenen Person, erlangen. Die bei Tethys verwendeten CDN-Dienste wurden vom Controller auf DSGVO-Konformität geprüft.
|
||||
Auf dieser Website hat der Controller Javascript, Schriftarten und Bilder integriert, die von Content Delivery Networks bereitgestellt
|
||||
werden. Ein Content Delivery Network (CDN) ist ein geografisch verteiltes Netzwerk von Proxy-Servern und deren Rechenzentren. Ziel ist es,
|
||||
den Service räumlich auf die Endbenutzer zu verteilen, um eine hohe Verfügbarkeit und Leistung zu gewährleisten. Während dieses technischen
|
||||
Verfahrens können Dritte Kenntnis von personenbezogenen Daten, wie der IP-Adresse der betroffenen Person, erlangen. Die bei Tethys
|
||||
verwendeten CDN-Dienste wurden vom Controller auf DSGVO-Konformität geprüft.
|
||||
</p>
|
||||
<h3 class="lead">Routinemäßige Löschung und Sperrung personenbezogener Daten</h3>
|
||||
<p>
|
||||
Der für die Verarbeitung Verantwortliche verarbeitet und speichert die personenbezogenen Daten der betroffenen Person nur für den Zeitraum, der zur Erreichung
|
||||
des Zwecks der Speicherung erforderlich ist, oder, soweit dies vom europäischen Gesetzgeber oder anderen Gesetzgebern in Gesetzen oder Verordnungen, denen der
|
||||
für die Verarbeitung Verantwortliche unterliegt, gewährt wird.
|
||||
Der für die Verarbeitung Verantwortliche verarbeitet und speichert die personenbezogenen Daten der betroffenen Person nur für den Zeitraum,
|
||||
der zur Erreichung des Zwecks der Speicherung erforderlich ist, oder, soweit dies vom europäischen Gesetzgeber oder anderen Gesetzgebern in
|
||||
Gesetzen oder Verordnungen, denen der für die Verarbeitung Verantwortliche unterliegt, gewährt wird.
|
||||
</p>
|
||||
<p>
|
||||
Ist der Speicherzweck nicht anwendbar oder läuft eine vom europäischen Gesetzgeber oder einem anderen zuständigen Gesetzgeber festgelegte Speicherfrist ab,
|
||||
werden die personenbezogenen Daten gemäß den gesetzlichen Bestimmungen routinemäßig gesperrt oder gelöscht.
|
||||
Ist der Speicherzweck nicht anwendbar oder läuft eine vom europäischen Gesetzgeber oder einem anderen zuständigen Gesetzgeber festgelegte
|
||||
Speicherfrist ab, werden die personenbezogenen Daten gemäß den gesetzlichen Bestimmungen routinemäßig gesperrt oder gelöscht.
|
||||
</p>
|
||||
<p>
|
||||
Bitte beachten Sie auch unsere rechtlichen Hinweise zu Nutzung, Haftungsausschluss und Haftungsbeschränkungen für die Nutzung unserer
|
||||
Website.
|
||||
</p>
|
||||
<p>Bitte beachten Sie auch unsere rechtlichen Hinweise zu Nutzung, Haftungsausschluss und Haftungsbeschränkungen für die Nutzung unserer Website.</p>
|
||||
<h3 class="lead">Uns kontaktieren</h3>
|
||||
<p>Bei Fragen zu dieser Datenschutzrichtlinie können Sie sich an uns wenden (<a href="/contact" target="_blank">Kontakt</a>).</p>
|
||||
<h3 class="lead">Änderungen unserer Datenschutzerklärung</h3>
|
||||
<p>
|
||||
Wenn wir uns entscheiden, unsere Datenschutzrichtlinie zu ändern, werden wir diese Änderungen auf dieser Seite veröffentlichen. Diese Richtlinie wurde zuletzt
|
||||
am 25.03.2020 geändert.
|
||||
Wenn wir uns entscheiden, unsere Datenschutzrichtlinie zu ändern, werden wir diese Änderungen auf dieser Seite veröffentlichen. Diese
|
||||
Richtlinie wurde zuletzt am 25.03.2020 geändert.
|
||||
</p>
|
||||
<h3 class="lead">OpenStreetMap</h3>
|
||||
<p>
|
||||
Diese Seite nutzt über eine Programmierschnittstelle (Application Programming Interface, API) das Open Source-Mapping-Werkzeug „OpenStreetMap“ (OSM). Anbieter
|
||||
ist die OpenStreetMap Foundation. Zur Nutzung der Funktionen von OpenStreetMap ist es notwendig, Ihre IP-Adresse zu speichern. Diese Informationen werden in der
|
||||
Regel an einen Server von OpenStreetMap übertragen und dort gespeichert. Der Anbieter dieser Seite hat keinen Einfluss auf diese Datenübertragung. Die Nutzung
|
||||
von OpenStreetMap erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote und an einer leichten Auffindbarkeit der von uns auf der Website
|
||||
angegebenen Orte. Dies stellt ein berechtigtes Interesse im Sinne von Artikel 6, Absatz 1 lit. f DSGVO dar. Mehr Informationen zum Umgang mit Nutzerdaten finden
|
||||
Sie in der Datenschutzseite von OpenStreetMap und auf
|
||||
Diese Seite nutzt über eine Programmierschnittstelle (Application Programming Interface, API) das Open Source-Mapping-Werkzeug
|
||||
„OpenStreetMap“ (OSM). Anbieter ist die OpenStreetMap Foundation. Zur Nutzung der Funktionen von OpenStreetMap ist es notwendig, Ihre
|
||||
IP-Adresse zu speichern. Diese Informationen werden in der Regel an einen Server von OpenStreetMap übertragen und dort gespeichert. Der
|
||||
Anbieter dieser Seite hat keinen Einfluss auf diese Datenübertragung. Die Nutzung von OpenStreetMap erfolgt im Interesse einer ansprechenden
|
||||
Darstellung unserer Online-Angebote und an einer leichten Auffindbarkeit der von uns auf der Website angegebenen Orte. Dies stellt ein
|
||||
berechtigtes Interesse im Sinne von Artikel 6, Absatz 1 lit. f DSGVO dar. Mehr Informationen zum Umgang mit Nutzerdaten finden Sie in der
|
||||
Datenschutzseite von OpenStreetMap und auf
|
||||
<a href="http://wiki.openstreetmap.org/wiki/Legal_FAQ" target="_blank">/wiki.openstreetmap.org/wiki/Legal_FAQ</a>.
|
||||
</p>
|
||||
<h3 class="lead">Rechtswirksamkeit dieses Haftungsausschlusses</h3>
|
||||
<p>
|
||||
Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese Seite verwiesen wurde. Sollten Teile des Textes oder eines
|
||||
Wortlautes nicht, nicht vollständig oder nicht mehr dem geltenden Recht entsprechen, so wird hierdurch die Gültigkeit oder der Inhalt der übrigen Teile des
|
||||
Dokumentes nicht berührt.
|
||||
Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese Seite verwiesen wurde. Sollten Teile des
|
||||
Textes oder eines Wortlautes nicht, nicht vollständig oder nicht mehr dem geltenden Recht entsprechen, so wird hierdurch die Gültigkeit oder
|
||||
der Inhalt der übrigen Teile des Dokumentes nicht berührt.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
101
tailwind.config.js
Normal file
101
tailwind.config.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
module.exports = {
|
||||
// purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
||||
content: ["./src/**/*.{edge,js,ts,jsx,tsx,vue}"],
|
||||
darkMode: "media", // or 'media' or 'class'
|
||||
theme: {
|
||||
asideScrollbars: {
|
||||
light: 'light',
|
||||
gray: 'gray',
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#22C55E",
|
||||
inprogress: "rgb(94 234 212)",
|
||||
released: "rgb(52 211 153)",
|
||||
"editor-accepted": "rgb(125 211 252)",
|
||||
approved: "#BFCE40",
|
||||
"rejected-editor": "#f97316",
|
||||
"rejected-reviewer": "#f97316",
|
||||
reviewed: "#34d399", // emerald
|
||||
published: "#34d399", // sky
|
||||
"primary-dark": "#DCFCE7",
|
||||
lime: {
|
||||
DEFAULT: "#BFCE40",
|
||||
dark: "rgba(5,46,55,0.7)",
|
||||
50: "#FBFCF7",
|
||||
100: "#F8FBE1",
|
||||
200: "#EEF69E",
|
||||
300: "#DCEC53",
|
||||
400: "#A8D619",
|
||||
500: "#65DC21",
|
||||
600: "#429E04",
|
||||
700: "#357C06",
|
||||
800: "#295B09",
|
||||
900: "#20450A",
|
||||
},
|
||||
},
|
||||
zIndex: {
|
||||
'-1': '-1',
|
||||
},
|
||||
flexGrow: {
|
||||
5: '5',
|
||||
},
|
||||
maxHeight: {
|
||||
'screen-menu': 'calc(100vh - 3.5rem)',
|
||||
'modal': 'calc(100vh - 160px)',
|
||||
},
|
||||
transitionProperty: {
|
||||
position: 'right, left, top, bottom, margin, padding',
|
||||
textColor: 'color',
|
||||
},
|
||||
keyframes: {
|
||||
'fade-out': {
|
||||
from: { opacity: 1 },
|
||||
to: { opacity: 0 },
|
||||
},
|
||||
'fade-in': {
|
||||
from: { opacity: 0 },
|
||||
to: { opacity: 1 },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
'fade-out': 'fade-out 250ms ease-in-out',
|
||||
'fade-in': 'fade-in 250ms ease-in-out',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
plugin(function ({ matchUtilities, theme }) {
|
||||
matchUtilities(
|
||||
{
|
||||
'aside-scrollbars': (value) => {
|
||||
const track = value === 'light' ? '100' : '900';
|
||||
const thumb = value === 'light' ? '300' : '600';
|
||||
const color = value === 'light' ? 'gray' : value;
|
||||
|
||||
return {
|
||||
'scrollbarWidth': 'thin',
|
||||
'scrollbarColor': `${theme(`colors.${color}.${thumb}`)} ${theme(`colors.${color}.${track}`)}`,
|
||||
'&::-webkit-scrollbar': {
|
||||
width: '8px',
|
||||
height: '8px',
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
backgroundColor: theme(`colors.${color}.${track}`),
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
borderRadius: '0.25rem',
|
||||
backgroundColor: theme(`colors.${color}.${thumb}`),
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{ values: theme('asideScrollbars') },
|
||||
);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
//what module code is generated
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
101
vue.config.cjs
Normal file
101
vue.config.cjs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/* eslint @typescript-eslint/no-var-requires: "off" */
|
||||
const webpack = require("webpack");
|
||||
// const { defineConfig } = require("@vue/cli-service");
|
||||
// const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
|
||||
const { VueLoaderPlugin } = require("vue-loader");
|
||||
|
||||
module.exports = {
|
||||
lintOnSave: false,
|
||||
publicPath: "/",
|
||||
chainWebpack: (config) => {
|
||||
const vueRule = config.module.rule("vue");
|
||||
vueRule.uses.clear();
|
||||
// const tsRule = config.module.rule("ts");
|
||||
// tsRule.uses.clear();
|
||||
// .plugin('define')
|
||||
// .tap(args => {
|
||||
// args[0] = {
|
||||
// ...args[0],
|
||||
// VUE_API: JSON.stringify(process.env.PORTAL),
|
||||
// // other stuff
|
||||
// }
|
||||
// return args
|
||||
// })
|
||||
},
|
||||
pages: {
|
||||
index: {
|
||||
// entry for the page
|
||||
entry: "src/main.ts",
|
||||
title: "TETHYS - Research Data Repository",
|
||||
},
|
||||
},
|
||||
// devServer: {
|
||||
// disableHostCheck: true,
|
||||
// },
|
||||
configureWebpack: {
|
||||
devtool: "source-map",
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: "vue-loader",
|
||||
options: {
|
||||
// loaders: {
|
||||
// ts: 'ts-loader',
|
||||
// },
|
||||
cacheDirectory: "C:\\Users\\kaiarn\\Documents\\Software\\tethys.viewer\\node_modules\\.cache\\vue-loader",
|
||||
cacheIdentifier: "39baf1b4",
|
||||
babelParserPlugins: ["jsx", "classProperties", "decorators-legacy"],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// test: /\.(js|jsx|ts|tsx)$/,
|
||||
// // exclude: /(node_modules|bower_components)/,
|
||||
// exclude: file => (
|
||||
// /node_modules/.test(file) &&
|
||||
// !/\.vue\.js/.test(file)
|
||||
// ),
|
||||
// exclude: /node_modules/,
|
||||
// use: {
|
||||
// loader: "babel-loader",
|
||||
// options: {
|
||||
// presets: [
|
||||
// ["@babel/preset-env", {}],
|
||||
// "babel-preset-typescript-vue3", //because of new vue setup method
|
||||
// // "@babel/preset-typescript"
|
||||
// ],
|
||||
// plugins: [
|
||||
// // "@babel/plugin-transform-runtime",
|
||||
// ["@babel/plugin-proposal-decorators", { legacy: true }],
|
||||
|
||||
// "@babel/proposal-class-properties",
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: "vue/dist/vue.runtime.esm-bundler.js",
|
||||
},
|
||||
extensions: [".tsx", ".ts", ".mjs", ".js", ".jsx", ".vue", ".json", ".wasm"],
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
__VUE_OPTIONS_API__: "true",
|
||||
__VUE_PROD_DEVTOOLS__: "false",
|
||||
__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),
|
||||
}),
|
||||
// new NodePolyfillPlugin(),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* eslint @typescript-eslint/no-var-requires: "off" */
|
||||
const webpack = require("webpack");
|
||||
// const { defineConfig } = require("@vue/cli-service");
|
||||
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
|
||||
|
||||
module.exports = {
|
||||
publicPath: "/",
|
||||
// chainWebpack: config => {
|
||||
// config
|
||||
// .plugin('define')
|
||||
// .tap(args => {
|
||||
// args[0] = {
|
||||
// ...args[0],
|
||||
// VUE_APP_PORTAL: JSON.stringify(process.env.PORTAL),
|
||||
// // other stuff
|
||||
// }
|
||||
// return args
|
||||
// })
|
||||
// },
|
||||
pages: {
|
||||
index: {
|
||||
// entry for the page
|
||||
entry: "src/main.ts",
|
||||
title: "TETHYS - Research Data Repository",
|
||||
},
|
||||
},
|
||||
// devServer: {
|
||||
// disableHostCheck: true,
|
||||
// },
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
VUE_APP_PORTAL: JSON.stringify(process.env.VUE_APP_PORTAL),
|
||||
SOLR_HOST: JSON.stringify(process.env.SOLR_HOST),
|
||||
SOLR_CORE: JSON.stringify(process.env.SOLR_CORE),
|
||||
}),
|
||||
new NodePolyfillPlugin(),
|
||||
],
|
||||
},
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue