Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/Form/FormGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import FieldAffiliations from './fields/FieldAffiliations.vue';
import FieldArchivingPn from './fields/FieldArchivingPn.vue';
import FieldAutosuggestPreset from './fields/FieldAutosuggestPreset.vue';
import FieldBaseAutosuggest from './fields/FieldBaseAutosuggest.vue';
import FieldAuthors from './fields/FieldAuthors.vue';
import FieldColor from './fields/FieldColor.vue';
import FieldControlledVocab from './fields/FieldControlledVocab.vue';
import FieldPubId from './fields/FieldPubId.vue';
Expand Down Expand Up @@ -91,6 +92,7 @@ export default {
FieldArchivingPn,
FieldAutosuggestPreset,
FieldBaseAutosuggest,
FieldAuthors,
FieldColor,
FieldControlledVocab,
FieldPubId,
Expand Down
23 changes: 23 additions & 0 deletions src/components/Form/fields/FieldAuthors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
Primary,
Controls,
Stories,
Meta,
ArgTypes,
} from '@storybook/addon-docs/blocks';

import * as FieldAuthorsStories from './FieldAuthors.stories.js';

<Meta of={FieldAuthorsStories}/>

# FieldAuthors

## Usage

A special component to maintain authors of a citation of publications.

The `value` is an array of objects `{ givenName, familyName, orcid }`.

<Primary/>
<Controls/>
<Stories/>
36 changes: 36 additions & 0 deletions src/components/Form/fields/FieldAuthors.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import FieldAuthors from './FieldAuthors.vue';
import FieldAuthorsMock from '@/components/Form/mocks/field-authors.js';

const args = {...FieldAuthorsMock};

export default {
title: 'Forms/FieldAuthors',
component: FieldAuthors,
args: {},
parameters: {},
render: (args) => ({
components: {FieldAuthors},
setup() {
function change(name, prop, newValue, localeKey) {
if (localeKey) {
args[prop][localeKey] = newValue;
} else {
args[prop] = newValue;
}
}

return {args, change};
},
template: `
<FieldAuthors v-bind="args" @change="change" />`,
}),
decorators: [
() => ({
template: '<div style="height: 600px"><story/></div>',
}),
],
};

export const Base = {
args: {...FieldAuthorsMock},
};
167 changes: 167 additions & 0 deletions src/components/Form/fields/FieldAuthors.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<template>
<div
:id="`${props.formId}-${props.name}`"
class="pkpFormField pkpFormField--authors"
>
<div class="pkpFormField__heading">
<label :id="labelId" class="pkpFormFieldLabel">
{{ props.label }}
</label>
</div>
<div :id="descriptionId" class="pkpFormField__description">
{{ props.description }}
</div>
<PkpTable :labelled-by="labelId" :described-by="descriptionId">
<TableHeader>
<TableColumn id="">{{ t('user.givenName', []) }}</TableColumn>
<TableColumn id="">{{ t('user.familyName', []) }}</TableColumn>
<TableColumn id="">{{ t('user.orcid', []) }}</TableColumn>
<TableColumn id="" class="w-[100px]">&nbsp;</TableColumn>
</TableHeader>
<TableBody>
<TableRow v-for="(row, index) in currentValue" :key="index">
<TableCell>
<FieldText
:name="'givenName'"
:value="row.givenName"
@change="
(fieldName, _, fieldValue) => {
updateRow(index, fieldName, fieldValue);
}
"
:all-errors="{givenName: errors?.[index]?.givenName}"
/>
</TableCell>
<TableCell>
<FieldText
:name="'familyName'"
:value="row.familyName"
@change="
(fieldName, _, fieldValue) => {
updateRow(index, fieldName, fieldValue);
}
"
:all-errors="{familyName: errors?.[index]?.familyName}"
/>
</TableCell>
<TableCell>
<FieldText
:name="'orcid'"
:value="row.orcid"
@change="
(fieldName, _, fieldValue) => {
updateRow(index, fieldName, fieldValue);
}
"
:all-errors="{orcid: errors?.[index]?.orcid}"
/>
</TableCell>
<TableCell>
<PkpButton :is-link="true" @click="deleteRow(index)">
{{ t('common.delete', []) }}
</PkpButton>
</TableCell>
</TableRow>
</TableBody>
<template #bottom-controls>
<PkpButton @click="addRow()">
{{ addButtonLabel ? addButtonLabel : t('common.add') }}
</PkpButton>
</template>
</PkpTable>
</div>
</template>

<script setup>
import {computed, useId} from 'vue';
import {useLocalize} from '@/composables/useLocalize';
import PkpButton from '@/components/Button/Button.vue';
import PkpTable from '@/components/Table/Table.vue';
import TableCell from '@/components/Table/TableCell.vue';
import TableRow from '@/components/Table/TableRow.vue';
import TableColumn from '@/components/Table/TableColumn.vue';
import TableHeader from '@/components/Table/TableHeader.vue';
import TableBody from '@/components/Table/TableBody.vue';
import FieldText from '@/components/Form/fields/FieldText.vue';

const {t} = useLocalize();
const props = defineProps({
/** Field key used for form submission */
name: {
type: String,
default: null,
},
/** The ID of the form this field should appear in. This is passed down from the `Form`. */
formId: {
type: String,
default: null,
},
/** The `<label>` for this field. May be used in a `<fieldset>` when appropriate. All form fields should have an accessible label. */
label: {
type: String,
default: null,
},
/** Adds a description to the field. Can include HTML code. */
description: {
type: String,
default: null,
},
/** Current value of the field */
value: {
type: Array,
default: () => [],
},
/** Label for add button */
addButtonLabel: {
type: String,
default: null,
},
/** Object containing all form errors */
allErrors: {
type: Object,
default() {
return {};
},
},
});
const labelId = useId();
const descriptionId = useId();
const emit = defineEmits(['change', 'set-errors']);
const errors = computed(() => {
if (!Object.keys(props.allErrors).includes(props.name)) {
return [];
}
return props.allErrors[props.name];
});
const rowDataModel = () => {
return {
givenName: '',
familyName: '',
orcid: '',
};
};
const currentValue = computed({
get: () => props.value,
set: (newVal) => emit('change', props.name, 'value', newVal),
});

function deleteRow(index) {
currentValue.value.splice(index, 1);
}

function addRow() {
currentValue.value.push(rowDataModel());
}

function updateRow(rowIndex, fieldName, fieldValue) {
currentValue.value = currentValue.value.map((row, index) => {
if (index !== rowIndex) {
return row;
}
return {
...row,
[fieldName]: fieldValue,
};
});
}
</script>
32 changes: 32 additions & 0 deletions src/components/Form/mocks/field-authors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default {
name: 'author-authors',
component: 'author-authors',
label: 'Author Information',
description: 'Author information description',
value: [
{
givenName: 'Christian',
familyName: 'Hauschke',
orcid: 'https://orcid.org/0000-0003-2499-7741',
},
{
givenName: 'Lambert',
familyName: 'Heller',
orcid: 'https://orcid.org/0000-0003-0232-7085',
},
{
givenName: 'Bo-Christer',
familyName: 'Björk',
},
{
givenName: 'Cenyu',
familyName: 'Shen',
orcid: 'https://orcid.org/0000-0002-4411-9674',
},
{
givenName: 'Mikael',
familyName: 'Laakso',
orcid: 'https://orcid.org/0000-0003-3951-7990',
},
],
};
34 changes: 34 additions & 0 deletions src/managers/CitationManager/CitationManager.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
Primary,
Controls,
Stories,
Meta,
ArgTypes
} from '@storybook/addon-docs/blocks';
import * as CitationManager from './CitationManager.stories.js';

<Meta of={CitationManager} />

# Citation manager

Listing of Citations.

## Props

<ArgTypes />

## Extension points for plugins

For more details and examples on how to use them, check out [Plugins guide](..?path=/docs/guide-plugins--docs)

The name of the Pinia store is `CitationManager`.

- `getTopItems`: Add/Change items in the top right, where the `Upload / Select` button is.
- `getItemActions`: Add/Change the list of actions that are displayed after clicking the 3 dots button.
- `getItemPrimaryActions`: Add/Change one individual Action which is displayed in the ACTIONS column.
- `getColumns`: Add/Change the columns being displayed in the table.
- ...

<Primary />
<Controls />
<Stories />
17 changes: 17 additions & 0 deletions src/managers/CitationManager/CitationManager.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import CitationManager from './CitationManager.vue';

export default {
title: 'Managers/CitationManager',
component: CitationManager,
render: (args) => ({
components: {CitationManager},
setup() {
return {args};
},
template: `<CitationManager v-bind="args"/>`,
}),
};

export const Base = {
args: {},
};
Loading
Loading