- npm updates - added "type": "module" inside package.json - renamed .eslintrc.js, postcss.config.js and vue.config.js - adapted search-view-component
144 lines
3.9 KiB
TypeScript
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;
|
|
});
|
|
}
|
|
}
|