Commits (7)
......@@ -14,6 +14,7 @@ test:
- npm test
except:
refs:
- master
- tags
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
......@@ -22,6 +23,7 @@ publish:
stage: publish
script:
- npm run build
- npm test
- npx semantic-release
only:
- master
......
This diff is collapsed.
{
"name": "@coscine/form-generator",
"version": "1.8.4",
"version": "1.9.0",
"main": "./dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
......@@ -32,12 +32,15 @@
"singleQuote": true
},
"dependencies": {
"@coscine/api-connection": "^1.21.0",
"@coscine/app-util": "^1.5.2",
"@coscine/api-connection": "^1.22.0",
"@coscine/app-util": "^1.6.0",
"@types/jquery": "^3.5.2",
"@types/vuelidate": "^0.7.13",
"bootstrap-vue": "^2.17.3",
"jquery": "^3.5.1",
"rdf-ext": "^1.3.0",
"rdf-parse": "^1.5.0",
"rdf-validate-shacl": "^0.2.3",
"vue": "^2.6.12",
"vue-i18n": "^8.22.0",
"vue-material-design-icons": "^4.9.0",
......
......@@ -3,14 +3,17 @@
<div v-for="(formElement, index) in sortedSHACLDefinition" :key="index">
<WrapperInput
:componentDefinition="fieldDefinition(formElement)"
:idForFixedValues="fixedValueIds[index]"
:formFieldInformation="formElement"
:formData="SHACLResponse"
:formData="formData"
:resourceId="resourceId"
:projectId="projectId"
:fixedValueMode="fixedValueMode"
:fixedValues="fixedValues"
:disabledMode="disabledMode"
:languageLocale="languageLocale"
:v="$v"
:errorMessages="errorMessages"
/>
</div>
</div>
......@@ -30,6 +33,11 @@ import { LanguageUtil } from '@coscine/app-util';
import FieldReader from './util/FieldReader';
import factory from 'rdf-ext';
import SHACLValidator from 'rdf-validate-shacl';
import rdfParser from "rdf-parse";
import { Readable } from 'stream';
import WrapperInput from './components/WrapperInput.vue';
Vue.use(BootstrapVue);
......@@ -37,10 +45,13 @@ Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en',
messages: coscine.i18n['form-generator'],
messages: (window.coscine && coscine.i18n) ? coscine.i18n['form-generator'] : {},
silentFallbackWarn: true,
});
import Vuelidate from 'vuelidate';
Vue.use(Vuelidate);
export default Vue.extend({
i18n,
name: 'FormGenerator',
......@@ -52,8 +63,12 @@ export default Vue.extend({
default: '',
type: String,
},
SHACLResponse: {
default: {},
mimeType: {
default: 'application/ld+json',
type: String,
},
formData: {
default: () => ({}),
type: Object,
},
projectId: {
......@@ -73,41 +88,130 @@ export default Vue.extend({
type: Boolean,
},
fixedValues: {
default: {},
default: () => ({}),
type: Object,
},
SHACLDefinition: {
default: '',
type: String,
},
languageLocale: {
default: () => LanguageUtil.getLanguage(),
type: String,
},
},
data() {
return {
sortedSHACLDefinition: [] as object[],
SHACLDefinition: Object,
languageLocale: LanguageUtil.getLanguage(),
quads: [] as any[],
fixedValueIds: [] as any[],
sortedSHACLDefinition: [] as any[],
errorMessages: {} as any,
timeouts: {} as any,
timeoutInterval: 500,
};
},
beforeMount() {
i18n.locale = this.languageLocale;
this.sortedSHACLDefinition = [];
if (this.applicationProfileId !== '') {
if (
this.resourceId !== '00000000-0000-0000-0000-000000000000' &&
this.resourceId !== ''
) {
MetadataApi.getProfileComplete(
this.applicationProfileId,
this.resourceId,
(response: any) => {
this.handleApplicationProfiles(response);
});
} else {
MetadataApi.getProfile(
this.applicationProfileId,
(response: any) => {
this.handleApplicationProfiles(response);
});
validations() : any {
const me = this;
if (!this.fixedValueMode) {
const validator = {} as any;
for (const nodename of Object.keys(this.formData)) {
validator[nodename] = {
$each: {
value: {
async shaclValidated(value: any) {
// A debounce has been implemented based on the nodename
if (me.timeouts[nodename]) clearTimeout(me.timeouts[nodename]);
return new Promise((resolve, reject) => {
me.timeouts[nodename] = setTimeout(async() => {
// Validate the whole data and check if for the current nodename an error is logged
const report = await me.validatorFunction();
let resolveValue = true;
if (report.results.some((entry: any) => entry.path.value === nodename)) {
const result = report.results.find((entry: any) => entry.path.value === nodename);
me.errorMessages[nodename] = result.message;
resolveValue = false;
}
resolve(resolveValue);
}, me.timeoutInterval);
});
},
},
},
};
}
return {
formData: validator,
};
}
return {
formData: {},
};
},
beforeMount() {
i18n.locale = this.languageLocale;
this.handleApplicationProfiles();
},
watch: {
SHACLDefinition() {
this.handleApplicationProfiles();
},
formData() {
this.$v.$reset();
},
},
methods: {
async validatorFunction() {
const shapes = await this.loadDataset(this.SHACLDefinition, this.mimeType, this.applicationProfileId);
// RDF/JSON => JSON-LD since the loadDataset function doesn't support RDF/JSON
const dataObject = {} as any;
dataObject['@type'] = this.applicationProfileId;
for (const entry of Object.keys(this.formData)) {
for (const metadataEntry of this.formData[entry]) {
if (metadataEntry['value'] !== '') {
if (metadataEntry['type'] === 'uri') {
dataObject[entry] = {
'@id': metadataEntry['value'],
'@type': metadataEntry['datatype']
};
} else {
dataObject[entry] = {
'@value': metadataEntry['value'],
'@type': metadataEntry['datatype']
};
}
}
}
}
const data = await this.loadDataset(JSON.stringify(dataObject), 'application/ld+json', null);
const validator = new SHACLValidator(shapes);
const report = validator.validate(data);
this.$emit('isValid', report.conforms);
return report;
},
async getQuads (data: string, mimeType: string, baseUri: string | null) : Promise<any> {
const input = new Readable({
read: () => {
input.push(data);
input.push(null);
}
});
const quads = [] as any[];
return new Promise((resolve) => {
rdfParser.parse(input, { contentType: mimeType, baseIRI: baseUri })
.on('data', (quad: any) => {
quads.push(quad);
})
.on('end', () => resolve(quads));
});
},
async loadDataset (data: string, mimeType: string, baseUri: string | null) {
const quads = await this.getQuads(data, mimeType, baseUri);
const dataSet = factory.dataset();
for (const quad of quads) {
dataSet.add(quad);
}
return dataSet;
},
checkField(data: any, nodename: string, property: string = 'value') {
return FieldReader.isValueAssignedToKey(data, nodename, property);
},
......@@ -116,14 +220,14 @@ export default Vue.extend({
if (
this.checkField(formElement, 'http://www.w3.org/ns/shacl#datatype')
) {
let datatype = formElement['http://www.w3.org/ns/shacl#datatype'][0];
let datatype = FieldReader.getObject(formElement, 'http://www.w3.org/ns/shacl#datatype');
if (datatype['value'] === 'http://www.w3.org/2001/XMLSchema#string') {
if (
this.checkField(
formElement,
'http://datashapes.org/dash#singleLine'
) &&
formElement['http://datashapes.org/dash#singleLine'][0][
FieldReader.getObject(formElement, 'http://datashapes.org/dash#singleLine')[
'value'
] === 'false'
) {
......@@ -151,22 +255,36 @@ export default Vue.extend({
}
return null;
},
handleApplicationProfiles(response: any) {
this.SHACLDefinition = response.data;
let keys = Object.keys(this.SHACLDefinition);
for (let i = 0; i < keys.length; i++) {
for (let j = 0; j < keys.length; j++) {
let tmp = (this.SHACLDefinition as any)[keys[j]];
if (
this.checkField(tmp, 'http://www.w3.org/ns/shacl#order') &&
tmp['http://www.w3.org/ns/shacl#order'][0]['value'].toString() ===
'' + i
) {
tmp['idForFixedValues'] = keys[j];
this.sortedSHACLDefinition.push(tmp);
}
async retrieveSHACLDefinition() : Promise<any> {
if (this.SHACLDefinition !== null && this.SHACLDefinition !== '') {
return this.getQuads(this.SHACLDefinition, this.mimeType, this.applicationProfileId);
}
return [];
},
async handleApplicationProfiles() {
this.quads = await this.retrieveSHACLDefinition();
const unmappedSubjects = {} as any;
this.errorMessages = {} as any;
this.timeouts = {} as any;
for (let i = 0; i < this.quads.length; i++) {
if (this.quads[i].predicate.value === 'http://www.w3.org/ns/shacl#order') {
unmappedSubjects[this.quads[i].object.value] = this.quads.filter((entry) =>
entry.subject.value === this.quads[i].subject.value);
this.errorMessages[this.quads[i].subject.value] = '';
this.timeouts[this.quads[i].subject.value] = null;
}
}
this.fixedValueIds = [];
this.sortedSHACLDefinition = [];
let keys = Object.keys(unmappedSubjects).sort((a, b) => parseInt(a) - parseInt(b));
for (let i = 0; i < keys.length; i++) {
this.fixedValueIds.push(unmappedSubjects[keys[i]][0].subject.value);
this.sortedSHACLDefinition.push(unmappedSubjects[keys[i]]);
}
await this.validatorFunction();
},
},
});
......
......@@ -15,13 +15,25 @@
<script lang="ts">
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import Multiselect from 'vue-multiselect';
import 'vue-multiselect/dist/vue-multiselect.min.css';
import FieldReader from '@/util/FieldReader';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en',
messages: (window.coscine && coscine.i18n) ? coscine.i18n['form-generator'] : {},
silentFallbackWarn: true,
});
export default Vue.extend({
i18n,
name: 'InputBooleanCombobox',
beforeMount() {
i18n.locale = this.languageCode;
// set the datatype
this.$set(this.formData[this.nodeName][0], 'type', 'literal');
this.$set(
......@@ -54,11 +66,13 @@ export default Vue.extend({
},
methods: {
input() {
if (this.selectedOption !== null) {
this.$set(this.formData[this.nodeName][0], 'value', (this.selectedOption as any).value);
} else {
this.$set(this.formData[this.nodeName][0], 'value', '');
}
FieldReader.setField(
this.formData,
this.v,
this.nodeName,
this.selectedOption !== null ? (this.selectedOption as any).value : '',
this.$set
);
this.updateFixedValues();
},
loadData() {
......@@ -81,9 +95,8 @@ export default Vue.extend({
locked: Boolean,
required: Boolean,
nodeName: String,
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
fixedValues: Object,
fixedValueMode: Boolean,
disabledMode: Boolean,
checkField: Function,
......@@ -91,6 +104,7 @@ export default Vue.extend({
resourceId: String,
projectId: String,
languageCode: String,
v: Object,
},
components: {
Multiselect,
......
......@@ -23,12 +23,13 @@ import Multiselect from 'vue-multiselect';
import 'vue-multiselect/dist/vue-multiselect.min.css';
import { MetadataApi } from '@coscine/api-connection';
import FieldReader from '@/util/FieldReader';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en',
messages: coscine.i18n['form-generator'],
messages: (window.coscine && coscine.i18n) ? coscine.i18n['form-generator'] : {},
silentFallbackWarn: true,
});
......@@ -42,12 +43,19 @@ export default Vue.extend({
this.formFieldInformation,
'http://www.w3.org/ns/shacl#maxCount'
) &&
parseInt(this.formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0][
parseInt(FieldReader.getObject(this.formFieldInformation, 'http://www.w3.org/ns/shacl#maxCount')[
'value'
]) === 1;
this.class = FieldReader.getObject(this.formFieldInformation, 'http://www.w3.org/ns/shacl#class').value;
// set the datatype
this.$set(this.formData[this.nodeName][0], 'type', 'uri');
this.$set(
this.formData[this.nodeName][0],
'datatype',
this.class
);
if (this.fixedValueMode) {
this.updateFixedValues();
......@@ -56,7 +64,7 @@ export default Vue.extend({
mounted() {
MetadataApi.getClassInstances(
this.projectId,
this.formFieldInformation['http://www.w3.org/ns/shacl#class'][0].value,
this.class,
(response: any) => {
if (
Array.isArray(response.data[this.languageCode]) &&
......@@ -81,6 +89,7 @@ export default Vue.extend({
},
data() {
return {
class: '',
noMaxMode: true,
selectableOptions: [] as object[],
selectedOptions: [] as object[],
......@@ -90,19 +99,16 @@ export default Vue.extend({
methods: {
getMax() {
if (!this.noMaxMode) {
return this.formFieldInformation[
const maxCountObject = FieldReader.getObject(this.formFieldInformation,
'http://www.w3.org/ns/shacl#maxCount'
] !== undefined &&
this.formFieldInformation[
'http://www.w3.org/ns/shacl#maxCount'
][0] !== undefined &&
this.formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0][
);
return
maxCountObject !== undefined &&
maxCountObject[
'value'
] !== undefined
? parseInt(
this.formFieldInformation[
'http://www.w3.org/ns/shacl#maxCount'
][0]['value']
maxCountObject['value']
)
: this.maxNumberOfSelectedObjects;
}
......@@ -112,12 +118,15 @@ export default Vue.extend({
const array = [];
if (Array.isArray(this.selectedOptions)) {
for (const field of this.selectedOptions) {
array.push({ value: (field as any).value, type: 'uri' });
array.push({ value: (field as any).value, type: 'uri', datatype: this.class });
}
} else {
array.push({ value: (this.selectedOptions as any).value, type: 'uri' });
array.push({ value: (this.selectedOptions as any).value, type: 'uri', datatype: this.class });
}
this.$set(this.formData, this.nodeName, array);
if (this.v.formData[this.nodeName]) {
this.v.formData[this.nodeName].$touch();
}
this.updateFixedValues();
},
loadData() {
......@@ -140,9 +149,8 @@ export default Vue.extend({
locked: Boolean,
required: Boolean,
nodeName: String,
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
fixedValues: Object,
fixedValueMode: Boolean,
disabledMode: Boolean,
checkField: Function,
......@@ -150,6 +158,7 @@ export default Vue.extend({
resourceId: String,
projectId: String,
languageCode: String,
v: Object,
},
components: {
Multiselect,
......
......@@ -21,6 +21,8 @@ import Vue from 'vue';
import Datepicker from 'vuejs-datepicker';
import { de, en } from 'vuejs-datepicker/dist/locale';
import FieldReader from '@/util/FieldReader';
export default Vue.extend({
name: 'InputDatePicker',
beforeMount() {
......@@ -54,21 +56,21 @@ export default Vue.extend({
locked: Boolean,
required: Boolean,
nodeName: String,
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
fixedValues: Object,
fixedValueMode: Boolean,
disabledMode: Boolean,
checkDataField: Function,
checkField: Function,
updateFixedValues: Function,
v: Object,
},
components: {
Datepicker,
},
methods: {
replacePlaceholder() {
if (this.checkField(this.formData, this.nodeName)) {
let adjustDate = 0;
if (this.checkDataField(this.formData, this.nodeName)) {
if (this.formData[this.nodeName][0]['value'] === '{TODAY}') {
if (this.fixedValueMode) {
return;
......@@ -77,29 +79,26 @@ export default Vue.extend({
} else if (this.formData[this.nodeName][0]['value'] === '') {
this.selectedDate = new Date();
} else {
adjustDate = 1;
this.selectedDate = new Date(
this.formData[this.nodeName][0]['value']
this.formData[this.nodeName][0]['value'] + " UTC"
);
}
this.$set(
this.formData[this.nodeName][0],
'value',
`${this.selectedDate.getUTCFullYear()}-${
this.selectedDate.getUTCMonth() + 1
}-${this.selectedDate.getUTCDate() + adjustDate}`
this.selectedDate.toISOString().slice(0, 10)
);
}
},
updateFixedValuesOverwrite() {
this.$set(
this.formData[this.nodeName][0],
'value',
`${this.selectedDate.getUTCFullYear()}-${
this.selectedDate.getUTCMonth() + 1
}-${this.selectedDate.getUTCDate() + 1}`
FieldReader.setField(
this.formData,
this.v,
this.nodeName,
this.selectedDate.toISOString().slice(0, 10),
this.$set
);
this.updateFixedValues();
},
},
......
<template>
<b-form-textarea
:id="cssId"
v-model="formData[nodeName][0]['value']"
@input="updateFixedValues"
v-model="textValue"
@input="input"
:disabled="disabledMode || locked"
:required="required"
:state="v.formData[nodeName] && v.formData[nodeName].$each[0]['value'].$dirty ? !v.formData[nodeName].$each[0]['value'].$error : null"
></b-form-textarea>
</template>
......@@ -12,6 +13,7 @@
import Vue from 'vue';
import { UserApi } from '@coscine/api-connection';
import FieldReader from '@/util/FieldReader';
export default Vue.extend({
name: 'InputTextArea',
......@@ -21,29 +23,56 @@ export default Vue.extend({
// set the datatype
this.$set(this.formData[this.nodeName][0], 'type', 'literal');
this.$set(
this.formData[this.nodeName][0],
'datatype',
'http://www.w3.org/2001/XMLSchema#string'
);
if (this.fixedValueMode) {
this.updateFixedValues();
}
},
mounted() {
this.loadData();
},
data() {
return {
textValue: '',
};
},
props: {
cssId: String,
invisible: Boolean,
locked: Boolean,
required: Boolean,
nodeName: String,
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
fixedValues: Object,
fixedValueMode: Boolean,
disabledMode: Boolean,
checkDataField: Function,
checkField: Function,
updateFixedValues: Function,
v: Object,
},
methods: {
input() {
FieldReader.setField(
this.formData,
this.v,
this.nodeName,
this.textValue,
this.$set
);
this.updateFixedValues();
},
loadData() {
this.textValue = this.formData[this.nodeName][0]['value'];
},
replacePlaceholder() {
if (!this.fixedValueMode) {
if (this.checkField(this.formData, this.nodeName)) {
if (this.checkDataField(this.formData, this.nodeName)) {
if (this.formData[this.nodeName][0]['value'] === '{ME}') {
UserApi.getUser((response: any) => {
this.$set(
......@@ -51,6 +80,7 @@ export default Vue.extend({
'value',
response.data.displayName
);
this.textValue = this.formData[this.nodeName][0]['value'];
this.$forceUpdate();
});
}
......
<template>
<b-form-input
:id="cssId"
v-model="formData[nodeName][0]['value']"
@input="updateFixedValues"
v-model="textValue"
@input="input"
:disabled="disabledMode || locked"
:required="required"
:state="v.formData[nodeName] && v.formData[nodeName].$each[0]['value'].$dirty ? !v.formData[nodeName].$each[0]['value'].$error : null"
/>
</template>
......@@ -12,6 +13,7 @@
import Vue from 'vue';
import { UserApi } from '@coscine/api-connection';
import FieldReader from '@/util/FieldReader';
export default Vue.extend({
name: 'InputTextField',
......@@ -21,29 +23,56 @@ export default Vue.extend({
// set the datatype
this.$set(this.formData[this.nodeName][0], 'type', 'literal');
this.$set(
this.formData[this.nodeName][0],
'datatype',
'http://www.w3.org/2001/XMLSchema#string'
);
if (this.fixedValueMode) {
this.updateFixedValues();
}
},
mounted() {
this.loadData();
},
data() {
return {
textValue: '',
};
},
props: {
cssId: String,
invisible: Boolean,
locked: Boolean,
required: Boolean,
nodeName: String,
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
fixedValues: Object,
fixedValueMode: Boolean,
disabledMode: Boolean,
checkDataField: Function,
checkField: Function,
updateFixedValues: Function,
v: Object,
},
methods: {
input() {
FieldReader.setField(
this.formData,
this.v,
this.nodeName,
this.textValue,
this.$set
);
this.updateFixedValues();
},
loadData() {
this.textValue = this.formData[this.nodeName][0]['value'];
},
replacePlaceholder() {
if (!this.fixedValueMode) {
if (this.checkField(this.formData, this.nodeName)) {
if (this.checkDataField(this.formData, this.nodeName)) {
if (this.formData[this.nodeName][0]['value'] === '{ME}') {
UserApi.getUser((response: any) => {
this.$set(
......@@ -51,6 +80,7 @@ export default Vue.extend({
'value',
response.data.displayName
);
this.textValue = this.formData[this.nodeName][0]['value'];
this.$forceUpdate();
});
}
......
<template>
<div :class="componentDefinition" v-if="componentDefinition !== null">
<div :class="componentDefinition" v-if="componentDefinition !== null" :style="cssProps">
<b-form-group
v-bind:class="{
mandatory: valueRequired,
invisible:
!fixedValueMode &&
checkField(
this.formFieldInformation,
'https://purl.org/coscine/invisible'
) &&
this.formFieldInformation['https://purl.org/coscine/invisible'][0][
'value'
] === '1',
invisible: !fixedValueMode && invisible,
}"
:label-for="cssid"
label-cols-sm="3"
......@@ -36,17 +28,14 @@
:fixedValues="fixedValues"
:disabledMode="disabledMode"
:languageCode="languageLocale"
:checkDataField="checkDataField"
:checkField="checkField"
:updateFixedValues="updateFixedValues"
:v="v"
/>
<b-button-group v-if="fixedValueMode" class="wrapper-input-button">
<b-button
:disabled="
disabledMode ||
!formDataExists() ||
(formDataExists() && formData[nodeName][0]['value'] === '') ||
(this.valueRequired && this.invisible)
"
:disabled="fixedValueDisabled()"
class="lockButton"
variant="outline-secondary"
@click.prevent="changeLockable()"
......@@ -66,6 +55,11 @@
</b-button>
</b-button-group>
</b-button-toolbar>
<b-form-invalid-feedback :state="v.formData[nodeName] && v.formData[nodeName].$dirty ? !v.formData[nodeName].$error : null">
<div v-for="(message, index) in errorMessages[nodeName]" :key="index">
{{ message.value }}
</div>
</b-form-invalid-feedback>
</b-form-group>
</div>
</template>
......@@ -91,7 +85,7 @@ Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en',
messages: coscine.i18n['form-generator'],
messages: (window.coscine && coscine.i18n) ? coscine.i18n['form-generator'] : {},
silentFallbackWarn: true,
});
......@@ -125,11 +119,11 @@ export default Vue.extend({
if (
this.checkField(this.formFieldInformation, 'http://www.w3.org/ns/shacl#datatype')
) {
let currentDatatype = this.formFieldInformation['http://www.w3.org/ns/shacl#datatype'][0];
if (currentDatatype['value'] == 'http://www.w3.org/2001/XMLSchema#date') {
let currentDatatype = FieldReader.getObject(this.formFieldInformation, 'http://www.w3.org/ns/shacl#datatype');
if (currentDatatype['value'] === 'http://www.w3.org/2001/XMLSchema#date') {
this.type = 'literal';
this.datatype = 'http://www.w3.org/2001/XMLSchema#date';
} else if (currentDatatype['value'] == 'http://www.w3.org/2001/XMLSchema#boolean') {
} else if (currentDatatype['value'] === 'http://www.w3.org/2001/XMLSchema#boolean') {
this.type = 'literal';
this.datatype = 'http://www.w3.org/2001/XMLSchema#boolean';
} else {
......@@ -152,24 +146,24 @@ export default Vue.extend({
) {
this.$set(this.formData, this.nodeName, [
{
value: this.formFieldInformation[
value: FieldReader.getObject(this.formFieldInformation,
'https://purl.org/coscine/fixedValue'
][0].value,
).value,
},
]);
this.locked = true;
}
// if a fixed values was given directly take that
if (
this.checkField(
this.fixedValues[this.formFieldInformation['idForFixedValues']],
this.checkDataField(
this.fixedValues[this.idForFixedValues],
'https://purl.org/coscine/fixedValue'
)
) {
this.$set(this.formData, this.nodeName, [
{
value: this.fixedValues[
this.formFieldInformation['idForFixedValues']
this.idForFixedValues
]['https://purl.org/coscine/fixedValue'][0].value,
},
]);
......@@ -178,22 +172,22 @@ export default Vue.extend({
if (
this.checkField(
this.formFieldInformation['idForFixedValues'],
this.formFieldInformation,
'https://purl.org/coscine/invisible'
)
) {
this.invisible =
this.formFieldInformation['https://purl.org/coscine/invisible'][0]
FieldReader.getObject(this.formFieldInformation, 'https://purl.org/coscine/invisible')
.value === '1';
}
if (
this.checkField(
this.fixedValues[this.formFieldInformation['idForFixedValues']],
this.checkDataField(
this.fixedValues[this.idForFixedValues],
'https://purl.org/coscine/invisible'
)
) {
this.invisible =
this.fixedValues[this.formFieldInformation['idForFixedValues']][
this.fixedValues[this.idForFixedValues][
'https://purl.org/coscine/invisible'
][0].value === '1';
}
......@@ -208,9 +202,9 @@ export default Vue.extend({
) {
this.$set(this.formData, this.nodeName, [
{
value: this.formFieldInformation[
value: FieldReader.getObject(this.formFieldInformation,
'http://www.w3.org/ns/shacl#defaultValue'
][0].value,
).value,
},
]);
}
......@@ -223,23 +217,23 @@ export default Vue.extend({
) {
this.$set(this.formData, this.nodeName, [
{
value: this.formFieldInformation[
value: FieldReader.getObject(this.formFieldInformation,
'https://purl.org/coscine/defaultValue'
][0].value,
).value
},
]);
}
// take the default value from the provided values
if (
this.checkField(
this.fixedValues[this.formFieldInformation['idForFixedValues']],
this.checkDataField(
this.fixedValues[this.idForFixedValues],
'https://purl.org/coscine/defaultValue'
)
) {
this.$set(this.formData, this.nodeName, [
{
value: this.fixedValues[
this.formFieldInformation['idForFixedValues']
this.idForFixedValues
]['https://purl.org/coscine/defaultValue'][0].value,
},
]);
......@@ -255,10 +249,18 @@ export default Vue.extend({
this.formFieldInformation,
'http://www.w3.org/ns/shacl#minCount'
) &&
this.formFieldInformation['http://www.w3.org/ns/shacl#minCount'][0][
FieldReader.getObject(this.formFieldInformation, 'http://www.w3.org/ns/shacl#minCount')[
'value'
] >= 1;
},
computed: {
cssProps() : any {
return {
'--wrapperInputWidth': (this.fixedValueMode) ? 'calc(100% - 121px - 1rem)' : '100%',
'--wrapperInputRightMargin': (this.fixedValueMode) ? '1rem' : '0rem',
};
},
},
data() {
return {
type: 'literal',
......@@ -272,7 +274,7 @@ export default Vue.extend({
};
},
props: {
formFieldInformation: Object,
formFieldInformation: Array,
formData: Object,
resourceId: String,
fixedValues: Object,
......@@ -281,6 +283,9 @@ export default Vue.extend({
disabledMode: Boolean,
componentDefinition: String,
languageLocale: String,
idForFixedValues: String,
errorMessages: Object,
v: Object,
},
methods: {
changeLockable() {
......@@ -295,6 +300,9 @@ export default Vue.extend({
}
this.setFixedValues();
},
checkDataField(data: any, nodename: string, property: string = 'value') {
return FieldReader.isDataValueAssignedToKey(data, nodename, property);
},
checkField(data: any, nodename: string, property: string = 'value') {
return FieldReader.isValueAssignedToKey(data, nodename, property);
},
......@@ -307,14 +315,20 @@ export default Vue.extend({
!this.valueRequired
);
},
fixedValueDisabled() {
return this.disabledMode ||
!this.formDataExists() ||
(this.formDataExists() && this.formData[this.nodeName][0]['value'] === '') ||
(this.valueRequired && this.invisible)
},
formDataExists() {
return this.checkField(this.formData, this.nodeName);
return this.checkDataField(this.formData, this.nodeName);
},
removeEmptyEntry(){
if ((this.checkField(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/fixedValue') && this.fixedValues[this.formFieldInformation['idForFixedValues']]['https://purl.org/coscine/fixedValue'][0]['value'] === '') ||
this.checkField(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/defaultValue') && this.fixedValues[this.formFieldInformation['idForFixedValues']]['https://purl.org/coscine/defaultValue'][0]['value'] === '') {
this.$delete(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/defaultValue');
this.$delete(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/fixedValue');
if ((this.checkDataField(this.fixedValues[this.idForFixedValues],'https://purl.org/coscine/fixedValue') && this.fixedValues[this.idForFixedValues]['https://purl.org/coscine/fixedValue'][0]['value'] === '') ||
this.checkDataField(this.fixedValues[this.idForFixedValues],'https://purl.org/coscine/defaultValue') && this.fixedValues[this.idForFixedValues]['https://purl.org/coscine/defaultValue'][0]['value'] === '') {
this.$delete(this.fixedValues[this.idForFixedValues],'https://purl.org/coscine/defaultValue');
this.$delete(this.fixedValues[this.idForFixedValues],'https://purl.org/coscine/fixedValue');
this.locked = false;
}
},
......@@ -322,7 +336,7 @@ export default Vue.extend({
if (this.locked) {
this.$set(
this.fixedValues,
this.formFieldInformation['idForFixedValues'],
this.idForFixedValues,
{
'https://purl.org/coscine/invisible': [
{ value: this.invisible ? '1' : '0', type: 'literal' },
......@@ -339,7 +353,7 @@ export default Vue.extend({
} else {
this.$set(
this.fixedValues,
this.formFieldInformation['idForFixedValues'],
this.idForFixedValues,
{
'https://purl.org/coscine/invisible': [
{ value: this.invisible ? '1' : '0', type: 'literal' },
......@@ -359,9 +373,9 @@ export default Vue.extend({
updateFixedValues() {
if (this.fixedValueMode) {
if (
this.fixedValues[this.formFieldInformation['idForFixedValues']] !==
this.fixedValues[this.idForFixedValues] !==
undefined &&
this.fixedValues[this.formFieldInformation['idForFixedValues']][
this.fixedValues[this.idForFixedValues][
'https://purl.org/coscine/fixedValue'
] !== undefined
) {
......@@ -378,8 +392,8 @@ export default Vue.extend({
<style>
.wrapper-input {
width: calc(100% - 121px - 1rem);
margin-right: 1rem;
width: var(--wrapperInputWidth);
margin-right: var(--wrapperInputRightMargin);
}
.wrapper-input-button {
width: 21px;
......
......@@ -11,3 +11,7 @@ declare var coscine: {
};
declare var _spPageContextInfo: any;
interface FormFieldInformation extends Array<any>{
idForFixedValues: any;
}
\ No newline at end of file
......@@ -2,3 +2,7 @@ declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
declare module 'rdf-validate-shacl';
declare module 'rdf-ext';
declare module 'rdf-parse';
\ No newline at end of file
export default {
getNodeName(data: any, defaultValue: string = '') {
if (this.isValueAssignedToKey(data, 'http://www.w3.org/ns/shacl#path')) {
return data['http://www.w3.org/ns/shacl#path'][0].value;
return this.getObject(data, 'http://www.w3.org/ns/shacl#path').value;
}
return defaultValue;
},
......@@ -10,17 +10,17 @@ export default {
selectedLanguage: any,
defaultValue: string = ''
) {
if (data['http://www.w3.org/ns/shacl#name'] === undefined) {
if (!this.isValueAssignedToKey(data, 'http://www.w3.org/ns/shacl#name')) {
return defaultValue;
}
for (const localizedName of data['http://www.w3.org/ns/shacl#name']) {
if (localizedName.lang === selectedLanguage) {
return localizedName.value;
for (const localizedName of this.getTriples(data, 'http://www.w3.org/ns/shacl#name')) {
if (localizedName.object.language === selectedLanguage) {
return localizedName.object.value;
}
}
return defaultValue;
},
isValueAssignedToKey(
isDataValueAssignedToKey(
data: any,
nodename: string | null | undefined,
property: string | null = 'value'
......@@ -39,4 +39,63 @@ export default {
}
return true;
},
isValueAssignedToKey(
data: any,
nodename: string | null | undefined,
property: string = 'value'
) {
if (
data === null ||
data === undefined ||
nodename === null ||
nodename === undefined ||
!data.some((entry: any) => entry.predicate[property] === nodename)
) {
return false;
}
return true;
},
getObject(
data: any,
nodename: string | null | undefined
) {
if (
data === null ||
data === undefined ||
nodename === null ||
nodename === undefined) {
return null;
}
return data.find((entry: any) => entry.predicate.value === nodename).object;
},
getTriples(
data: any,
nodename: string | null | undefined
) {
if (
data === null ||
data === undefined ||
nodename === null ||
nodename === undefined) {
return null;
}
return data.filter((entry: any) => entry.predicate.value === nodename);
},
setField(
formData: any,
v: any,
nodeName: string,
value: any,
setFunction: any
) {
if (v.formData[nodeName]) {
v.formData[nodeName].$each[0]['value'].$model = value;
} else {
setFunction(
formData[nodeName][0],
'value',
value
);
}
},
};