Skip to content

Commit 62bcd47

Browse files
committed
structured citations (development)
1 parent ee1bbc0 commit 62bcd47

21 files changed

+741
-3
lines changed

src/components/Form/FormGroup.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import FieldAffiliations from './fields/FieldAffiliations.vue';
5959
import FieldArchivingPn from './fields/FieldArchivingPn.vue';
6060
import FieldAutosuggestPreset from './fields/FieldAutosuggestPreset.vue';
6161
import FieldBaseAutosuggest from './fields/FieldBaseAutosuggest.vue';
62+
import FieldAuthors from './fields/FieldAuthors.vue';
6263
import FieldColor from './fields/FieldColor.vue';
6364
import FieldControlledVocab from './fields/FieldControlledVocab.vue';
6465
import FieldPubId from './fields/FieldPubId.vue';
@@ -91,6 +92,7 @@ export default {
9192
FieldArchivingPn,
9293
FieldAutosuggestPreset,
9394
FieldBaseAutosuggest,
95+
FieldAuthors,
9496
FieldColor,
9597
FieldControlledVocab,
9698
FieldPubId,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks';
2+
3+
import * as FieldAuthorsStories from './FieldAuthors.stories.js';
4+
5+
<Meta of={FieldAuthorsStories} />
6+
7+
# FieldAuthors
8+
9+
## Usage
10+
11+
A special component to maintain authors of a citation of publications.
12+
13+
The `value` is an array of Author objects `{ displayName, givenName, familyName, orcid, wikidata, openAlex }`.
14+
15+
<Primary />
16+
<Controls />
17+
<Stories />
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import FieldAuthors from './FieldAuthors.vue';
2+
import FieldAuthorsMock from '@/components/Form/mocks/field-citation-authors.js';
3+
4+
const args = {...FieldAuthorsMock};
5+
6+
export default {
7+
title: 'Forms/FieldAuthors',
8+
component: FieldAuthors,
9+
args: {},
10+
parameters: {},
11+
render: (args) => ({
12+
components: {FieldAuthors},
13+
setup() {
14+
return {args};
15+
},
16+
template: `
17+
<FieldAuthors v-bind="args"/>`,
18+
}),
19+
decorators: [
20+
() => ({
21+
template: '<div style="height: 600px"><story/></div>',
22+
}),
23+
],
24+
};
25+
26+
export const Base = {
27+
args: {...FieldAuthorsMock},
28+
};
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<template>
2+
<div
3+
:id="`${props.formId}-${props.name}`"
4+
class="pkpFormField pkpFormField--citationAuthors"
5+
>
6+
<PkpTable aria-label="CitationAuthors">
7+
<TableHeader>
8+
<TableColumn id="">{{ t('user.givenName', []) }}</TableColumn>
9+
<TableColumn id="">{{ t('user.familyName', []) }}</TableColumn>
10+
<TableColumn id="">{{ t('user.orcid', []) }}</TableColumn>
11+
<TableColumn id="" class="w-[100px]">&nbsp;</TableColumn>
12+
</TableHeader>
13+
<TableBody>
14+
<TableRow
15+
v-for="(author, authorIndex) in currentValue"
16+
:key="authorIndex"
17+
>
18+
<TableCell>
19+
<FieldText :value="author.givenName" />
20+
</TableCell>
21+
<TableCell>
22+
<FieldText :value="author.givenName" />
23+
</TableCell>
24+
<TableCell>
25+
<FieldText v-if="!author.orcid" :value="author.orcid" />
26+
<a v-if="author.orcid" :href="author.orcid" target="_blank">
27+
<Icon
28+
icon="Orcid"
29+
:class="'relative top-[-2px] inline-block h-auto w-[16px] align-middle'"
30+
:inline="true"
31+
/>
32+
{{ author.orcid }}
33+
</a>
34+
</TableCell>
35+
<TableCell>
36+
<a
37+
class="pkpButton flex cursor-pointer items-center border-transparent py-2 text-lg-semibold text-primary hover:enabled:underline"
38+
@click="deleteAuthor(authorIndex)"
39+
>
40+
{{ t('common.delete', []) }}
41+
</a>
42+
</TableCell>
43+
</TableRow>
44+
<TableRow>
45+
<TableCell>
46+
<Button @click="addAuthor()">
47+
{{ t('common.add') }}
48+
</Button>
49+
</TableCell>
50+
<TableCell></TableCell>
51+
<TableCell></TableCell>
52+
<TableCell></TableCell>
53+
</TableRow>
54+
</TableBody>
55+
</PkpTable>
56+
</div>
57+
</template>
58+
59+
<script setup>
60+
import Button from '@/components/Button/Button.vue';
61+
import PkpTable from '@/components/Table/Table.vue';
62+
import TableCell from '@/components/Table/TableCell.vue';
63+
import TableRow from '@/components/Table/TableRow.vue';
64+
import TableColumn from '@/components/Table/TableColumn.vue';
65+
import TableHeader from '@/components/Table/TableHeader.vue';
66+
import TableBody from '@/components/Table/TableBody.vue';
67+
import {computed} from 'vue';
68+
import {t} from '@/utils/i18n';
69+
import FieldText from '@/components/Form/fields/FieldText.vue';
70+
import Icon from '@/components/Icon/Icon.vue';
71+
72+
const props = defineProps({
73+
/** Field key used for form submission */
74+
name: {
75+
type: String,
76+
default: null,
77+
},
78+
/** The ID of the form this field should appear in. This is passed down from the `Form`. */
79+
formId: {
80+
type: String,
81+
default: null,
82+
},
83+
/** The `<label>` for this field. May be used in a `<fieldset>` when appropriate. All form fields should have an accessible label. */
84+
label: {
85+
type: String,
86+
default: null,
87+
},
88+
/** Adds a description to the field. Can include HTML code. */
89+
description: {
90+
type: String,
91+
default: null,
92+
},
93+
/** Current value of the field */
94+
value: {
95+
type: Array,
96+
default: () => [],
97+
},
98+
/** Default locale of the form */
99+
primaryLocale: {
100+
type: String,
101+
default: 'en',
102+
},
103+
/** List of supported locales */
104+
locales: {
105+
type: Array,
106+
default: () => [],
107+
},
108+
/** Object containing all form errors */
109+
allErrors: {
110+
type: Object,
111+
default() {
112+
return {};
113+
},
114+
},
115+
});
116+
const authorDataModel = () => {
117+
return {
118+
displayName: '',
119+
givenName: '',
120+
familyName: '',
121+
orcid: '',
122+
};
123+
};
124+
const currentValue = computed({
125+
get: () => props.value,
126+
set: (newVal) => emit('change', props.name, 'value', newVal),
127+
});
128+
129+
function deleteAuthor(authorIndex) {
130+
currentValue.value.splice(authorIndex, 1);
131+
}
132+
133+
function addAuthor() {
134+
currentValue.value.push(authorDataModel());
135+
}
136+
</script>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
export default {
2+
name: 'author-citation-authors',
3+
component: 'author-citation-authors',
4+
primaryLocale: 'en',
5+
locales: [
6+
{key: 'en', label: 'English'},
7+
{key: 'fr_CA', label: 'French (Canada)'},
8+
{key: 'de', label: 'German'},
9+
],
10+
value: [
11+
{
12+
displayName: 'Christian Hauschke',
13+
givenName: 'Christian',
14+
familyName: 'Hauschke',
15+
orcid: 'https://orcid.org/0000-0003-2499-7741',
16+
wikidata: '',
17+
openAlex: 'https://openalex.org/A5021239193',
18+
},
19+
{
20+
displayName: 'Lambert Heller',
21+
givenName: 'Lambert',
22+
familyName: 'Heller',
23+
orcid: 'https://orcid.org/0000-0003-0232-7085',
24+
wikidata: '',
25+
openAlex: 'https://openalex.org/A5018666082',
26+
},
27+
{
28+
displayName: 'Bo‐Christer Björk',
29+
givenName: 'Bo-Christer',
30+
familyName: 'Björk',
31+
wikidata: '',
32+
openAlex: 'https://openalex.org/A5036789552',
33+
},
34+
{
35+
displayName: 'Cenyu Shen',
36+
givenName: 'Cenyu',
37+
familyName: 'Shen',
38+
orcid: 'https://orcid.org/0000-0002-4411-9674',
39+
wikidata: '',
40+
openAlex: 'https://openalex.org/A5080285387',
41+
},
42+
{
43+
displayName: 'Mikael Laakso',
44+
givenName: 'Mikael',
45+
familyName: 'Laakso',
46+
orcid: 'https://orcid.org/0000-0003-3951-7990',
47+
wikidata: '',
48+
openAlex: 'https://openalex.org/A5067698582',
49+
},
50+
],
51+
};

src/composables/useDataChanged.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// todo: gazi
12
import {onUnmounted} from 'vue';
23
import {injectFromCurrentInstance} from '@/utils/defineComponentStore';
34

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks';
2+
3+
import * as CitationManager from './CitationManager.stories.js';
4+
5+
<Meta of={CitationManager} />
6+
7+
# Citation manager
8+
9+
Listing of Citations.
10+
11+
## Props
12+
13+
<ArgTypes />
14+
15+
## Extension points for plugins
16+
17+
For more details and examples on how to use them, check out [Plugins guide](..?path=/docs/guide-plugins--docs)
18+
19+
The name of the Pinia store is `CitationManager`.
20+
21+
- `getTopItems`: Add/Change items in the top right, where the `Upload / Select` button is.
22+
- `getItemActions`: Add/Change the list of actions that are displayed after clicking the 3 dots button.
23+
- `getItemPrimaryActions`: Add/Change one individual Action which is displayed in the ACTIONS column.
24+
- `getCellStatusItems`: Add/Change what components are displayed in the Reviewer status.
25+
- `getColumns`: Add/Change the columns being displayed in the table.
26+
27+
<Primary />
28+
<Controls />
29+
<Stories />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import CitationManager from './CitationManager.vue';
2+
3+
export default {
4+
title: 'Managers/CitationManager',
5+
component: CitationManager,
6+
render: (args) => ({
7+
components: {CitationManager},
8+
setup() {
9+
return {args};
10+
},
11+
template: `<CitationManager v-bind="args"/>`,
12+
}),
13+
};
14+
15+
export const Base = {
16+
args: {},
17+
};

0 commit comments

Comments
 (0)