forked from pkp/ui-library
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pkp/pkp-lib#9771 Move ORCID functionality into core application
- Loading branch information
Showing
10 changed files
with
367 additions
and
6 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
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,15 @@ | ||
import {Primary, Controls, Meta, Stories} from '@storybook/blocks'; | ||
|
||
import * as FieldOrcidStories from './FieldOrcid.stories.js'; | ||
|
||
<Meta of={FieldOrcidStories} />{' '} | ||
|
||
# FieldOrcid | ||
|
||
## Usage | ||
|
||
Field used for managing a linked user/author's ORCID | ||
|
||
<Primary /> | ||
<Controls /> | ||
<Stories /> |
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,65 @@ | ||
import FieldOrcid from '@/components/Form/fields/FieldOrcid.vue'; | ||
import FieldBaseMock from '../mocks/field-base'; | ||
import FieldOrcidMock from '../mocks/field-orcid'; | ||
import {http, HttpResponse} from 'msw'; | ||
|
||
export default { | ||
title: 'Forms/FieldOrcid', | ||
component: FieldOrcid, | ||
render: (args) => ({ | ||
components: {FieldOrcid}, | ||
setup() { | ||
function change(name, prop, newValue, localeKey) { | ||
if (localeKey) { | ||
args[prop][localeKey] = newValue; | ||
} else { | ||
args[prop] = newValue; | ||
} | ||
} | ||
|
||
return {args, change}; | ||
}, | ||
template: ` | ||
<FieldOrcid v-bind="args" @change="change" /> | ||
`, | ||
}), | ||
parameters: { | ||
msw: { | ||
handlers: [ | ||
http.post( | ||
'https://mock/index.php/publicknowledge/api/v1/orcid/requestAuthorVerification/1', | ||
async () => { | ||
return HttpResponse.json(); | ||
}, | ||
), | ||
http.post( | ||
'https://mock/index.php/publicknowledge/api/v1/orcid/deleteForAuthor/1', | ||
async () => { | ||
return HttpResponse.json(); | ||
}, | ||
), | ||
], | ||
}, | ||
}, | ||
}; | ||
|
||
export const Base = { | ||
args: {...FieldBaseMock, ...FieldOrcidMock}, | ||
}; | ||
|
||
export const WithOrcid = { | ||
args: { | ||
...FieldBaseMock, | ||
...FieldOrcidMock, | ||
orcid: 'https://sandbox.orcid.org/0009-0009-3222-5777', | ||
isVerified: true, | ||
}, | ||
}; | ||
|
||
export const WithUnverifiedOrcid = { | ||
args: { | ||
...FieldBaseMock, | ||
...FieldOrcidMock, | ||
orcid: 'https://sandbox.orcid.org/0009-0009-3222-5777', | ||
}, | ||
}; |
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,251 @@ | ||
<template> | ||
<div class="pkpFormField pkpFormField--html"> | ||
<div class="pkpFormField__heading"> | ||
<span class="pkpFormFieldLabel"> | ||
{{ label }} | ||
</span> | ||
<tooltip v-if="tooltip" aria-hidden="true" :tooltip="tooltip" label="" /> | ||
<span v-if="tooltip" class="-screenReader" v-html="tooltip" /> | ||
<help-button | ||
v-if="helpTopic" | ||
:topic="helpTopic" | ||
:section="helpSection" | ||
:label="t('help.help')" | ||
/> | ||
</div> | ||
<div | ||
v-if="!isVerified && hasOrcid" | ||
class="pkpFormField__description" | ||
v-html="t('orcid.field.unverified.shouldRequest')" | ||
/> | ||
<div> | ||
<!-- When ORCID is present --> | ||
<Icon | ||
v-if="isVerified && hasOrcid" | ||
:class="'mr-2'" | ||
:icon="'orcid'" | ||
:inline="true" | ||
/> | ||
<div | ||
v-if="hasOrcid" | ||
class="pkpFormField__control pkpFormField__control--html" | ||
v-html="orcidDisplayValue" | ||
/> | ||
<pkp-button | ||
v-if="hasOrcid" | ||
class="pkpFormField__control--html__button" | ||
:is-warnable="true" | ||
:is-disabled="isButtonDisabled" | ||
@click="openDeleteDialog" | ||
> | ||
{{ t('common.delete') }} | ||
</pkp-button> | ||
<!-- When ORCID is absent --> | ||
<pkp-button | ||
v-if="!hasOrcid" | ||
:disabled="verificationRequested || isButtonDisabled" | ||
:icon="verificationRequested ? 'Complete' : null" | ||
@click="openSendAuthorEmailDialog" | ||
> | ||
{{ | ||
verificationRequested | ||
? t('orcid.field.verification.requested') | ||
: t('orcid.field.verification.request') | ||
}} | ||
</pkp-button> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import FieldBase from '@/components/Form/fields/FieldBase.vue'; | ||
import {useApiUrl} from '@/composables/useApiUrl'; | ||
import {useFetch} from '@/composables/useFetch'; | ||
import {useModal} from '@/composables/useModal'; | ||
export default { | ||
name: 'FieldOrcid', | ||
extends: FieldBase, | ||
props: { | ||
/** ORCID URL that has been verified */ | ||
orcid: { | ||
type: String, | ||
required: true, | ||
default: '', | ||
}, | ||
/** Author ID used in ORCID related actions */ | ||
authorId: { | ||
type: Number, | ||
required: true, | ||
default: 0, | ||
}, | ||
/** Whether ORCID ID has been verified and authenticated by the owner */ | ||
isVerified: { | ||
type: Boolean, | ||
required: true, | ||
default: false, | ||
}, | ||
}, | ||
data() { | ||
return { | ||
/** Internal value used for displaying ORCID in component. Takes initial value from `orcid` prop */ | ||
orcidValue: '', | ||
/** Whether an email requesting users verify their ORCID has been sent or not */ | ||
verificationRequested: false, | ||
/** Whether request verification/delete ORCID button should be disabled or not */ | ||
isButtonDisabled: false, | ||
}; | ||
}, | ||
computed: { | ||
/** | ||
* Helper to see if an ORCID value is present | ||
* @returns {boolean} | ||
*/ | ||
hasOrcid: function () { | ||
return this.orcidValue.length !== 0; | ||
}, | ||
/** | ||
* Wraps ORCID in <a> tag for HTML display | ||
* @returns {string} | ||
*/ | ||
orcidDisplayValue: function () { | ||
if (this.hasOrcid) { | ||
return `<a target="_blank" class="underline" href="${this.orcidValue}">${this.orcidValue}</a>`; | ||
} else { | ||
return this.orcidValue; | ||
} | ||
}, | ||
}, | ||
created() { | ||
this.orcidValue = this.orcid; | ||
}, | ||
methods: { | ||
/** | ||
* Triggers author email request via API | ||
* | ||
* @returns {Promise<void>} | ||
*/ | ||
sendAuthorEmail: async function () { | ||
this.isButtonDisabled = true; | ||
const {apiUrl} = useApiUrl( | ||
`orcid/requestAuthorVerification/${this.authorId}`, | ||
); | ||
const {isSuccess, fetch} = useFetch(apiUrl, { | ||
method: 'POST', | ||
expectValidationError: true, | ||
}); | ||
await fetch(); | ||
if (isSuccess) { | ||
this.verificationRequested = true; | ||
} | ||
this.isButtonDisabled = false; | ||
}, | ||
/** | ||
* Open confirmation dialog for requesting author ORCID verification | ||
*/ | ||
openSendAuthorEmailDialog: function () { | ||
const {openDialog} = useModal(); | ||
openDialog({ | ||
name: 'sendAuthorEmail', | ||
title: this.t('orcid.field.authorEmailModal.title'), | ||
message: this.t('orcid.field.authorEmailModal.message'), | ||
actions: [ | ||
{ | ||
label: this.t('common.yes'), | ||
isPrimary: true, | ||
callback: async (close) => { | ||
await this.sendAuthorEmail(); | ||
close(); | ||
}, | ||
}, | ||
{ | ||
label: this.t('common.no'), | ||
isWarnable: true, | ||
callback: (close) => { | ||
close(); | ||
}, | ||
}, | ||
], | ||
close: () => {}, | ||
}); | ||
}, | ||
/** | ||
* Trigger API request to remove ORCID and access tokens from author/user | ||
* | ||
* @returns {Promise<void>} | ||
*/ | ||
deleteOrcid: async function () { | ||
this.isButtonDisabled = true; | ||
const {apiUrl} = useApiUrl(`orcid/deleteForAuthor/${this.authorId}`); | ||
const {isSuccess, fetch} = useFetch(apiUrl, { | ||
method: 'POST', | ||
expectValidationError: true, | ||
}); | ||
await fetch(); | ||
if (isSuccess) { | ||
this.orcidValue = ''; | ||
} | ||
this.isButtonDisabled = false; | ||
}, | ||
/** | ||
* Opens dialog to confirm deletion of ORCID from author/user | ||
*/ | ||
openDeleteDialog: function () { | ||
const {openDialog} = useModal(); | ||
openDialog({ | ||
name: 'deleteOrcid', | ||
title: this.t('orcid.field.deleteOrcidModal.title'), | ||
message: this.t('orcid.field.deleteOrcidModal.message'), | ||
actions: [ | ||
{ | ||
label: this.t('common.yes'), | ||
isPrimary: true, | ||
callback: async (close) => { | ||
await this.deleteOrcid(); | ||
close(); | ||
}, | ||
}, | ||
{ | ||
label: this.t('common.no'), | ||
isWarnable: true, | ||
callback: (close) => { | ||
close(); | ||
}, | ||
}, | ||
], | ||
close: () => {}, | ||
}); | ||
}, | ||
}, | ||
}; | ||
</script> | ||
|
||
<style lang="less"> | ||
@import '../../../styles/_import'; | ||
.pkpFormField__control--html { | ||
font-size: @font-sml; | ||
line-height: 1.8em; | ||
display: inline-block; | ||
p:first-child { | ||
margin-top: 0; | ||
} | ||
p:last-child { | ||
margin-bottom: 0; | ||
} | ||
} | ||
.pkpFormField__control--html__button { | ||
margin-inline-start: 0.25rem; | ||
} | ||
</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,9 @@ | ||
export default { | ||
name: 'orcid', | ||
component: 'field-orcid', | ||
label: 'ORCID', | ||
orcid: '', | ||
authorId: 1, | ||
tooltip: | ||
'ORCID is an independent non-profit organization that provides a persistent identifier – an ORCID iD – that distinguishes you from other researchers and a mechanism for linking your research outputs and activities to your iD. ORCID is integrated into many systems used by publishers, funders, institutions, and other research-related services. Learn more at https://orcid.org.', | ||
}; |
Oops, something went wrong.