mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #17483 from itisAliRH/citation-refactor
Citation refactors
This commit is contained in:
@@ -1,55 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { computed } from "vue";
|
||||
|
||||
import { Citation } from ".";
|
||||
|
||||
library.add(faExternalLinkAlt);
|
||||
|
||||
interface Props {
|
||||
citation: Citation;
|
||||
outputFormat?: string;
|
||||
prefix?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
outputFormat: "bibliography",
|
||||
prefix: "",
|
||||
});
|
||||
|
||||
const link = computed(() => {
|
||||
const citeUrl = props.citation.cite?.data?.[0]?.URL;
|
||||
return citeUrl ? decodeURIComponent(citeUrl) : null;
|
||||
});
|
||||
const citationHtml = computed(() => {
|
||||
const citation = props.citation;
|
||||
const cite = citation.cite;
|
||||
const formattedCitation = cite.format(props.outputFormat, {
|
||||
format: "html",
|
||||
template: "apa",
|
||||
lang: "en-US",
|
||||
});
|
||||
return formattedCitation;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
{{ prefix }}
|
||||
<span v-html="citationHtml" />
|
||||
<a v-if="link" :href="link" target="_blank">Visit Citation <FontAwesomeIcon icon="external-link-alt" /> </a>
|
||||
|
||||
<a v-if="link" :href="link" target="_blank">
|
||||
Visit Citation
|
||||
<FontAwesomeIcon :icon="faExternalLinkAlt" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
|
||||
library.add(faExternalLinkAlt);
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FontAwesomeIcon,
|
||||
},
|
||||
props: {
|
||||
citation: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
outputFormat: {
|
||||
type: String,
|
||||
default: "bibliography",
|
||||
},
|
||||
prefix: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
link() {
|
||||
const citeUrl = this.citation.cite?.data?.[0]?.URL;
|
||||
return citeUrl ? decodeURIComponent(citeUrl) : null;
|
||||
},
|
||||
citationHtml() {
|
||||
const citation = this.citation;
|
||||
const cite = citation.cite;
|
||||
const formattedCitation = cite.format(this.outputFormat, {
|
||||
format: "html",
|
||||
template: "apa",
|
||||
lang: "en-US",
|
||||
});
|
||||
return formattedCitation;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.csl-bib-body {
|
||||
display: inline;
|
||||
|
||||
@@ -1,23 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
import { BButton, BCard, BCollapse, BNav, BNavItem } from "bootstrap-vue";
|
||||
import { onMounted, onUpdated, ref } from "vue";
|
||||
|
||||
import { getCitations } from "@/components/Citation/services";
|
||||
import { useConfig } from "@/composables/config";
|
||||
|
||||
import { type Citation } from ".";
|
||||
|
||||
import CitationItem from "@/components/Citation/CitationItem.vue";
|
||||
|
||||
const outputFormats = Object.freeze({
|
||||
CITATION: "bibliography",
|
||||
BIBTEX: "bibtex",
|
||||
RAW: "raw",
|
||||
});
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
source: string;
|
||||
simple: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
simple: false,
|
||||
});
|
||||
|
||||
const { config } = useConfig(true);
|
||||
|
||||
const emit = defineEmits(["rendered", "show", "shown", "hide", "hidden"]);
|
||||
|
||||
const outputFormat = ref(outputFormats.CITATION);
|
||||
const citations = ref<Citation[]>([]);
|
||||
|
||||
onUpdated(() => {
|
||||
emit("rendered");
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
citations.value = await getCitations(props.source, props.id);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<b-card v-if="!simple" class="citation-card" header-tag="nav">
|
||||
<BCard v-if="!simple" class="citation-card" header-tag="nav">
|
||||
<template v-slot:header>
|
||||
<b-nav card-header tabs>
|
||||
<b-nav-item
|
||||
<BNav card-header tabs>
|
||||
<BNavItem
|
||||
:active="outputFormat === outputFormats.CITATION"
|
||||
@click="outputFormat = outputFormats.CITATION"
|
||||
>Citations (APA)</b-nav-item
|
||||
>
|
||||
<b-nav-item
|
||||
@click="outputFormat = outputFormats.CITATION">
|
||||
Citations (APA)
|
||||
</BNavItem>
|
||||
|
||||
<BNavItem
|
||||
:active="outputFormat === outputFormats.BIBTEX"
|
||||
@click="outputFormat = outputFormats.BIBTEX"
|
||||
>BibTeX</b-nav-item
|
||||
>
|
||||
</b-nav>
|
||||
@click="outputFormat = outputFormats.BIBTEX">
|
||||
BibTeX
|
||||
</BNavItem>
|
||||
</BNav>
|
||||
</template>
|
||||
|
||||
<div v-if="source === 'histories'" class="infomessage">
|
||||
<div v-html="config.citations_export_message_html"></div>
|
||||
</div>
|
||||
|
||||
<div class="citations-formatted">
|
||||
<CitationItem
|
||||
v-for="(citation, index) in citations"
|
||||
@@ -26,94 +76,31 @@
|
||||
:citation="citation"
|
||||
:output-format="outputFormat" />
|
||||
</div>
|
||||
</b-card>
|
||||
</BCard>
|
||||
<div v-else-if="citations.length">
|
||||
<b-btn v-b-toggle="id" variant="primary">Citations</b-btn>
|
||||
<b-collapse
|
||||
<BButton v-b-toggle="id" variant="primary">Citations</BButton>
|
||||
|
||||
<BCollapse
|
||||
:id="id.replace(/ /g, '_')"
|
||||
class="mt-2"
|
||||
@show="$emit('show')"
|
||||
@shown="$emit('shown')"
|
||||
@hide="$emit('hide')"
|
||||
@hidden="$emit('hidden')">
|
||||
<b-card>
|
||||
<BCard>
|
||||
<CitationItem
|
||||
v-for="(citation, index) in citations"
|
||||
:key="index"
|
||||
class="formatted-reference"
|
||||
:citation="citation"
|
||||
:output-format="outputFormat" />
|
||||
</b-card>
|
||||
</b-collapse>
|
||||
</BCard>
|
||||
</BCollapse>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import BootstrapVue from "bootstrap-vue";
|
||||
import Vue from "vue";
|
||||
|
||||
import { useConfig } from "@/composables/config";
|
||||
|
||||
import CitationItem from "./CitationItem";
|
||||
import { getCitations } from "./services";
|
||||
|
||||
Vue.use(BootstrapVue);
|
||||
|
||||
const outputFormats = Object.freeze({
|
||||
CITATION: "bibliography",
|
||||
BIBTEX: "bibtex",
|
||||
RAW: "raw",
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CitationItem,
|
||||
},
|
||||
props: {
|
||||
source: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
simple: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { config } = useConfig(true);
|
||||
return { config };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
citations: [],
|
||||
errors: [],
|
||||
showCollapse: false,
|
||||
outputFormats,
|
||||
outputFormat: outputFormats.CITATION,
|
||||
};
|
||||
},
|
||||
updated() {
|
||||
this.$nextTick(() => {
|
||||
this.$emit("rendered");
|
||||
});
|
||||
},
|
||||
created() {
|
||||
getCitations(this.source, this.id)
|
||||
.then((citations) => {
|
||||
this.citations = citations;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
<style scoped lang="scss">
|
||||
.citation-card .card-header .nav-tabs {
|
||||
margin-bottom: -0.75rem !important;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface Citation {
|
||||
raw: string;
|
||||
cite: {
|
||||
data: {
|
||||
URL: string;
|
||||
}[];
|
||||
format: (
|
||||
format: string,
|
||||
options: {
|
||||
format: string;
|
||||
template: string;
|
||||
lang: string;
|
||||
}
|
||||
) => string;
|
||||
};
|
||||
}
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
import axios from "axios";
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
|
||||
import { getCitations } from "./services.js";
|
||||
import { getCitations } from "./services";
|
||||
|
||||
const mockCitationResponseJson = [
|
||||
{
|
||||
@@ -14,7 +14,7 @@ const mockCitationResponseJson = [
|
||||
];
|
||||
|
||||
describe("Citation", () => {
|
||||
let axiosMock;
|
||||
let axiosMock: MockAdapter;
|
||||
|
||||
beforeEach(() => {
|
||||
axiosMock = new MockAdapter(axios);
|
||||
@@ -28,7 +28,7 @@ describe("Citation", () => {
|
||||
it("Should fetch and create a citation object", async () => {
|
||||
axiosMock.onGet(`/api/tools/random_lines1/citations`).reply(200, mockCitationResponseJson);
|
||||
const citations = await getCitations("tools", "random_lines1");
|
||||
const formattedCitation = citations[0].cite.format("bibliography", {
|
||||
const formattedCitation = citations?.[0]?.cite.format("bibliography", {
|
||||
format: "html",
|
||||
template: "apa",
|
||||
lang: "en-US",
|
||||
+7
-4
@@ -1,13 +1,16 @@
|
||||
import axios from "axios";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import { rethrowSimple } from "utils/simple-error";
|
||||
|
||||
export async function getCitations(source, id) {
|
||||
import { getAppRoot } from "@/onload/loadConfig";
|
||||
import { rethrowSimple } from "@/utils/simple-error";
|
||||
|
||||
import { type Citation } from ".";
|
||||
|
||||
export async function getCitations(source: string, id: string): Promise<Citation[]> {
|
||||
try {
|
||||
const request = await axios.get(`${getAppRoot()}api/${source}/${id}/citations`);
|
||||
const rawCitations = request.data;
|
||||
const citations = [];
|
||||
const { Cite } = await import(/* webpackChunkName: "cite" */ "./cite.js");
|
||||
const { Cite } = await import(/* webpackChunkName: "cite" */ "./cite");
|
||||
for (const rawCitation of rawCitations) {
|
||||
try {
|
||||
const cite = new Cite(rawCitation.content);
|
||||
Reference in New Issue
Block a user