Select Git revision
PhInputForm.vue 22.87 KiB
<template>
<v-container>
<v-stepper v-model="stepper" non-linear>
<v-stepper-header>
<template v-for="(n,index) in stepsTitle">
<v-stepper-step
:key="`${index}-step`"
:edit-icon="'check'"
:complete-icon="'edit'"
:step="index+1"
:complete="stepper>index"
editable
>{{n}}</v-stepper-step>
</template>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content v-for="(n,index) in steps" :key="`${index}-content`" :step="index+1">
<v-layout align-center justify-center class="ma-0 pa-0">
<v-flex>
<div class="text-xs-right">
<v-btn v-if="stepper!==1" @click="stepper = index">Back</v-btn>
<v-btn
v-if="stepper!==sectionNumbers"
color="primary"
@click="stepper = index+2"
>Continue</v-btn>
</div>
</v-flex>
</v-layout>
<v-flex v-if="n== 'general'">
<v-layout v-for="(f) in s[index].fields" :key="f.id" row wrap fill-height>
<v-flex xs12 v-if="f.component === 'text-field'">
<v-card-title v-if="f.header !== ''" class="title grey lighten-2 white--text">
<span>{{f.header}}</span>
</v-card-title>
<ph-text-field
v-bind.sync="f"
v-on:input="f.value=$event"
v-on:input-language="setSelected(f, 'language', $event)"
v-on:textfield-validation="f.warning=$event"
v-on:add="addField(s[index].fields, f)"
v-on:remove="removeField(s[index].fields, f)"
></ph-text-field>
</v-flex>
<v-flex xs12 v-else-if="f.component === 'pharma-title'">
<ph-title
v-bind.sync="f"
v-on:input-title="f.title=$event"
v-on:input-language="setSelected(f, 'language', $event)"
v-on:title-validation="f.warning=$event"
></ph-title>
</v-flex>
<v-flex xs12 v-else-if="f.component === 'date'">
<ph-date
v-bind.sync="f"
v-on:input-date-type="setSelected(f, 'type', $event)"
v-on:input-date="f.value=$event"
v-on:add="addField(s[index].fields, f)"
v-on:remove="removeField(s[index].fields, f)"
v-on:date-validation="f.warning=$event"
></ph-date>
</v-flex>
<v-flex xs12 v-else-if="f.component === 'entity'">
<ph-entity
v-bind.sync="f"
v-on:input-firstname="f.firstname=$event"
v-on:input-lastname="f.lastname=$event"
v-on:input-organisation="f.institution=$event"
v-on:input-role="f.role=$event"
v-on:input-orcid="f.orcid=$event"
v-on:input-email="f.email=$event"
v-on:add="addField(s[index].fields, f);alert(f)"
v-on:remove="removeField(s[index].fields, f)"
v-on:up="sortFieldUp(s[index].fields, f)"
v-on:down="sortFieldDown(s[index].fields, f)"
v-on:entity-validation="f.warning=$event"
></ph-entity>
</v-flex>
<v-flex xs12 v-else-if="f.component === 'project'">
<ph-project
v-bind.sync="f"
v-on:input-project="f.project=$event; "
v-on:input-agency="f.agency=$event; "
v-on:validation="f.warning=$event"
v-on:add="addField(s[index].fields, f)"
v-on:remove="removeField(s[index].fields, f)"
v-on:up="sortFieldUp(s[index].fields, f)"
v-on:down="sortFieldDown(s[index].fields, f)"
></ph-project>
</v-flex>
<v-flex v-else-if="f.component === 'p-select'">
<p-i-select
v-bind.sync="f"
v-on:input="selectInput(f, $event)"
v-on:add="addField(s.fields, f)"
v-on:remove="removeField(s.fields, f)"
v-on:validation="f.warning=$event"
></p-i-select>
</v-flex>
</v-layout>
</v-flex>
<v-flex v-else-if="n== 'file'">
<v-card-text>
<v-layout v-for="(f) in s[index].fields" :key="f.id" row wrap>
<v-flex v-if="f.component == 'files'">
<ph-files
v-bind.sync="f"
v-on:input-numberFiles="f.nfile=$event"
v-on:input-file="f.file=$event"
v-on:input-name="f.fileName=$event"
v-on:input-type="f.fileFormat=$event"
v-on:input-extension="f.fileExtension=$event"
v-on:input-description="f.fileDescription=$event"
v-on:input-license="f.fileLicense=$event"
v-on:input-warning="f.licenseWarning=$event"
v-on:validation="f.warning=$event"
></ph-files>
</v-flex>
</v-layout>
</v-card-text>
</v-flex>
<v-flex v-else-if="n== 'content'">
<v-layout align-center justify-center fill-height>
<v-flex>
<v-toolbar dense flat color="white">
<v-toolbar-title class="title">
Fill-in the metadata for the research collection: {{$store.state.metadataInputs.containerTitle}}
{{$store.state.metadataInputs.filesTitle}}
</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs3>
<v-navigation-drawer permanent>
<v-list>
<v-item-group v-model="window">
<v-item v-for="(c) in s[index].categories" :key="c.id">
<div slot-scope="{ active, toggle }">
<v-list-tile @click="toggle">
<v-list-tile-content>{{c.question}}</v-list-tile-content>
</v-list-tile>
</div>
</v-item>
</v-item-group>
</v-list>
</v-navigation-drawer>
</v-flex>
<v-flex xs12>
<v-window v-model="window" class="mx-0">
<v-window-item v-for="(c) in s[index].categories" :key="c.id">
<v-card-title class="title">{{c.description}}</v-card-title>
<v-layout v-for="(f,index) in c.fields" :key="index">
<v-flex v-if="f.component=='ext-service'&&f.visible==true">
<ph-ext-service
v-bind.sync="f"
v-on:input-value="f.value=$event"
v-on:add-textfield="changeFieldToText(c.fields, f)"
></ph-ext-service>
</v-flex>
<v-flex v-if="f.component == 'text-field'&&f.visible==true">
<ph-text-field
v-bind.sync="f"
:multiplicable="true"
v-on:input="f.value=$event"
v-on:add="addField(c.fields, f)"
v-on:remove="removeField(c.fields, f)"
></ph-text-field>
</v-flex>
<v-flex v-if=" f.component == 'selection'&&f.visible==true">
<ph-selection
v-bind.sync="f"
:required="false"
:field="[]"
:commit="true"
:freeField="f.freefield"
:text="'skos:prefLabel'"
:nested="['@value']"
v-on:input-select="f.value=$event;updateSubfields(f.multiplicable,c.fields,f)"
:freeText="{'@type': [f.type],'skos:prefLabel': [{'@value':''}]}"
></ph-selection>
</v-flex>
<v-layout
row
wrap
v-if="f.visible==false&&$store.state.metadataInputs[f.category[0]]&&$store.state.metadataInputs[f.category[0]].indexOf(f.description)>=0"
>
<v-card-title
v-if="f.category[0]=='biologicalMacromolecule'&&c.fields[index-1].description!=f.description"
class="title"
>{{f.description}}</v-card-title>
<v-flex offset-xs2 xs10>
<ph-ext-service
v-if="f.component=='ext-service'"
v-bind.sync="f"
v-on:input-value="f.value=$event"
v-on:add-textfield="changeFieldToText(c.fields, f)"
></ph-ext-service>
<ph-text-field
v-if="f.component=='text-field'"
v-bind.sync="f"
:multiplicable="true"
v-on:input="f.value=$event"
v-on:input-language="f.language=$event"
v-on:add="addField(c.fields, f)"
v-on:remove="removeField(c.fields, f)"
></ph-text-field>
<ph-selection
v-if="f.component=='selection'"
v-bind.sync="f"
:required="false"
:field="[]"
:commit="true"
:freeField="true"
:text="'skos:prefLabel'"
:nested="['@value']"
v-on:input-select="f.value=$event;updateSubfields(f.multiplicable,c.fields,f)"
:freeText="{ '@type': [f.subjectType],
'skos:prefLabel': [{'@value':''}]}"
></ph-selection>
</v-flex>
</v-layout>
</v-layout>
</v-window-item>
</v-window>
</v-flex>
</v-layout>
</v-flex>
<v-flex v-else-if="n== 'submit'">
<v-layout align-center justify-end row class="ma-3">
<v-dialog v-if="templating" v-model="templatedialog" width="500">
<v-btn
class="mr-3"
slot="activator"
dark
raised
:loading="loading"
:disabled="loading"
color="grey"
>Save as template</v-btn>
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
<span v-t="'Save as template'"></span>
</v-card-title>
<v-card-text>
<v-text-field v-model="templatename" :label="$t('Template name')"></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
:loading="loading"
:disabled="loading"
color="grey"
dark
@click="templatedialog= false"
>
<span v-t="'Cancel'"></span>
</v-btn>
<v-btn :loading="loading" :disabled="loading" color="primary">
<span v-t="'Save'"></span>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-btn
v-if="targetpid"
raised
:loading="loading"
:disabled="loading"
color="primary"
@click="save()"
>
<span v-t="'Save'"></span>
</v-btn>
<v-btn
v-else
raised
:loading="loading"
:disabled="loading"
color="primary"
@click="$emit('submit')"
>
<span v-t="'Submit'"></span>
</v-btn>
</v-layout>
</v-flex>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-container>
</template>
<script>
import VueJsonPretty from "vue-json-pretty";
import arrays from "@/utils/arrays";
import jsonLd from "@/utils/json-ld";
import fields from "@/utils/fields";
import PhTextField from "./PhTextField";
import PhTextFieldSuggest from "./PhTextFieldSuggest";
import PhTitle from "./PhTitle";
import PhEntity from "./PhEntity";
import PhProject from "./PhProject";
import PhExtService from "./PhExtService";
import PhFiles from "./PhFiles";
import PhSelection from "./PhSelection";
import PhSelectionProj from "./PhSelectionProj";
import PhAssaySelection from "./PhAssaySelection";
import PhDate from "./PhDate";
import PISelect from "./PISelect";
export default {
name: "ph-input-form",
components: {
PhTextField,
PhTextFieldSuggest,
PhTitle,
PhEntity,
PhProject,
PhExtService,
PhFiles,
PhSelection,
PhSelectionProj,
PhDate,
PhAssaySelection,
PISelect,
VueJsonPretty
},
props: {
form: {
type: Object,
default: {
sections: []
}
},
loading: {
type: Boolean,
default: false
},
templating: {
type: Boolean,
default: true
},
floatingsavebutton: {
type: Boolean,
default: false
},
targetpid: {
type: String
},
addbutton: {
type: Boolean,
default: true
}
},
computed: {
activeTabs: function() {
var sections = this.form.sections;
return sections.filter(function(section) {
return section.isActive;
});
},
sectionNumbers: function() {
return this.activeTabs.length;
},
/* submittype: function() {
for (let s of this.form.sections) {
if (s.fields && s.type !== "member") {
for (let field of s.fields) {
if (field.predicate === "dcterms:type") {
return this.getObjectType(field.value);
}
}
}
}
},*/
filteredMetadatafields() {
let list = fields.getEditableFields();
if (this.searchfieldsinput) {
return list.filter(
f =>
f.fieldname
.toLowerCase()
.includes(this.searchfieldsinput.toLowerCase()) ||
f.definition
.toLowerCase()
.includes(this.searchfieldsinput.toLowerCase())
);
} else {
return list;
}
},
s: function() {
return this.form.sections;
}
},
data() {
return {
loading: false,
templatedialog: "",
templatename: "",
window: 0,
stepper: 1,
stepsTitle: [
"General metadata",
"File",
"Content Classification",
"Submission"
],
steps: ["general", "file", "content", "submit"]
};
},
methods: {
alert: function(e) {
console.log("alert", e);
},
getObjectType: function(contentmodel) {
switch (contentmodel) {
case "https://pid.phaidra.org/vocabulary/44TN-P1S0":
return "picture";
case "https://pid.phaidra.org/vocabulary/8YB5-1M0J":
return "audio";
case "https://pid.phaidra.org/vocabulary/B0Y6-GYT8":
return "video";
case "https://pid.phaidra.org/vocabulary/69ZZ-2KGX":
return "document";
case "https://pid.phaidra.org/vocabulary/8MY0-BQDQ":
return "container";
default:
return "unknown";
}
},
changeFieldToText: function(arr, f) {
var newField = arrays.duplicate(arr, f);
//console.log("newField", newField);
if (newField) {
newField.id = new Date().getTime();
newField.removable = true;
newField.component = "text-field";
newField.predicate = "dcterms:subject";
//newField.type = f.subjectType;
newField.removable = true;
if (newField.multiplicable) {
newField.multiplicable = true;
}
if (newField.value) {
newField.value = "";
}
if (newField.text) {
newField.text = "";
}
if (newField.ontClass) {
delete newField.ontClass;
}
if (newField.ontology) {
delete newField.ontology;
}
if (newField.topId) {
delete newField.topId;
}
}
},
addField: function(arr, f) {
var newField = arrays.duplicate(arr, f);
if (newField) {
newField.id = new Date().getTime();
newField.removable = true;
if (newField.value) {
newField.value = "";
}
if (newField.firstname) {
newField.firstname = "";
}
if (newField.lastname) {
newField.lastname = "";
}
if (newField.email) {
newField.email = "";
}
if (newField.orcid) {
newField.orcid = "";
}
if (newField.institution) {
newField.institution = [
{ "@id": "univie", "skos:prefLabel": "University of Vienna" }
];
}
if (newField.project) {
newField.project = [
{
"@type": "foaf:Project",
"skos:prefLabel": [
{
"@value": "",
"@language": "en"
}
],
"rdfs:comment": [
{
"@value": "",
"@language": "eng"
}
],
"foaf:homepage": [""],
"skos:notation": [""]
}
];
}
if (newField.agency) {
newField.agency = [
{
"@type": "frapo:FundingAgency",
"skos:prefLabel": [
{
"@value": "",
"@language": "eng"
}
],
"skos:exactMatch": [""]
}
];
}
}
},
removeField: function(arr, f) {
arrays.remove(arr, f);
},
updateSubfields: function(mult, arr, el) {
if (mult) {
var self = this;
var sub = [];
if (el.subcategory) {
sub = arr.filter(function(a) {
if (a.category) {
return a.category[0] === el.subcategory[0];
}
});
} else {
sub = arr.filter(function(a) {
if (a.category) {
return a.category[0] === el.category[0];
}
});
}
for (var a2 in sub) {
if (
self.$store.state.metadataInputs[el.category[0]].indexOf(
sub[a2].description
) < 0 &&
sub[a2].description != "selection"
) {
sub[a2].value = "";
sub[a2].text = "";
//and remove the value of the subfields, if there are some
if (sub[a2].subcategory) {
this.$store.commit(sub[a2].stateVoc, []);
//then clear all the subcategories
for (var b in sub) {
if (sub[b].category[0] === sub[a2].subcategory[0]) {
//it's a subcategory of what we selected
//clear values and store
sub[b].value = "";
sub[b].text = "";
}
}
}
} else {
}
}
// } else {
//console.log("doing nothing");
}
},
/*sortFieldUp: function(arr, f) {
var i = arr.indexOf(f);
if (arr[i - 1]) {
if (arr[i - 1].ordergroup === f.ordergroup) {
arrays.moveUp(arr, f);
}
}
},*/
/* sortFieldDown: function(arr, f) {
var i = arr.indexOf(f);
if (arr[i + 1]) {
if (arr[i + 1].ordergroup === f.ordergroup) {
arrays.moveDown(arr, f);
}
}
},*/
setSelected: function(f, property, event) {
//if (event) {
// console.log("setselected", property, f);
f[property] = event["@id"];
//}
this.$emit("form-input-" + f.component, f);
},
warning: function(section) {
console.log("in warning", section);
if (typeof section === "undefined") {
//console.log("undefined");
} else {
var w = false;
//console.log("section", section);
if (section.fields) {
var fields = section.fields;
for (var f in fields) {
//console.log("field w", fields[f]);
if (fields[f].warning === true) {
w = true;
//console.log("field", fields[f].label, "is missing");
}
}
} else if (section.categories) {
//console.log("cat", section.categories);
for (var c in section.categories) {
if (section.categories[c].fields) {
var fields = section.categories[c].fields;
for (var f in fields) {
if (fields[f].warning === true) {
w = true;
console.log("field", fields[f].label, "is missing");
}
}
}
}
}
}
return w;
},
selectInput: function(f, event) {
if (event) {
f.value = event["@id"];
if (event["@type"]) {
f.type = event["@type"];
}
var preflabels = event["skos:prefLabel"];
f["skos:prefLabel"] = [];
Object.entries(preflabels).forEach(([key, value]) => {
f["skos:prefLabel"].push({ "@value": value, "@language": key });
});
var rdfslabels = event["rdfs:label"];
if (rdfslabels) {
f["rdfs:label"] = [];
Object.entries(rdfslabels).forEach(([key, value]) => {
f["rdfs:label"].push({ "@value": value, "@language": key });
});
}
f["skos:notation"] = event["skos:notation"];
} else {
f.value = "";
f["skos:prefLabel"] = [];
}
this.$emit("form-input-" + f.component, f);
}
},
mounted: function() {
this.$store.dispatch("loadLanguages");
}
};
</script>
<style scoped>
.v-btn {
margin: 0;
}
.container {
padding: 0 !important;
}
.pharma-form .v-label {
color: rgba(0, 0, 0, 0.8) !important;
}
</style>