Skip to content

Commit

Permalink
Merge pull request #17483 from itisAliRH/citation-refactor
Browse files Browse the repository at this point in the history
Citation refactors
  • Loading branch information
martenson authored Feb 16, 2024
2 parents 74a1b02 + a16de7b commit cbdf64c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 133 deletions.
85 changes: 41 additions & 44 deletions client/src/components/Citation/CitationItem.vue
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
<template>
<div>
{{ prefix }}
<span v-html="citationHtml" />
<a v-if="link" :href="link" target="_blank">Visit Citation <FontAwesomeIcon icon="external-link-alt" /> </a>
</div>
</template>

<script>
<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);
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;
},
},
};
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="faExternalLinkAlt" />
</a>
</div>
</template>

<style>
.csl-bib-body {
display: inline;
Expand Down
151 changes: 69 additions & 82 deletions client/src/components/Citation/CitationsList.vue
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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;
}
Expand Down
16 changes: 16 additions & 0 deletions client/src/components/Citation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface Citation {
raw: string;
cite: {
data: {
URL: string;
}[];
format: (
format: string,
options: {
format: string;
template: string;
lang: string;
}
) => string;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
{
Expand All @@ -14,7 +14,7 @@ const mockCitationResponseJson = [
];

describe("Citation", () => {
let axiosMock;
let axiosMock: MockAdapter;

beforeEach(() => {
axiosMock = new MockAdapter(axios);
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
Expand Down

0 comments on commit cbdf64c

Please sign in to comment.