Commit 823f1f6c authored by Marcel Nellesen's avatar Marcel Nellesen
Browse files

Merge branch 'Product/791-uiAdaptions' into 'Sprint/2020-09'

Product/791-uiAdaptions

See merge request coscine/vue/form-generator!22
parents d4ce9631 d986b957
This diff is collapsed.
......@@ -16,11 +16,21 @@
"dev": "vue serve FormGenerator.vue",
"build": "bili",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
"test:unit": "vue-cli-service test:unit",
"precommit": "lint-staged"
},
"lint-staged": {
"{src,test}/**/*.{ts,vue}": [
"prettier --write"
]
},
"files": [
"dist/*"
],
"prettier": {
"semi": true,
"singleQuote": true
},
"dependencies": {
"@coscine/api-connection": "^1.13.0",
"@coscine/app-util": "^1.3.2",
......@@ -50,10 +60,15 @@
"@vue/test-utils": "1.0.0-beta.33",
"bili": "^4.9.1",
"chai": "^4.2.0",
"lint-staged": "^10.1.7",
"prettier": "^2.0.5",
"rollup-plugin-typescript2": "^0.27.0",
"rollup-plugin-vue": "^5.1.6",
"semantic-release": "^17.0.7",
"@hutson/semantic-delivery-gitlab": "^9.1.0",
"tslint": "^6.1.1",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^3.8.3",
"vue-template-compiler": "^2.6.11"
},
......
<template>
<div id="FormGenerator">
<div v-for="(formElement, index) in sortedSHACLDefinition" :key="index">
<InputTextArea
v-if="checkField(formElement,'http://www.w3.org/ns/shacl#order') && checkField(formElement,'http://www.w3.org/ns/shacl#datatype') && formElement['http://www.w3.org/ns/shacl#datatype'][0]['value'] === 'http://www.w3.org/2001/XMLSchema#string' && checkField(formElement,'http://datashapes.org/dash#singleLine') && formElement['http://datashapes.org/dash#singleLine'][0]['value'] === 'false'"
<WrapperInput
:componentDefinition="fieldDefinition(formElement)"
:formFieldInformation="formElement"
:formData="SHACLResponse"
:resourceId="resourceId"
......@@ -10,37 +10,8 @@
:fixedValueMode="fixedValueMode"
:fixedValues="fixedValues"
:disabledMode="disabledMode"
></InputTextArea>
<InputTextField
v-else-if="checkField(formElement,'http://www.w3.org/ns/shacl#order') && checkField(formElement,'http://www.w3.org/ns/shacl#datatype') && formElement['http://www.w3.org/ns/shacl#datatype'][0]['value'] === 'http://www.w3.org/2001/XMLSchema#string'"
:formFieldInformation="formElement"
:formData="SHACLResponse"
:resourceId="resourceId"
:projectId="projectId"
:fixedValueMode="fixedValueMode"
:fixedValues="fixedValues"
:disabledMode="disabledMode"
></InputTextField>
<InputCombobox
v-else-if="checkField(formElement,'http://www.w3.org/ns/shacl#order') && checkField(formElement,'http://www.w3.org/ns/shacl#class')"
:formFieldInformation="formElement"
:formData="SHACLResponse"
:resourceId="resourceId"
:projectId="projectId"
:fixedValueMode="fixedValueMode"
:fixedValues="fixedValues"
:disabledMode="disabledMode"
></InputCombobox>
<InputDatePicker
v-else-if="checkField(formElement,'http://www.w3.org/ns/shacl#order') && checkField(formElement,'http://www.w3.org/ns/shacl#datatype') && formElement['http://www.w3.org/ns/shacl#datatype'][0]['value'] === 'http://www.w3.org/2001/XMLSchema#date'"
:formFieldInformation="formElement"
:formData="SHACLResponse"
:resourceId="resourceId"
:projectId="projectId"
:fixedValueMode="fixedValueMode"
:fixedValues="fixedValues"
:disabledMode="disabledMode"
></InputDatePicker>
:languageLocale="languageLocale"
/>
</div>
</div>
</template>
......@@ -56,14 +27,11 @@ import VueI18n from 'vue-i18n';
import BootstrapVue from 'bootstrap-vue';
import InputCombobox from './components/InputCombobox.vue';
import InputTextField from './components/InputTextField.vue';
import InputTextArea from './components/InputTextArea.vue';
import InputDatePicker from './components/InputDatePicker.vue';
import { LanguageUtil } from '@coscine/app-util';
import FieldReader from "./util/FieldReader";
import FieldReader from './util/FieldReader';
import WrapperInput from './components/WrapperInput.vue';
Vue.use(BootstrapVue);
Vue.use(VueI18n);
......@@ -78,106 +46,134 @@ export default Vue.extend({
i18n,
name: 'FormGenerator',
components: {
InputTextField,
InputTextArea,
InputCombobox,
InputDatePicker,
WrapperInput,
},
props: {
applicationProfileId: {
default: '',
type: String
type: String,
},
SHACLResponse: {
default: function () { return {} },
type: Object
default: () => {
return {};
},
type: Object,
},
projectId: {
default: '00000000-0000-0000-0000-000000000000',
type: String
type: String,
},
resourceId: {
default: '00000000-0000-0000-0000-000000000000',
type: String
type: String,
},
fixedValueMode: {
default: false,
type: Boolean
type: Boolean,
},
disabledMode: {
default: false,
type: Boolean
type: Boolean,
},
fixedValues: {
default: function () { return {} },
type: Object
default: () => {
return {};
},
type: Object,
},
languageLocale: String,
},
data() {
return {
sortedSHACLDefinition: [] as object[],
SHACLDefinition: Object,
languageLocale: LanguageUtil.getLanguage(),
};
},
beforeMount() {
i18n.locale = this.$props.languageLocale;
i18n.locale = this.languageLocale;
this.sortedSHACLDefinition = [];
if(this.applicationProfileId !== '') {
if(this.resourceId !== '00000000-0000-0000-0000-000000000000' && this.resourceId !== '') {
MetadataApi.getApplicationProfileComplete(
this.resourceId,
this.applicationProfileId,
(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++)
{
if (this.checkField((this.SHACLDefinition as any)[keys[j]],"http://www.w3.org/ns/shacl#order") &&
(this.SHACLDefinition as any)[keys[j]]["http://www.w3.org/ns/shacl#order"][0]["value"].toString() === "" + i )
{
let tmp = (this.SHACLDefinition as any)[keys[j]];
tmp['idForFixedValues'] = keys[j]
this.sortedSHACLDefinition.push(tmp);
}
}
}
if (this.applicationProfileId !== '') {
if (
this.resourceId !== '00000000-0000-0000-0000-000000000000' &&
this.resourceId !== ''
) {
MetadataApi.getApplicationProfileComplete(
this.resourceId,
this.applicationProfileId,
(response: any) => {
this.handleApplicationProfiles(response);
},
defaultOnCatch,
);
defaultOnCatch
);
} else {
MetadataApi.getApplicationProfile(
this.projectId,
this.applicationProfileId,
(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++)
{
if (this.checkField((this.SHACLDefinition as any)[keys[j]],"http://www.w3.org/ns/shacl#order") &&
(this.SHACLDefinition as any)[keys[j]]["http://www.w3.org/ns/shacl#order"][0]["value"].toString() === "" + i )
{
let tmp = (this.SHACLDefinition as any)[keys[j]];
tmp['idForFixedValues'] = keys[j];
this.sortedSHACLDefinition.push(tmp);
}
}
}
this.handleApplicationProfiles(response);
},
defaultOnCatch,
defaultOnCatch
);
}
}
},
methods: {
checkField(data:any,nodename:string,property: string = 'value'){
return FieldReader.isValueAssignedToKey(data,nodename,property);
checkField(data: any, nodename: string, property: string = 'value') {
return FieldReader.isValueAssignedToKey(data, nodename, property);
},
}
fieldDefinition(formElement: any) {
if (this.checkField(formElement, 'http://www.w3.org/ns/shacl#order')) {
if (
this.checkField(formElement, 'http://www.w3.org/ns/shacl#datatype')
) {
let datatype = formElement['http://www.w3.org/ns/shacl#datatype'][0];
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][
'value'
] === 'false'
) {
return 'InputTextArea';
} else {
return 'InputTextField';
}
} else if (
datatype['value'] === 'http://www.w3.org/2001/XMLSchema#date'
) {
return 'InputDatePicker';
}
} else {
if (
this.checkField(formElement, 'http://www.w3.org/ns/shacl#class')
) {
return 'InputCombobox';
}
}
}
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);
}
}
}
},
},
});
</script>
......@@ -186,25 +182,25 @@ export default Vue.extend({
float: right;
}
#FormGenerator .form-group.mandatory .col-form-label:after {
content: " *";
content: ' *';
color: #a70619;
}
#FormGenerator .col-form-label {
font-weight: bold;
}
#FormGenerator .lockButton {
height: calc(1.4em + .75rem + 2px);
height: calc(1.4em + 0.75rem + 2px);
margin: 0px !important;
min-width: 60px !important;
width: 60px !important;
max-width: 60px !important;;
max-width: 60px !important;
}
#FormGenerator .visibilityButton {
height: calc(1.4em + .75rem + 2px);
height: calc(1.4em + 0.75rem + 2px);
margin: 0px !important;
min-width: 60px !important;
width: 60px !important;
max-width: 60px !important;;
max-width: 60px !important;
}
#FormGenerator .metadata .material-design-icon__svg {
margin-top: -0.1em;
......
<template>
<div class="InputComboxbox">
<b-form-group
v-bind:class="{
mandatory: (checkField(this.formFieldInformation,'http://www.w3.org/ns/shacl#minCount') &&
this.formFieldInformation['http://www.w3.org/ns/shacl#minCount'][0]['value'] >= 1),
invisible: (!fixedValueMode && checkField(this.formFieldInformation,'https://purl.org/coscine/invisible') &&
this.formFieldInformation['https://purl.org/coscine/invisible'][0]['value'] === '1') }"
:label-for="cssid"
label-cols-sm="3"
label-align-sm="right"
:label="label"
label-class="application-profile-label"
>
<b-row>
<b-col>
<multiselect
v-if="checkField(formFieldInformation,'http://www.w3.org/ns/shacl#maxCount') && formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0]['value'] === 1"
:id="cssid"
:options="selectableOptions"
v-model="selectedOptions"
:multiple="false"
:hide-selected="true"
label="name"
track-by="name"
:placeholder="$t('multiselectPlaceholder')"
:required="checkField(formFieldInformation,'http://www.w3.org/ns/shacl#minCount') && formFieldInformation['http://www.w3.org/ns/shacl#minCount'][0]['value'] >= 1"
:disabled="disabledMode || locked"
@input="input"
@change="input"
></multiselect>
<multiselect
v-else
:id="cssId"
:options="selectableOptions"
v-model="selectedOptions"
:multiple="true"
:hide-selected="true"
label="name"
track-by="name"
:placeholder="$t('multiselectPlaceholder')"
:max="this.formFieldInformation['http://www.w3.org/ns/shacl#maxCount'] !== undefined && this.formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0] !== undefined && formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0]['value'] !== undefined ? parseInt(formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0]['value']) : maxNumberOfSelectedObjects"
:disabled="disabledMode || locked"
:required="checkField(formFieldInformation,'http://www.w3.org/ns/shacl#minCount') && formFieldInformation['http://www.w3.org/ns/shacl#minCount'][0]['value'] >= 1"
@input="input"
@change="input"
></multiselect>
</b-col>
<b-col v-if="fixedValueMode" class="lock-colum col-sm-2">
<b-button-group>
<b-button :disabled="disabledMode || !checkField(formData,nodeName) || (checkField(formData,nodeName) && formData[nodeName][0]['value'] ==='') || (this.isMandatoryField() && this.invisible)" class="lockButton" variant="outline-secondary" @click.prevent="changeLockable()">
<LockIcon v-if="locked"/>
<LockOpenIcon v-else />
</b-button>
<b-button v-b-tooltip.hover.bottom="$t('invisibilityInfo')" :disabled="disabledMode || !fieldCanBeInvisible()" class="visibilityButton" variant="outline-secondary" @click.prevent="changeVisibility()">
<Invisible v-if="invisible"/>
<Visible v-else />
</b-button>
</b-button-group>
</b-col>
</b-row>
</b-form-group>
</div>
<multiselect
:id="cssId"
:options="selectableOptions"
v-model="selectedOptions"
:multiple="!noMaxMode"
label="name"
track-by="name"
:placeholder="$t('multiselectPlaceholder')"
:max="getMax()"
:required="required"
:disabled="disabledMode || locked"
@input="input"
@change="input"
/>
</template>
<script lang="ts">
import Vue from 'vue';
import LockIcon from 'vue-material-design-icons/Lock.vue';
import LockOpenIcon from 'vue-material-design-icons/LockOpen.vue';
import Visible from 'vue-material-design-icons/Eye.vue';
import Invisible from 'vue-material-design-icons/EyeOff.vue';
import Multiselect from 'vue-multiselect';
import 'vue-multiselect/dist/vue-multiselect.min.css';
import { LanguageUtil } from '@coscine/app-util';
import { MetadataApi, defaultOnCatch } from '@coscine/api-connection';
import FieldReader from '../util/FieldReader';
import locales from '../locale/locales';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en', // set locale
messages: locales, // set locale messages
silentFallbackWarn: true,
});
export default Vue.extend({
i18n,
name: 'InputCombobox',
beforeMount() {
i18n.locale = LanguageUtil.getLanguage();
this.label = FieldReader.getLocalizedField(
this.formFieldInformation,
this.languageCode,
);
this.nodeName = FieldReader.getNodeName(this.formFieldInformation);
this.cssId = this.nodeName.substr(this.nodeName.lastIndexOf('\/') + 1);
if (this.cssId.indexOf('#') !== -1) {
this.cssId = this.cssId.substr(this.cssId.indexOf('#') + 1);
}
// if a fixed value was sent with the application profile take this
if (this.checkField(this.formFieldInformation,'https://purl.org/coscine/fixedValue')) {
this.$set(this.formData,this.nodeName, [{'value': this.formFieldInformation['https://purl.org/coscine/fixedValue'][0].value}]);
this.locked = true;
}
// if a fixed values was given directly take that
if (this.checkField(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/fixedValue')) {
this.$set(this.formData,this.nodeName, [{'value': this.fixedValues[this.formFieldInformation['idForFixedValues']]['https://purl.org/coscine/fixedValue'][0].value}]);
this.locked = true;
}
if (this.checkField(this.formFieldInformation['idForFixedValues'],'https://purl.org/coscine/invisible')) {
this.invisible = this.formFieldInformation['https://purl.org/coscine/invisible'][0].value === '1';
}
if (this.checkField(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/invisible')) {
this.invisible = this.fixedValues[this.formFieldInformation['idForFixedValues']]['https://purl.org/coscine/invisible'][0].value === '1';
}
if (!this.checkField(this.formData,this.nodeName)){
// if formdata is still emty take the default value from the ap
if (this.checkField(this.formFieldInformation,'http://www.w3.org/ns/shacl#defaultValue')) {
this.$set(this.formData,this.nodeName, [{'value': this.formFieldInformation['http://www.w3.org/ns/shacl#defaultValue'][0].value}]);
}
// take the default value from the alt provided values of the ap
if (this.checkField(this.formFieldInformation,'https://purl.org/coscine/defaultValue')) {
this.$set(this.formData,this.nodeName, [{'value': this.formFieldInformation['https://purl.org/coscine/defaultValue'][0].value}]);
}
// take the default value from the provided values
if (this.checkField(this.fixedValues[this.formFieldInformation['idForFixedValues']],'https://purl.org/coscine/defaultValue')) {
this.$set(this.formData,this.nodeName, [{'value': this.fixedValues[this.formFieldInformation['idForFixedValues']]['https://purl.org/coscine/defaultValue'][0].value}]);
}
}
// if formdata is still empty intialize it with an empty value
if (!this.checkField(this.formData,this.nodeName)){
this.$set(this.formData,this.nodeName, [{'value': ''}]);
}
// take whatever is defined in formdata now and try to get the content if we are not in fixed value mode
this.replacePlaceholder();
this.noMaxMode =
this.checkField(
this.formFieldInformation,
'http://www.w3.org/ns/shacl#maxCount'
) &&
parseInt(this.formFieldInformation['http://www.w3.org/ns/shacl#maxCount'][0][
'value'
]) === 1;
// set the datatype
this.$set(this.formData[this.nodeName][0],'type', 'uri');
this.$set(this.formData[this.nodeName][0], 'type', 'uri');
if (this.fixedValueMode) {
this.updateFixedValues();
......@@ -155,51 +44,69 @@ export default Vue.extend({
},
mounted() {
MetadataApi.getVocabulary(
this.projectId,
this.formFieldInformation['http://www.w3.org/ns/shacl#class'][0].value,
(response: any) => {
if (Array.isArray(response.data[this.languageCode]) && response.data[this.languageCode].length === 0) {
if (Array.isArray(response.data.en) && response.data.en.length !== 0) {
this.selectableOptions = response.data.en;
} else {
this.selectableOptions = response.data.de;
}
this.projectId,
this.formFieldInformation['http://www.w3.org/ns/shacl#class'][0].value,
(response: any) => {
if (
Array.isArray(response.data[this.languageCode]) &&
response.data[this.languageCode].length === 0
) {
if (
Array.isArray(response.data.en) &&
response.data.en.length !== 0
) {
this.selectableOptions = response.data.en;
} else {
this.selectableOptions = response.data[this.languageCode];
this.selectableOptions = response.data.de;
}
this.loadData();
},
defaultOnCatch,
);
if (this.fixedValueMode) {
this.updateFixedValues();
}
} else {
this.selectableOptions = response.data[this.languageCode];
}
this.loadData();
},
defaultOnCatch
);
if (this.fixedValueMode) {
this.updateFixedValues();
}
},
data() {
return {
label: 'Label:',
nodeName: '',
cssId: 'cssId',
noMaxMode: true,
selectableOptions: [] as object[],
selectedOptions: [] as object[],
languageCode: LanguageUtil.getLanguage(),
listLanguageCode: LanguageUtil.getLanguage(),
maxNumberOfSelectedObjects: 10000,
locked: false,
invisible: false,
};
},
methods: {
replacePlaceholder(){
getMax() {
if (!this.noMaxMode) {
return 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][
'value'
] !== undefined
? parseInt(
this.formFieldInformation[
'http://www.w3.org/ns/shacl#maxCount'
][0]['value']
)
: this.maxNumberOfSelectedObjects;
}
return false;
},
input() {
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' });
}
} else {
array.push({value: (this.selectedOptions as any).value , type: 'uri'});
array.push({ value: (this.selectedOptions as any).value, type: 'uri' });
}
this.$set(this.formData, this.nodeName, array);
this.updateFixedValues();
......@@ -207,81 +114,36 @@ export default Vue.extend({
loadData() {
const selectedData = this.formData[this.nodeName];
</