tethys.frontend/src/components/datacite/BaseWidget.ts
Arno Kaimbacher c6469b00b4 - added src/compoenents/Pagination.vue
- npm updates
- added "type": "module" inside package.json
- renamed .eslintrc.js, postcss.config.js and vue.config.js
- adapted search-view-component
2024-03-19 16:43:25 +01:00

144 lines
3.9 KiB
TypeScript

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;
});
}
}