- schow no contributor in oai if no contributor is defined

- add contributor_type during creating the dataset
This commit is contained in:
Arno Kaimbacher 2020-05-04 13:50:23 +02:00
parent 76bdfcdf92
commit 3a2336adad
23 changed files with 434 additions and 316 deletions

View File

@ -21,6 +21,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Config;
class IndexController extends Controller class IndexController extends Controller
{ {
@ -75,6 +76,8 @@ class IndexController extends Controller
$page = Page::query()->where('page_slug', 'terms-and-conditions')->firstOrFail(); $page = Page::query()->where('page_slug', 'terms-and-conditions')->firstOrFail();
$contributorTypes = Config::get('enums.contributor_types');
//$relationTypes = array('updates' => 'updates', 'updated-by' => 'updated-by', 'other' => 'other'); //$relationTypes = array('updates' => 'updates', 'updated-by' => 'updated-by', 'other' => 'other');
return view( return view(
'publish.create-step1', 'publish.create-step1',
@ -88,6 +91,7 @@ class IndexController extends Controller
'titleTypes', 'titleTypes',
'keywordTypes', 'keywordTypes',
'descriptionTypes', 'descriptionTypes',
'contributorTypes',
'page' 'page'
) )
); );
@ -394,7 +398,11 @@ class IndexController extends Controller
if (isset($data['contributors'])) { if (isset($data['contributors'])) {
//$data_to_sync = []; //$data_to_sync = [];
foreach ($request->get('contributors') as $key => $contributor) { foreach ($request->get('contributors') as $key => $contributor) {
$pivot_data = ['role' => 'contributor', 'sort_order' => $key + 1]; $pivot_data = [
'role' => 'contributor',
'sort_order' => $key + 1,
'contributor_type' => $contributor['contributor_type']
];
if (isset($contributor['id'])) { if (isset($contributor['id'])) {
//$data_to_sync[$person['id']] = $pivot_data; //$data_to_sync[$person['id']] = $pivot_data;
$dataset->persons()->attach($contributor['id'], $pivot_data); $dataset->persons()->attach($contributor['id'], $pivot_data);

View File

@ -26,6 +26,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Config;
class SubmitController extends Controller class SubmitController extends Controller
{ {
@ -61,8 +62,11 @@ class SubmitController extends Controller
*/ */
public function edit($id): \Illuminate\Contracts\View\View public function edit($id): \Illuminate\Contracts\View\View
{ {
$dataset = Dataset::findOrFail($id); // $dataset = Dataset::findOrFail($id);
$dataset->load('licenses', 'authors', 'contributors', 'titles', 'abstracts', 'files', 'coverage', 'subjects', 'references'); $dataset = Dataset::where('id', $id)
->with('contributors')->first();
$dataset->load('licenses', 'authors', 'titles', 'abstracts', 'files', 'coverage', 'subjects', 'references');
$titleTypes = ['Main' => 'Main', 'Sub' => 'Sub', 'Alternative' => 'Alternative', $titleTypes = ['Main' => 'Main', 'Sub' => 'Sub', 'Alternative' => 'Alternative',
'Translated' => 'Translated', 'Other' => 'Other']; 'Translated' => 'Translated', 'Other' => 'Other'];
@ -73,6 +77,8 @@ class SubmitController extends Controller
->where('active', true) ->where('active', true)
->pluck('part1', 'part1'); ->pluck('part1', 'part1');
$contributorTypes = Config::get('enums.contributor_types');
$messages = DB::table('messages') $messages = DB::table('messages')
->pluck('help_text', 'metadata_element'); ->pluck('help_text', 'metadata_element');
@ -111,6 +117,7 @@ class SubmitController extends Controller
'dataset', 'dataset',
'titleTypes', 'titleTypes',
'descriptionTypes', 'descriptionTypes',
'contributorTypes',
'languages', 'languages',
'messages', 'messages',
'projects', 'projects',

View File

@ -139,7 +139,7 @@ class Dataset extends Model
{ {
return $this return $this
->belongsToMany(Person::class, 'link_documents_persons', 'document_id', 'person_id') ->belongsToMany(Person::class, 'link_documents_persons', 'document_id', 'person_id')
->withPivot('role', 'sort_order', 'allow_email_contact'); ->withPivot('role', 'sort_order', 'allow_email_contact', 'contributor_type');
} }
/** /**

13
composer.lock generated
View File

@ -4087,24 +4087,21 @@
}, },
{ {
"name": "phpdocumentor/reflection-common", "name": "phpdocumentor/reflection-common",
"version": "2.0.0", "version": "2.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
"reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1" "php": ">=7.1"
}, },
"require-dev": {
"phpunit/phpunit": "~6"
},
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -4135,7 +4132,7 @@
"reflection", "reflection",
"static analysis" "static analysis"
], ],
"time": "2018-08-07T13:53:10+00:00" "time": "2020-04-27T09:25:28+00:00"
}, },
{ {
"name": "phpdocumentor/reflection-docblock", "name": "phpdocumentor/reflection-docblock",

View File

@ -22,8 +22,31 @@ return [
'mimetypes_allowed' => [ 'mimetypes_allowed' => [
"pdf" => "application/pdf", "pdf" => "application/pdf",
"txt|asc|c|cc|h|srt" => "text/plain", "txt|asc|c|cc|h|srt" => "text/plain",
"htm|html" => "text/html", "htm|html" => "text/html",
"png" => "image/png", "png" => "image/png",
"jpg|jpeg|jpe" => "image/jpeg", "jpg|jpeg|jpe" => "image/jpeg",
] ],
'contributor_types' => [
'contact_person' => 'ContactPerson',
'data_collector' => 'DataCollector',
'data_curator' => 'DataCurator',
'data_manager' => 'DataManager',
'Distributor' => 'Distributor',
'editor' => 'Editor',
'hosting_institution' => 'HostingInstitution',
'producer' => 'Producer',
'poroject_leader' => 'ProjectLeader',
'project_manager' => 'ProjectManager',
'project_member' => 'ProjectMember',
'registration_agency' => 'RegistrationAgency',
'registration_authority' => 'RegistrationAuthority',
'related_person' => 'RelatedPerson',
'researcher' => 'Researcher',
'research_group' => 'ResearchGroup',
'rights_holder' => 'RightsHolder',
'sponsor' => 'Sponsor',
'supervisor' => 'Supervisor',
'work_package_leader' => 'WorkPackageLeader',
'other' => 'Other',
],
]; ];

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Config;
class AddContributorTypeToDocumentsPersons extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('link_documents_persons', function (Blueprint $table) {
$table->enum('contributor_type', Config::get('enums.contributor_types'))->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('link_documents_persons', function (Blueprint $table) {
$table->dropColumn('contributor_type');
});
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -38,8 +38,8 @@
<xsl:output method="xml" indent="yes" /> <xsl:output method="xml" indent="yes" />
<xsl:template match="Rdr_Dataset" mode="oai_datacite"> <xsl:template match="Rdr_Dataset" mode="oai_datacite">
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://datacite.org/schema/kernel-4" <resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.1/metadata.xsd"> xmlns="http://datacite.org/schema/kernel-4" xsi:schemaLocation="http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.1/metadata.xsd">
<!-- <isReferenceQuality>true</isReferenceQuality> <!-- <isReferenceQuality>true</isReferenceQuality>
<schemaVersion>4.1</schemaVersion> <schemaVersion>4.1</schemaVersion>
<datacentreSymbol>RDR.GBA</datacentreSymbol> --> <datacentreSymbol>RDR.GBA</datacentreSymbol> -->
@ -70,9 +70,11 @@
<language> <language>
<xsl:value-of select="@Language" /> <xsl:value-of select="@Language" />
</language> </language>
<contributors> <xsl:if test="PersonContributor">
<xsl:apply-templates select="PersonContributor" mode="oai_datacite" /> <contributors>
</contributors> <xsl:apply-templates select="PersonContributor" mode="oai_datacite" />
</contributors>
</xsl:if>
<dates> <dates>
<xsl:call-template name="RdrDate2" mode="oai_datacite" /> <xsl:call-template name="RdrDate2" mode="oai_datacite" />
</dates> </dates>
@ -115,7 +117,8 @@
</resource> </resource>
</xsl:template> </xsl:template>
<xsl:template name="RdrDate2" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template name="RdrDate2" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<xsl:if test="EmbargoDate"> <xsl:if test="EmbargoDate">
<date> <date>
<xsl:attribute name="dataType">Available</xsl:attribute> <xsl:attribute name="dataType">Available</xsl:attribute>
@ -140,7 +143,8 @@
</xsl:if> </xsl:if>
</xsl:template> </xsl:template>
<xsl:template match="Coverage" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="Coverage" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<geoLocation> <geoLocation>
<geoLocationBox> <geoLocationBox>
<westBoundLongitude> <westBoundLongitude>
@ -159,7 +163,8 @@
</geoLocation> </geoLocation>
</xsl:template> </xsl:template>
<xsl:template match="TitleAbstract" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="TitleAbstract" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<description> <description>
<xsl:attribute name="xml:lang"> <xsl:attribute name="xml:lang">
<xsl:value-of select="@Language" /> <xsl:value-of select="@Language" />
@ -172,7 +177,8 @@
<xsl:value-of select="@Value" /> <xsl:value-of select="@Value" />
</description> </description>
</xsl:template> </xsl:template>
<xsl:template match="TitleAbstractAdditional" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="TitleAbstractAdditional" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<description> <description>
<xsl:attribute name="xml:lang"> <xsl:attribute name="xml:lang">
<xsl:value-of select="@Language" /> <xsl:value-of select="@Language" />
@ -186,7 +192,8 @@
</description> </description>
</xsl:template> </xsl:template>
<xsl:template match="TitleMain" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="TitleMain" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<title> <title>
<xsl:if test="@Language != ''"> <xsl:if test="@Language != ''">
<xsl:attribute name="xml:lang"> <xsl:attribute name="xml:lang">
@ -201,7 +208,8 @@
<xsl:value-of select="@Value"/> <xsl:value-of select="@Value"/>
</title> </title>
</xsl:template> </xsl:template>
<xsl:template match="TitleAdditional" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="TitleAdditional" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<title> <title>
<xsl:if test="@Language != ''"> <xsl:if test="@Language != ''">
<xsl:attribute name="xml:lang"> <xsl:attribute name="xml:lang">
@ -217,7 +225,8 @@
</title> </title>
</xsl:template> </xsl:template>
<xsl:template match="Subject" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="Subject" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<subject> <subject>
<xsl:if test="@Language != ''"> <xsl:if test="@Language != ''">
<xsl:attribute name="xml:lang"> <xsl:attribute name="xml:lang">
@ -228,7 +237,8 @@
</subject> </subject>
</xsl:template> </xsl:template>
<xsl:template match="Reference" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="Reference" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<relatedIdentifier> <relatedIdentifier>
<xsl:attribute name="relatedIdentifierType"> <xsl:attribute name="relatedIdentifierType">
<xsl:value-of select="@Type" /> <xsl:value-of select="@Type" />
@ -240,7 +250,8 @@
</relatedIdentifier> </relatedIdentifier>
</xsl:template> </xsl:template>
<xsl:template match="PersonContributor" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="PersonContributor" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<contributor> <contributor>
<contributorName> <contributorName>
<xsl:if test="@NameType != ''"> <xsl:if test="@NameType != ''">
@ -254,7 +265,8 @@
</xsl:template> </xsl:template>
<xsl:template match="PersonAuthor" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="PersonAuthor" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<creator> <creator>
<creatorName> <creatorName>
<xsl:if test="@NameType != ''"> <xsl:if test="@NameType != ''">
@ -291,13 +303,15 @@
</creator> </creator>
</xsl:template> </xsl:template>
<xsl:template match="File/@MimeType" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="File/@MimeType" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<format> <format>
<xsl:value-of select="." /> <xsl:value-of select="." />
</format> </format>
</xsl:template> </xsl:template>
<xsl:template match="Licence" mode="oai_datacite" xmlns="http://datacite.org/schema/kernel-4"> <xsl:template match="Licence" mode="oai_datacite"
xmlns="http://datacite.org/schema/kernel-4">
<rights> <rights>
<xsl:if test="@LinkLicence != ''"> <xsl:if test="@LinkLicence != ''">
<xsl:attribute name="rightsURI"> <xsl:attribute name="rightsURI">

View File

@ -112,6 +112,7 @@ export default class EditDataset extends Vue {
this.realMerge(this.form, window.Laravel.form); this.realMerge(this.form, window.Laravel.form);
this.titleTypes = window.Laravel.titleTypes; this.titleTypes = window.Laravel.titleTypes;
this.descriptionTypes = window.Laravel.descriptionTypes; this.descriptionTypes = window.Laravel.descriptionTypes;
this.contributorTypes = window.Laravel.contributorTypes;
this.languages = window.Laravel.languages; this.languages = window.Laravel.languages;
this.messages = window.Laravel.messages; this.messages = window.Laravel.messages;
this.projects = window.Laravel.projects; this.projects = window.Laravel.projects;
@ -119,8 +120,6 @@ export default class EditDataset extends Vue {
this.checkeds = window.Laravel.checkeds; this.checkeds = window.Laravel.checkeds;
this.referenceTypes = window.Laravel.referenceTypes; this.referenceTypes = window.Laravel.referenceTypes;
this.relationTypes = window.Laravel.relationTypes; this.relationTypes = window.Laravel.relationTypes;
} }
created() { created() {

View File

@ -1,155 +1,211 @@
<!-- https://pineco.de/instant-ajax-search-laravel-vue/ <!-- https://pineco.de/instant-ajax-search-laravel-vue/
https://alligator.io/vuejs/vue-autocomplete-component/ --> https://alligator.io/vuejs/vue-autocomplete-component/ -->
<template> <template>
<div style="position:relative"> <div style="position:relative">
<input type="search" @input="searchChanged" v-model="search" v-bind:readonly="isLoading == true" v-bind:title="title" v-bind:placeholder="title" <input
class="pure-u-23-24" v-on:keydown.down="onArrowDown" v-on:keydown.up="onArrowUp" v-on:keydown.enter="onEnter"> type="search"
<!-- <ul class="autocomplete-results" v-show="results.length > 0"> --> @input="searchChanged"
<ul class="autocomplete-results pure-u-23-24" v-show="isOpen"> v-model="display"
<li class="loading" v-if="isLoading" >Loading results...</li> v-bind:readonly="isLoading == true"
v-bind:title="title"
v-bind:placeholder="title"
class="pure-u-23-24"
v-on:keydown.down="onArrowDown"
v-on:keydown.up="onArrowUp"
v-on:keydown.enter="onEnter"
/>
<!-- <ul class="autocomplete-results" v-show="results.length > 0"> -->
<ul class="autocomplete-results pure-u-23-24" v-show="showResults">
<li class="loading" v-if="isLoading">Loading results...</li>
<li <li
v-else v-else
v-for="(suggestion, i) in results" v-for="(suggestion, i) in results"
:key="i" :key="i"
@click="setResult(suggestion)" @click.prevent="setResult(suggestion)"
class="autocomplete-result" ref="options"
:class="{ 'is-active': i === arrowCounter }" class="autocomplete-result"
> :class="{ 'is-active': i === selectedIndex }"
<strong>{{ suggestion.full_name }}</strong> >
</li> <strong>{{ suggestion.full_name }}</strong>
</ul> </li>
</div> </ul>
</div>
</template> </template>
<script> <script lang="ts">
import _ from 'lodash'; import Vue from "vue";
import axios from 'axios'; import debounce from "lodash/debounce";
import axios from "axios";
import { Component, Prop, Watch } from "vue-property-decorator";
export default { @Component({})
export default class MyAutocomplete extends Vue {
//data from parent component //data from parent component
props: { @Prop()
title: String title: string;
// items: {
// type: Array,
// required: false,
// default: () => []
// },
// isAsync: {
// type: Boolean,
// required: false,
// default: false
// }
},
data() {
return {
search: null,
results: [],
isOpen: false,
isLoading: false,
isAsync: true,
items: [],
arrowCounter: -1
};
},
// watch: { display: string = "";
// search(after, before) { value = null;
// this.isOpen = true; error: string = null;
// this.filterResults(); suggestions: Array<any> = [];
// } isOpen = false;
// }, // isLoading = false;
loading: boolean = false;
isAsync: boolean = true;
results: Array<any> = [];
selectedIndex: number = null;
selectedDisplay = null;
watch: { get showResults(): boolean {
// Once the items content changes, it means the parent component return this.results.length > 0;
// provided the needed data
items: function(value, oldValue) {
// we want to make sure we only do this when it's an async request
if (this.isAsync) {
this.results = value;
this.isOpen = true;
this.isLoading = false;
} else {
if (value.length !== oldValue.length) {
this.results = value;
this.isLoading = false;
}
}
}
},
methods: {
setResult(person) {
// this.search = person.full_name;
this.reset();
this.$emit("person", person);
},
reset() {
this.search = "";
this.results = [];
this.isOpen = false;
},
searchChanged() {
// Let's warn the parent that a change was made
this.$emit("input", this.search);
if (this.search.length >= 2) {
// Is the data given by an outside ajax request?
if (this.isAsync) {
this.isLoading = true;
this.filterResults();
} else {
// Data is sync, we can search our flat array
this.results = this.items.filter(item => {
return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
});
this.isOpen = true;
}
} else {
this.items = [];
}
},
filterResults: _.debounce(function() {
var self = this;
axios
.get("/api/persons", { params: { filter: this.search.toLowerCase() } })
.then(function(response) {
return (self.items = response.data.data);
})
.catch(function(error) {
alert(error);
});
// this.results = this.items.filter(item => {
// return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
// });
}, 300),
onArrowDown() {
if (this.arrowCounter < this.results.length - 1) {
this.arrowCounter = this.arrowCounter + 1;
}
},
onArrowUp() {
if (this.arrowCounter > 0) {
this.arrowCounter = this.arrowCounter - 1;
}
},
onEnter() {
if(Array.isArray(this.results) && this.results.length && this.arrowCounter !== -1 && this.arrowCounter < this.results.length){
//this.search = this.results[this.arrowCounter];
var person = this.results[this.arrowCounter];
this.$emit("person", person);
//this.isOpen = false;
this.reset();
this.arrowCounter = -1;
}
}
},
computed: {
// isOpen() {
// return this.results.length > 0;
// }
} }
}; get noResults(): boolean {
return Array.isArray(this.results) && this.results.length === 0;
}
get isLoading(): boolean {
return this.loading === true;
}
get hasError(): boolean {
return this.error !== null;
}
@Watch("results")
onResultsChanged(value: Array<string>, oldValue: Array<string>) {
// we want to make sure we only do this when it's an async request
if (this.isAsync) {
this.suggestions = value;
this.isOpen = true;
this.loading = false;
} else {
if (value.length !== oldValue.length) {
this.suggestions = value;
this.loading = false;
}
}
}
setResult(person) {
// this.search = person.full_name;
this.clear();
this.$emit("person", person);
}
clear() {
this.display = "";
this.results = [];
this.error = null;
this.$emit("clear");
}
searchChanged() {
// Let's warn the parent that a change was made
this.$emit("input", this.display);
this.selectedIndex = null;
if (this.display.length >= 2) {
// Is the data given by an outside ajax request?
if (this.isAsync) {
this.loading = true;
this.resourceSearch();
} else {
// Data is sync, we can search our flat array
this.results = this.results.filter(item => {
return item.toLowerCase().indexOf(this.display.toLowerCase()) > -1;
});
this.isOpen = true;
}
} else {
this.results = [];
}
}
resourceSearch = debounce(function() {
var self = this;
if (!this.display) {
this.results = [];
return;
}
this.loading = true;
this.request();
// axios
// .get("/api/persons", { params: { filter: this.display.toLowerCase() } })
// .then(function(response) {
// return (self.results = response.data.data);
// })
// .catch(function(error) {
// alert(error);
// });
}, 200);
async request() {
try {
var res = await this.searchTerm(this.display.toLowerCase());
this.error = null;
this.results = res.data;
this.loading = false;
} catch (error) {
this.error = error.message;
this.loading = false;
}
}
async searchTerm(term: string): Promise<any> {
let res = await axios.get("/api/persons", { params: { filter: term } });
return res.data; //.response;//.docs;
}
onArrowDown(ev) {
ev.preventDefault();
if (this.selectedIndex === null) {
this.selectedIndex = 0;
return;
}
this.selectedIndex =
this.selectedIndex === this.suggestions.length - 1
? 0
: this.selectedIndex + 1;
this.fixScrolling();
}
onArrowUp(ev) {
ev.preventDefault();
if (this.selectedIndex === null) {
this.selectedIndex = this.suggestions.length - 1;
return;
}
this.selectedIndex =
this.selectedIndex === 0
? this.suggestions.length - 1
: this.selectedIndex - 1;
this.fixScrolling();
}
private fixScrolling() {
const currentElement = this.$refs.options[this.selectedIndex];
currentElement.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "start"
});
}
onEnter() {
if (
Array.isArray(this.results) &&
this.results.length &&
this.selectedIndex !== -1 &&
this.selectedIndex < this.results.length
) {
//this.display = this.results[this.selectedIndex];
var person = this.results[this.selectedIndex];
this.$emit("person", person);
this.clear();
this.selectedIndex = -1;
}
}
}
</script> </script>
<style> <style>

View File

@ -1,4 +1,4 @@
<template> <template>
<div> <div>
<h3 v-if="heading && personlist.length && showHeading == true">{{ heading }}</h3> <h3 v-if="heading && personlist.length && showHeading == true">{{ heading }}</h3>
<table class="pure-table pure-table-horizontal" v-if="personlist.length"> <table class="pure-table pure-table-horizontal" v-if="personlist.length">
@ -12,86 +12,56 @@
<th scope="col"> <th scope="col">
<label for="language"> <label for="language">
<span> <span>
ORCID <i ORCID <i v-tooltip="{ content: messages.orcid, class: 'tooltip-custom tooltip-other-custom' }"
v-tooltip="{ content: messages.orcid, class: 'tooltip-custom tooltip-other-custom' }" class="far fa-lg fa-question-circle"></i>
class="far fa-lg fa-question-circle"
></i>
</span> </span>
</label> </label>
</th> </th>
<th scope="col" v-if="Object.keys(contributortypes).length">
<span>Type</span>
</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<draggable <draggable v-bind:list="personlist" tag="tbody" v-on:start="isDragging=true" v-on:end="isDragging=false">
v-bind:list="personlist" <tr v-for="(item, index) in personlist" v-bind:key="item.id"
tag="tbody" v-bind:class="[item.status==true ? 'activeClass' : 'inactiveClass']">
v-on:start="isDragging=true"
v-on:end="isDragging=false"
>
<tr
v-for="(item, index) in personlist"
v-bind:key="item.id"
v-bind:class="[item.status==true ? 'activeClass' : 'inactiveClass']"
>
<td scope="row">{{ index + 1 }}</td> <td scope="row">{{ index + 1 }}</td>
<td> <td>
<input <input style="width:30px;" v-bind:name="heading+'['+index+'][id]'" class="form-control" v-model="item.id"
v-bind:name="heading+'['+index+'][id]'" readonly data-vv-scope="step-1" />
class="form-control"
v-model="item.id"
readonly
data-vv-scope="step-1"
/>
</td> </td>
<td> <td>
<input <input v-bind:name="heading+'['+index+'][first_name]'" class="form-control" placeholder="[FIRST NAME]"
v-bind:name="heading+'['+index+'][first_name]'" v-model="item.first_name" v-bind:readonly="item.status==1" v-validate="'required'"
class="form-control" data-vv-scope="step-1" />
placeholder="[FIRST NAME]"
v-model="item.first_name"
v-bind:readonly="item.status==1"
v-validate="'required'"
data-vv-scope="step-1"
/>
</td> </td>
<td> <td>
<input <input v-bind:name="heading+'['+index+'][last_name]'" class="form-control" placeholder="[LAST NAME]"
v-bind:name="heading+'['+index+'][last_name]'" v-model="item.last_name" v-bind:readonly="item.status==1" v-validate="'required'"
class="form-control" data-vv-scope="step-1" />
placeholder="[LAST NAME]"
v-model="item.last_name"
v-bind:readonly="item.status==1"
v-validate="'required'"
data-vv-scope="step-1"
/>
</td> </td>
<td> <td>
<!-- v-validate="'required|email'" --> <!-- v-validate="'required|email'" -->
<input <input v-bind:name="heading+'['+index+'][email]'" class="form-control" placeholder="[EMAIL]"
v-bind:name="heading+'['+index+'][email]'" v-model="item.email" v-validate="{required: true, email: true, unique: [personlist, index, 'email']}"
class="form-control" v-bind:readonly="item.status==1" data-vv-scope="step-1" />
placeholder="[EMAIL]"
v-model="item.email"
v-validate="{required: true, email: true, unique: [personlist, index, 'email']}"
v-bind:readonly="item.status==1"
data-vv-scope="step-1"
/>
</td> </td>
<td> <td>
<input <input style="width:70px;" v-bind:name="heading+'['+index+'][identifier_orcid]'" class="form-control"
v-bind:name="heading+'['+index+'][identifier_orcid]'" placeholder="[ORCID]" v-model="item.identifier_orcid" v-bind:readonly="item.status==1"
class="form-control" data-vv-scope="step-1" />
placeholder="[ORCID optional]" </td>
v-model="item.identifier_orcid" <td v-if="Object.keys(contributortypes).length">
v-bind:readonly="item.status==1" <select type="text" v-bind:name="heading+'['+index+'][contributor_type]'" v-validate="{required: true}"
data-vv-scope="step-1" data-vv-scope="step-1" v-model="item.contributor_type">
/> <option v-for="(option, i) in contributortypes" :value="option" :key="i">
{{ option }}
</option>
</select>
</td> </td>
<td> <td>
<button <button class="pure-button button-small is-warning" @click.prevent="removeAuthor(index)">
class="pure-button button-small is-warning"
@click.prevent="removeAuthor(index)"
>
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
</button> </button>
</td> </td>
@ -102,78 +72,83 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import draggable from "vuedraggable"; import draggable from "vuedraggable";
import { Component, Inject, Vue, Prop, Watch } from "vue-property-decorator"; import { Component, Inject, Vue, Prop, Watch } from "vue-property-decorator";
import Tooltip from 'vue-directive-tooltip'; import Tooltip from 'vue-directive-tooltip';
import 'vue-directive-tooltip/dist/vueDirectiveTooltip.css'; import 'vue-directive-tooltip/dist/vueDirectiveTooltip.css';
Vue.use(Tooltip); Vue.use(Tooltip);
@Component({ @Component({
components: { draggable } components: { draggable }
}) })
export default class PersonTable extends Vue { export default class PersonTable extends Vue {
@Inject("$validator") readonly $validator; @Inject("$validator") readonly $validator;
// inject: { // inject: {
// $validator: "$validator" // $validator: "$validator"
// }, // },
name: "person-table"; name: "person-table";
// components: { // components: {
// draggable // draggable
// }, // },
editable = true; editable = true;
isDragging = false; isDragging = false;
delayedDragging = false; delayedDragging = false;
@Prop({ default: true, type: Array }) @Prop({ required: true, type: Array })
personlist; personlist;
@Prop(Number) @Prop({ default: {}, type: Object })
rowIndex; contributortypes;
@Prop(String) @Prop(Number)
heading; rowIndex;
@Prop({ required: true, type: Array }) @Prop(String)
messages; heading;
@Prop({ default: true, type: Boolean }) @Prop({ required: true, type: Array })
showHeading; messages;
@Prop({ default: true, type: Boolean })
showHeading;
// props: { // props: {
// personlist: { // personlist: {
// type: Array, // type: Array,
// required: true // required: true
// }, // },
// rowIndex: { // rowIndex: {
// type: Number // type: Number
// }, // },
// heading: String // heading: String
// }, // },
itemAction(action, data, index) { itemAction(action, data, index) {
console.log("custom-actions: " + action, data.full_name, index); console.log("custom-actions: " + action, data.full_name, index);
}
removeAuthor(key) {
this.personlist.splice(key, 1);
}
onMove({ relatedContext, draggedContext }) {
const relatedElement = relatedContext.element;
const draggedElement = draggedContext.element;
return (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed;
}
} }
removeAuthor(key) {
this.personlist.splice(key, 1);
}
onMove({ relatedContext, draggedContext }) {
const relatedElement = relatedContext.element;
const draggedElement = draggedContext.element;
return (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed;
}
}
</script> </script>
<style> <style>
.custom-actions button.ui.button { .custom-actions button.ui.button {
padding: 8px 8px; padding: 8px 8px;
} }
.custom-actions button.ui.button > i.icon {
margin: auto !important; .custom-actions button.ui.button>i.icon {
} margin: auto !important;
.activeClass { }
background-color: aquamarine;
} .activeClass {
.inactiveClass { background-color: aquamarine;
background-color: orange; }
}
.inactiveClass {
background-color: orange;
}
</style> </style>

View File

@ -93,6 +93,7 @@ const app = new Vue({
editLink: null, editLink: null,
releaseLink: null, releaseLink: null,
deleteLink: null, deleteLink: null,
contributorTypes : [],
isModalVisible: false, isModalVisible: false,
@ -154,6 +155,8 @@ const app = new Vue({
}, },
beforeMount() { beforeMount() {
this.messages = window.Laravel.messages; this.messages = window.Laravel.messages;
this.contributorTypes = window.Laravel.contributorTypes;
console.log(this.contributorTypes);
}, },
computed: { computed: {
keywords_length() { keywords_length() {
@ -331,6 +334,7 @@ const app = new Vue({
formData.append('contributors[' + i + '][email]', contributor.email); formData.append('contributors[' + i + '][email]', contributor.email);
formData.append('contributors[' + i + '][identifier_orcid]', contributor.identifier_orcid); formData.append('contributors[' + i + '][identifier_orcid]', contributor.identifier_orcid);
formData.append('contributors[' + i + '][status]', contributor.status); formData.append('contributors[' + i + '][status]', contributor.status);
formData.append('contributors[' + i + '][contributor_type]', contributor.contributor_type);
if (contributor.id !== undefined) { if (contributor.id !== undefined) {
formData.append('contributors[' + i + '][id]', contributor.id); formData.append('contributors[' + i + '][id]', contributor.id);
} }

View File

@ -320,7 +320,7 @@
<button class="pure-button button-small" @click.prevent="addNewContributor()">+</button> <button class="pure-button button-small" @click.prevent="addNewContributor()">+</button>
</div> </div>
{{-- <h3>contributor table</h3> --}} {{-- <h3>contributor table</h3> --}}
<person-table name="contributors" v-bind:messages="messages" v-bind:heading="'contributor table'" <person-table name="contributors" v-bind:messages="messages" v-bind:contributortypes="contributorTypes" v-bind:heading="'contributor table'"
v-bind:personlist="dataset.contributors"></person-table> v-bind:personlist="dataset.contributors"></person-table>
</fieldset> </fieldset>
@ -955,6 +955,7 @@
window.Laravel = <?php echo json_encode([ window.Laravel = <?php echo json_encode([
'languages' => $languages, 'languages' => $languages,
'messages' => $messages, 'messages' => $messages,
'contributorTypes' => $contributorTypes
]); ?> ]); ?>
</script> </script>
<script type="text/javascript" src="{{ asset('backend/publish/datasetPublish.js') }}"></script> <script type="text/javascript" src="{{ asset('backend/publish/datasetPublish.js') }}"></script>

View File

@ -65,6 +65,7 @@
'form' => $dataset, 'form' => $dataset,
'titleTypes' => $titleTypes, 'titleTypes' => $titleTypes,
'descriptionTypes' => $descriptionTypes, 'descriptionTypes' => $descriptionTypes,
'contributorTypes'=> $contributorTypes,
'languages' => $languages, 'languages' => $languages,
'messages' => $messages, 'messages' => $messages,
'projects' => $projects, 'projects' => $projects,