Commit 73a0bff7 authored by Jean Rabreau's avatar Jean Rabreau
Browse files

馃毀 analyse item and targeted template compliance

parent 9198fbf5
......@@ -145,7 +145,8 @@ const Item = {
itemId: state => state.current.id,
templateId: state => state.current.set.templateId,
projectId: state => state.current.set.projectId,
canEdit: (state) => state.current.canEdit,
canEdit: state => state.current.canEdit,
metadata: state => state.current.metadata,
files: state => state.current.mediaFiles,
fileView: state => state.current.viewer.fileId
? state.current.mediaFiles.find(f => f.id === state.current.viewer.fileId)
......
import authority from '@/assets/authAxios'
import i18n from '@/plugins/vue-i18n'
/**
* @typedef {Object} UsfFieldOption
* @property {string} id
* @property {string} label
* @property {string} owner
* @property {string} value
*/
/**
* @typedef {Object} UsfField
* @property {string} id -
......@@ -10,6 +20,10 @@ import i18n from '@/plugins/vue-i18n'
* @property {boolean} visible -
* @property {string} parentId - parent id or "root"
* @property {UsfField[]} [fields] - layout children
* @property {UsfFieldOption[]} [options]
* @property {boolean} [repeatable] -
* @property {boolean} [maxRepeat] -
* @property {boolean} [multiple] -
* @property {boolean} [required] -
* @property {boolean} [vertical] - row direction
* @property {boolean} [width] - col width
......
......@@ -12,27 +12,16 @@
:load-children="addSets"
>
<template v-slot:label="{item}">
<p
v-if="item.id === 'next'"
@click="addProjects"
>
{{ $t('item.copy.projectsLoad')}}
</p>
<p
v-else-if="item.level"
@click="analyseForCopy(item.templateId)"
>
<v-icon
color="secondary"
left
>
mdi-content-copy
</v-icon>
<p v-if="item.level" @click="analyseForCopy(item.id, item.templateId)">
<v-icon left color="secondary">
mdi-content-copy
</v-icon>
{{ item.title }}
</p>
<p
v-else
>
<p v-else-if="item.id === 'next'" @click="addProjects">
{{ $t('item.copy.projectsLoad')}}
</p>
<p v-else>
{{ item.title }}
</p>
</template>
......@@ -66,6 +55,31 @@
import TextHelpersMixin from '@/mixins/TextHelpersMixin'
import {mapActions, mapGetters, mapState} from 'vuex'
/**
* @typedef {object} Analysis
* @property {string} setId - targeted set id
* @property {boolean} displayed - control modal display
* @property {AnalysisResult | null} result - result details
*/
/**
* @typedef {object} AnalysisResult
* @property {ResultDetail[]} required - required fields that found no item value
* @property {ResultDetail[]} option - fields that do no recognize item value as valid option
* @property {ResultDetail[]} tooManyValues - fields for which item value number exceed its limit
* @property {ResultDetail[]} ignoredFields - fields for which repeatable, multiple or isOption itemData mismatch
* @property {ResultDetail[]} missing - remaining item fields that have found no match in target
* @property {ResultDetail[]} fields - item metadata to be copied
*/
/**
* @typedef {Object} ResultDetail
* @property {UsfField} field
* @property {string[]} [unknownOptions]
* @property {string[]} [itemValue]
*/
export default {
name: "ItemCopy",
mixins: [
......@@ -79,13 +93,21 @@ export default {
},
data() {
return {
/**
* @type Analysis
*/
analysis: {
setId: '',
displayed: false,
result: null
},
setLoaded: false,
projectsTree: [],
openProjects: []
}
},
computed: {
...mapGetters('item', ['projectId', 'templateId']),
...mapGetters('item', ['metadata', 'projectId', 'templateId']),
...mapState('set', ['projectSets']),
...mapGetters('template', ['inputFields']),
...mapGetters('project',
......@@ -99,8 +121,107 @@ export default {
...mapActions('project', ['loadProject', 'retrieveProjects']),
...mapActions('set', ['loadProjectSets']),
...mapActions('template', ['loadTemplate', 'loadProjectTemplates']),
async analyseForCopy(targetedTemplateId) {
async analyseForCopy(targetedSetId, targetedTemplateId) {
await this.loadTemplate(targetedTemplateId)
this.analysis.result = this.inputFields.reduce((result, field) => {
const itemFields = result.missing
const itemDataIndex = itemFields.findIndex(
f => f.name === field.name)
if (itemDataIndex === -1) {
if (field.required) {
result.required.push(field)
}
} else {
const itemData = itemFields[itemDataIndex]
if (itemData.repeatable === !!field.repeatable
&& itemData.multiple === !!field.multiple
&& itemData.isOption === !!field.options
) {
let error = false
const itemValue = Array.isArray(itemData) ? itemData.value : [itemData.value]
if (itemData.isOption) {
let unknownOptions
if (field.repeatable && field.multiple) {
unknownOptions = itemValue.reduce((options, valueSet) => {
return [
...options,
...valueSet.filter(v => field.options.every(o => o.value !== v))
]
}, [])
} else {
unknownOptions = itemValue.filter(v => field.options.every(o => o.value !== v))
}
if (unknownOptions.length) {
error = true
result.option.push({field, unknownOptions})
}
}
if (field.repeatable && itemValue.length > field.maxRepeat + 1) {
error = true
result.tooManyValues.push({field, itemValue})
}
result.missing.splice(itemDataIndex, 1)
if (!error) {
result.fields.push(itemData)
}
} else {
result.ignoredFields.push({
field
})
}
}
// } else if (field.options) {
// const itemValue = itemFields[itemValueIndex].value
// if (!Array.isArray(itemValue)) {
// if (field.options.every(o => o.value !== itemValue)) {
// result.option.push({...field, itemValue: [itemValue]})
// } else {
// const [matchingField] = result.missing.splice(itemValueIndex, 1)
//
// let value = itemValue
// // single value to comply to repeatable or multiple field
// if (field.repeatable) {
// value = [value]
// matchingField.repeatable = true
// }
// if (field.multiple) {
// value = [value]
// matchingField.multiple = true
// }
// result.fields.push({...matchingField, value, isOption: true})
// }
// } else if (field.multiple) {
// if (field.repeatable) {
// const valuesMatch = itemValue.every(
// value => Array.isArray(value)
// && value.every(v => field.options.every(o => o.value === v))
// )
// } else {
//
// }
// } else if (field.repeatable) {
// const unknownOptions = itemValue.filter(v => field.options.every(o => o.value !== v))
// if (unknownOptions.length) {
// result.option.push({...field, unknownOptions})
// } else {
// const [matchingField] = result.missing.splice(itemValueIndex, 1)
//
// }
// } else {
// result.tooManyValues.push({...field, itemValue})
// }
// }
return result
}, {
required: [],
option: [],
tooManyValues: [],
ignoredFields: [],
missing: this.metadata.map(m => ({...m})),// remaining item fields have found no match in target
fields: [] // received item metadata to be posted
})
this.analysis.targetedSet = targetedSetId
this.analysis.displayed = true
},
async duplicate() {
await this.itemDuplicate()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment