-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18134 from davelopez/display_doi
Display DOIs in Archived Histories
- Loading branch information
Showing
17 changed files
with
349 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<script setup lang="ts"> | ||
import { library } from "@fortawesome/fontawesome-svg-core"; | ||
import { faLink } from "@fortawesome/free-solid-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; | ||
import { BBadge } from "bootstrap-vue"; | ||
import { computed } from "vue"; | ||
library.add(faLink); | ||
interface Props { | ||
doi: string; | ||
} | ||
const props = defineProps<Props>(); | ||
const doiLink = computed(() => `https://doi.org/${props.doi}`); | ||
</script> | ||
|
||
<template> | ||
<BBadge class="doi-badge"> | ||
<FontAwesomeIcon :icon="faLink" /> | ||
<a :href="doiLink" target="_blank" rel="noopener noreferrer">{{ props.doi }}</a> | ||
</BBadge> | ||
</template> | ||
|
||
<style scoped> | ||
.doi-badge { | ||
font-size: 1rem; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<script setup lang="ts"> | ||
import axios from "axios"; | ||
import { ref, watch } from "vue"; | ||
import { BrowsableFilesSourcePlugin } from "@/api/remoteFiles"; | ||
import { useFileSources } from "@/composables/fileSources"; | ||
import DOILink from "./DOILink.vue"; | ||
const { getFileSourceByUri, isLoading: isLoadingFileSources } = useFileSources({ include: ["rdm"] }); | ||
interface Props { | ||
exportRecordUri?: string; | ||
rdmFileSources?: BrowsableFilesSourcePlugin[]; | ||
} | ||
const props = defineProps<Props>(); | ||
const doi = ref<string | undefined>(undefined); | ||
// File sources need to be loaded before we can get the DOI | ||
watch(isLoadingFileSources, async (isLoading) => { | ||
if (!isLoading) { | ||
doi.value = await getDOIFromExportRecordUri(props.exportRecordUri); | ||
} | ||
}); | ||
/** | ||
* Gets the DOI from an export record URI. | ||
* The URI should be in the format: `<scheme>://<source-id>/<record-id>/<file-name>`. | ||
* @param uri The target URI of the export record to get the DOI from. | ||
* @returns The DOI or undefined if it could not be retrieved. | ||
*/ | ||
async function getDOIFromExportRecordUri(uri?: string) { | ||
if (!uri) { | ||
return undefined; | ||
} | ||
const fileSource = getFileSourceByUri(uri); | ||
if (!fileSource) { | ||
console.debug("No file source found for URI: ", uri); | ||
return undefined; | ||
} | ||
const repositoryUrl = fileSource.url; | ||
if (!repositoryUrl) { | ||
console.debug("Invalid repository URL for file source: ", fileSource); | ||
return undefined; | ||
} | ||
const recordId = getRecordIdFromUri(uri); | ||
if (!recordId) { | ||
console.debug("No record ID found for URI: ", uri); | ||
return undefined; | ||
} | ||
const recordUrl = `${repositoryUrl}/api/records/${recordId}`; | ||
return getDOIFromInvenioRecordUrl(recordUrl); | ||
} | ||
/** | ||
* Extracts the record ID from a URI. | ||
* The URI should be in the format: `<scheme>://<source-id>/<record-id>/<file-name>`. | ||
* @param targetUri The URI to extract the record ID from. | ||
* @returns The record ID or undefined if it could not be extracted. | ||
*/ | ||
function getRecordIdFromUri(targetUri?: string): string | undefined { | ||
if (!targetUri) { | ||
return undefined; | ||
} | ||
return targetUri.split("//")[1]?.split("/")[1]; | ||
} | ||
/** | ||
* Gets the DOI from an Invenio record URL. | ||
* @param recordUrl The URL of the record to get the DOI from. | ||
* @returns The DOI or undefined if it could not be retrieved. | ||
*/ | ||
async function getDOIFromInvenioRecordUrl(recordUrl?: string): Promise<string | undefined> { | ||
if (!recordUrl) { | ||
return undefined; | ||
} | ||
try { | ||
const response = await axios.get(recordUrl); | ||
if (response.status !== 200) { | ||
console.debug("Failed to get record from URL: ", recordUrl); | ||
return undefined; | ||
} | ||
const record = response.data; | ||
if (!record?.doi) { | ||
console.debug("No DOI found in record: ", record); | ||
return undefined; | ||
} | ||
return record.doi; | ||
} catch (error) { | ||
console.warn("Failed to get record from URL: ", recordUrl, error); | ||
return undefined; | ||
} | ||
} | ||
</script> | ||
|
||
<template> | ||
<DOILink v-if="doi" :doi="doi" /> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
client/src/components/History/Archiving/ArchivedHistoryCard.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
<script setup lang="ts"> | ||
import { library } from "@fortawesome/fontawesome-svg-core"; | ||
import { faCopy, faEye, faUndo } from "@fortawesome/free-solid-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; | ||
import { BBadge, BButton, BButtonGroup } from "bootstrap-vue"; | ||
import { computed } from "vue"; | ||
import { ArchivedHistorySummary } from "@/api/histories.archived"; | ||
import localize from "@/utils/localization"; | ||
import ExportRecordDOILink from "@/components/Common/ExportRecordDOILink.vue"; | ||
import Heading from "@/components/Common/Heading.vue"; | ||
import StatelessTags from "@/components/TagsMultiselect/StatelessTags.vue"; | ||
import UtcDate from "@/components/UtcDate.vue"; | ||
interface Props { | ||
history: ArchivedHistorySummary; | ||
} | ||
const props = defineProps<Props>(); | ||
const canImportCopy = computed(() => props.history.export_record_data?.target_uri !== undefined); | ||
const emit = defineEmits<{ | ||
(e: "onView", history: ArchivedHistorySummary): void; | ||
(e: "onRestore", history: ArchivedHistorySummary): void; | ||
(e: "onImportCopy", history: ArchivedHistorySummary): void; | ||
}>(); | ||
library.add(faUndo, faCopy, faEye); | ||
function onViewHistoryInCenterPanel() { | ||
emit("onView", props.history); | ||
} | ||
async function onRestoreHistory() { | ||
emit("onRestore", props.history); | ||
} | ||
async function onImportCopy() { | ||
emit("onImportCopy", props.history); | ||
} | ||
</script> | ||
|
||
<template> | ||
<div class="archived-history-card"> | ||
<div class="d-flex justify-content-between align-items-center"> | ||
<Heading h3 inline bold size="sm"> | ||
{{ history.name }} <ExportRecordDOILink :export-record-uri="history.export_record_data?.target_uri" /> | ||
</Heading> | ||
|
||
<div class="d-flex align-items-center flex-gapx-1 badges"> | ||
<BBadge v-if="history.published" v-b-tooltip pill :title="localize('This history is public.')"> | ||
{{ localize("Published") }} | ||
</BBadge> | ||
<BBadge v-if="!history.purged" v-b-tooltip pill :title="localize('Amount of items in history')"> | ||
{{ history.count }} {{ localize("items") }} | ||
</BBadge> | ||
<BBadge | ||
v-if="history.export_record_data" | ||
v-b-tooltip | ||
pill | ||
:title=" | ||
localize( | ||
'This history has an associated export record containing a snapshot of the history that can be used to import a copy of the history.' | ||
) | ||
"> | ||
{{ localize("Snapshot available") }} | ||
</BBadge> | ||
<BBadge v-b-tooltip pill :title="localize('Last edited/archived')"> | ||
<UtcDate :date="history.update_time" mode="elapsed" /> | ||
</BBadge> | ||
</div> | ||
</div> | ||
|
||
<div class="d-flex justify-content-start align-items-center mt-1"> | ||
<BButtonGroup class="actions"> | ||
<BButton | ||
v-b-tooltip | ||
:title="localize('View this history')" | ||
variant="link" | ||
class="p-0 px-1" | ||
@click.stop="onViewHistoryInCenterPanel"> | ||
<FontAwesomeIcon :icon="faEye" size="lg" /> | ||
View | ||
</BButton> | ||
<BButton | ||
v-b-tooltip | ||
:title="localize('Unarchive this history and move it back to your active histories')" | ||
variant="link" | ||
class="p-0 px-1" | ||
@click.stop="onRestoreHistory"> | ||
<FontAwesomeIcon :icon="faUndo" size="lg" /> | ||
Unarchive | ||
</BButton> | ||
|
||
<BButton | ||
v-if="canImportCopy" | ||
v-b-tooltip | ||
:title="localize('Import a new copy of this history from the associated export record')" | ||
variant="link" | ||
class="p-0 px-1" | ||
@click.stop="onImportCopy"> | ||
<FontAwesomeIcon :icon="faCopy" size="lg" /> | ||
Import Copy | ||
</BButton> | ||
</BButtonGroup> | ||
</div> | ||
|
||
<p v-if="history.annotation" class="my-1">{{ history.annotation }}</p> | ||
|
||
<StatelessTags class="my-1" :value="history.tags" :disabled="true" :max-visible-tags="10" /> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.badges { | ||
font-size: 1rem; | ||
} | ||
</style> |
Oops, something went wrong.