Adds TermCreationPanel component to the item submission flow. #573
This commit is contained in:
parent
3e58ae0ce3
commit
b50c407421
|
@ -227,7 +227,7 @@
|
|||
|
||||
<script>
|
||||
import { formHooks } from "../../js/mixins";
|
||||
import {mapActions, mapGetters} from 'vuex';
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
import wpMediaFrames from '../../js/wp-media-frames';
|
||||
|
||||
export default {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
:maxtags="maxtags"
|
||||
v-model="valueComponent"
|
||||
:allow-select-to-create="allowSelectToCreate"
|
||||
:allow-new="allowNew"
|
||||
:allow-new="allowNewFromOptions"
|
||||
:taxonomy-id="taxonomyId"
|
||||
:item-metadatum="itemMetadatum"
|
||||
@showAddNewTerm="openTermCreationModal"
|
||||
|
@ -17,7 +17,7 @@
|
|||
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
|
||||
:is-modal="false"
|
||||
:parent="0"
|
||||
:allow-new="allowNew"
|
||||
:allow-new="allowNewFromOptions"
|
||||
@showAddNewTerm="openTermCreationModal"
|
||||
:taxonomy_id="taxonomyId"
|
||||
:selected="!valueComponent ? [] : valueComponent"
|
||||
|
@ -32,7 +32,7 @@
|
|||
/>
|
||||
|
||||
<div
|
||||
v-if="displayCreateNewTerm"
|
||||
v-if="displayCreateNewTerm && !isTermCreationPanelOpen"
|
||||
class="add-new-term">
|
||||
<a
|
||||
@click="openTermCreationModal"
|
||||
|
@ -45,6 +45,7 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Term creation modal, used on admin for a complete term creation -->
|
||||
<b-modal
|
||||
v-model="isTermCreationModalOpen"
|
||||
trap-focus
|
||||
|
@ -60,6 +61,17 @@
|
|||
@onEditionCanceled="() => $console.log('Edition canceled')"
|
||||
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
|
||||
</b-modal>
|
||||
|
||||
<!-- Term creation panel, used on item submission block for a simpler term creation -->
|
||||
<transition name="filter-item">
|
||||
<term-creation-panel
|
||||
v-if="isTermCreationPanelOpen"
|
||||
:taxonomy-id="taxonomyId"
|
||||
:edit-form="{ id: 'new', name: newTermName ? newTermName : '' }"
|
||||
@onEditionFinished="($event) => addTermToBeCreated($event)"
|
||||
@onEditionCanceled="() => isTermCreationPanelOpen = false"
|
||||
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -79,9 +91,8 @@
|
|||
disabled: false,
|
||||
forcedComponentType: '',
|
||||
maxtags: '',
|
||||
allowNew: false,
|
||||
allowSelectToCreate: false,
|
||||
isTermCreationModalOpen: false,
|
||||
newTermName: ''
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
|
@ -89,8 +100,11 @@
|
|||
taxonomyId: '',
|
||||
taxonomy: '',
|
||||
terms:[],
|
||||
allowNew: false,
|
||||
isAddingNewTermVaue: false
|
||||
isAddingNewTermVaue: false,
|
||||
isTermCreationModalOpen: false,
|
||||
isTermCreationPanelOpen: false,
|
||||
newTermName: '',
|
||||
allowNewFromOptions: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -106,7 +120,10 @@
|
|||
return '';
|
||||
},
|
||||
displayCreateNewTerm() {
|
||||
return this.allowNew;
|
||||
return this.allowNewFromOptions;
|
||||
},
|
||||
isOnItemSubmissionForm() {
|
||||
return !this.itemMetadatum.item || !this.itemMetadatum.item.id;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -120,9 +137,8 @@
|
|||
this.taxonomyId = metadata_type_options.taxonomy_id;
|
||||
this.taxonomy = metadata_type_options.taxonomy;
|
||||
|
||||
if (this.itemMetadatum.item && this.itemMetadatum.item.id && metadata_type_options && metadata_type_options.allow_new_terms && this.itemMetadatum.item)
|
||||
this.allowNew = metadata_type_options.allow_new_terms == 'yes';
|
||||
|
||||
this.allowNewFromOptions = this.allowNew === false ? false : metadata_type_options.allow_new_terms == 'yes';
|
||||
|
||||
this.getTermsId();
|
||||
},
|
||||
methods: {
|
||||
|
@ -164,9 +180,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
addTermToBeCreated(term) {
|
||||
this.isTermCreationPanelOpen = false;
|
||||
this.valueComponent = term.parent ? (term.parent + '>' + term.name) : term.name;
|
||||
},
|
||||
openTermCreationModal(newTerm) {
|
||||
this.newTermName = newTerm.name;
|
||||
this.isTermCreationModalOpen = true;
|
||||
|
||||
if (this.isOnItemSubmissionForm)
|
||||
this.isTermCreationPanelOpen = true;
|
||||
else
|
||||
this.isTermCreationModalOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import ItemSubmission from '../../../item-submission/item-submission.vue';
|
|||
|
||||
// Remaining imports
|
||||
import TainacanFormItem from '../../../admin/components/metadata-types/tainacan-form-item.vue';
|
||||
import TermCreationPanel from '../../../item-submission/components/term-creation-panel.vue';
|
||||
import HelpButton from '../../../admin/components/other/help-button.vue';
|
||||
import store from '../../../admin/js/store/store';
|
||||
import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, StatusHelperPlugin, CommentsStatusHelperPlugin } from '../../../admin/js/admin-utilities';
|
||||
|
@ -81,6 +82,7 @@ export default (element) => {
|
|||
|
||||
/* Others */
|
||||
Vue.component('tainacan-form-item', TainacanFormItem);
|
||||
Vue.component('term-creation-panel', TermCreationPanel);
|
||||
Vue.component('help-button', HelpButton);
|
||||
|
||||
const VueItemSubmission = new Vue({
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
<template>
|
||||
<form
|
||||
autofocus
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
aria-modal
|
||||
id="termEditForm"
|
||||
class="tainacan-form term-creation-panel"
|
||||
@submit.prevent="saveEdition(editForm)">
|
||||
|
||||
<h4>{{ editForm & editForm.id && editForm.id != 'new' ? $i18n.get("title_term_edition") : $i18n.get("title_term_creation") }}</h4>
|
||||
|
||||
<div>
|
||||
<b-loading
|
||||
:is-full-page="false"
|
||||
:active.sync="isLoading" />
|
||||
|
||||
<!-- Name -------------- -->
|
||||
<b-field
|
||||
:addons="false"
|
||||
:type="((formErrors.name !== '' || formErrors.repeated !== '') && (formErrors.name !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
|
||||
:message="formErrors.name ? formErrors.name : formErrors.repeated">
|
||||
<label class="label is-inline">
|
||||
{{ $i18n.get('label_name') }}
|
||||
<span class="required-term-asterisk">*</span>
|
||||
<help-button
|
||||
:title="$i18n.get('label_name')"
|
||||
:message="$i18n.get('info_help_term_name')"/>
|
||||
</label>
|
||||
<b-input
|
||||
:placeholder="$i18n.get('label_term_without_name')"
|
||||
v-model="editForm.name"
|
||||
name="name"
|
||||
@focus="clearErrors({ name: 'name', repeated: 'repeated' })"/>
|
||||
</b-field>
|
||||
|
||||
<!-- Parent -------------- -->
|
||||
<b-field
|
||||
:addons="false"
|
||||
:type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
|
||||
:message="formErrors.parent ? formErrors : formErrors.repeated">
|
||||
<label class="label is-inline">
|
||||
{{ $i18n.get('label_parent_term') }}
|
||||
<b-switch
|
||||
@input="onToggleSwitch()"
|
||||
id="tainacan-checkbox-has-parent"
|
||||
size="is-small"
|
||||
v-model="hasParent" />
|
||||
<help-button
|
||||
:title="$i18n.get('label_parent_term')"
|
||||
:message="$i18n.get('info_help_parent_term')"/>
|
||||
</label>
|
||||
<b-autocomplete
|
||||
id="tainacan-add-parent-field"
|
||||
:placeholder="$i18n.get('instruction_parent_term')"
|
||||
:data="parentTerms"
|
||||
field="name"
|
||||
clearable
|
||||
v-model="parentTermName"
|
||||
@select="onSelectParentTerm($event)"
|
||||
:loading="isFetchingParentTerms"
|
||||
@input="fetchParentTerms"
|
||||
@focus="clearErrors('parent');"
|
||||
:disabled="!hasParent"
|
||||
check-infinite-scroll
|
||||
@infinite-scroll="fetchMoreParentTerms">
|
||||
<template slot-scope="props">
|
||||
<div class="media">
|
||||
<div
|
||||
v-if="props.option.header_image"
|
||||
class="media-left">
|
||||
<img
|
||||
width="28"
|
||||
:src="props.option.header_image">
|
||||
</div>
|
||||
<div class="media-content">
|
||||
{{ props.option.name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="empty">{{ $i18n.get('info_no_parent_term_found') }}</template>
|
||||
</b-autocomplete>
|
||||
</b-field>
|
||||
|
||||
<!-- Submit buttons -------------- -->
|
||||
<div class="field is-grouped form-submit">
|
||||
<div class="control">
|
||||
<button
|
||||
type="button"
|
||||
class="button is-outlined"
|
||||
@click.prevent="cancelEdition()"
|
||||
slot="trigger">
|
||||
{{ $i18n.get('cancel') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
class="button is-success"
|
||||
type="submit">
|
||||
{{ $i18n.get('label_create_and_select') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formHooks } from "../../admin/js/mixins";
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'TermEditionForm',
|
||||
mixins: [ formHooks ],
|
||||
props: {
|
||||
editForm: Object,
|
||||
taxonomyId: ''
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formErrors: {},
|
||||
isFetchingParentTerms: false,
|
||||
parentTerms: [],
|
||||
parentTermName: '',
|
||||
hasParent: false,
|
||||
hasChangedParent: false,
|
||||
initialParentId: undefined,
|
||||
entityName: 'term',
|
||||
isLoading: false,
|
||||
parentTermSearchQuery: '',
|
||||
parentTermSearchOffset: 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.hasParent = this.editForm.parent != undefined && this.editForm.parent > 0;
|
||||
this.initialParentId = this.editForm.parent;
|
||||
|
||||
if (this.hasParent) {
|
||||
this.isFetchingParentTerms = true;
|
||||
this.fetchParentName({ taxonomyId: this.taxonomyId, parentId: this.editForm.parent })
|
||||
.then((parentName) => {
|
||||
this.parentTermName = parentName;
|
||||
this.isFetchingParentTerms = false;
|
||||
this.showCheckboxesWarning = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$console.error(error);
|
||||
this.isFetchingParentTerms = false;
|
||||
this.showCheckboxesWarning = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('taxonomy', [
|
||||
'sendChildTerm',
|
||||
'updateChildTerm',
|
||||
'fetchParentName',
|
||||
'fetchPossibleParentTerms'
|
||||
]),
|
||||
...mapGetters('taxonomy', [
|
||||
'getTerms'
|
||||
]),
|
||||
saveEdition(term) {
|
||||
|
||||
if (term.id === 'new') {
|
||||
this.$emit('onEditionFinished', { name: this.editForm.name, parent: this.editForm.parent });
|
||||
this.editForm = {};
|
||||
this.formErrors = {};
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
cancelEdition() {
|
||||
this.$emit('onEditionCanceled', this.editForm);
|
||||
},
|
||||
clearErrors(attributes) {
|
||||
if(attributes instanceof Object){
|
||||
for(let attribute in attributes){
|
||||
this.formErrors[attribute] = undefined;
|
||||
}
|
||||
} else {
|
||||
this.formErrors[attributes] = undefined;
|
||||
}
|
||||
},
|
||||
fetchParentTerms: _.debounce(function(search) {
|
||||
|
||||
// String update
|
||||
if (search != this.parentTermSearchQuery) {
|
||||
this.parentTermSearchQuery = search;
|
||||
this.parentTerms = [];
|
||||
this.parentTermSearchOffset = 0;
|
||||
}
|
||||
|
||||
// String cleared
|
||||
if (!search.length) {
|
||||
this.parentTermSearchQuery = search;
|
||||
this.parentTerms = [];
|
||||
this.parentTermSearchOffset = 0;
|
||||
}
|
||||
|
||||
// No need to load more
|
||||
if (this.parentTermSearchOffset > 0 && this.parentTerms.length >= this.totalTerms)
|
||||
return
|
||||
|
||||
|
||||
this.isFetchingParentTerms = true;
|
||||
|
||||
this.fetchPossibleParentTerms({
|
||||
taxonomyId: this.taxonomyId,
|
||||
termId: this.editForm.id,
|
||||
search: this.parentTermSearchQuery,
|
||||
offset: this.parentTermSearchOffset })
|
||||
.then((res) => {
|
||||
for (let term of res.parentTerms)
|
||||
this.parentTerms.push(term);
|
||||
|
||||
this.parentTermSearchOffset += 12;
|
||||
this.totalTerms = res.totalTerms;
|
||||
this.isFetchingParentTerms = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$console.error(error);
|
||||
this.isFetchingParentTerms = false;
|
||||
});
|
||||
}, 500),
|
||||
fetchMoreParentTerms: _.debounce(function () {
|
||||
this.fetchParentTerms(this.parentTermSearchQuery)
|
||||
}, 250),
|
||||
onToggleSwitch() {
|
||||
|
||||
if (this.editForm.parent == 0) {
|
||||
this.hasChangedParent = this.hasParent;
|
||||
} else {
|
||||
this.hasChangedParent = !this.hasParent;
|
||||
}
|
||||
|
||||
this.showCheckboxesWarning = true;
|
||||
this.clearErrors('parent');
|
||||
},
|
||||
onSelectParentTerm(selectedParentTerm) {
|
||||
this.hasChangedParent = this.initialParentId != selectedParentTerm.id;
|
||||
this.editForm.parent = selectedParentTerm.id;
|
||||
this.selectedParentTerm = selectedParentTerm;
|
||||
this.parentTermName = selectedParentTerm.name;
|
||||
this.showCheckboxesWarning = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.term-creation-panel {
|
||||
padding-top: 6px;
|
||||
|
||||
h4 {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
&>div {
|
||||
padding: 0 16px 16px;
|
||||
border-left: 1px solid var(--tainacan-input-border-color, #dbdbdb);
|
||||
border-bottom: 1px solid var(--tainacan-input-border-color, #dbdbdb);
|
||||
column-count: 2;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
column-count: 1;
|
||||
}
|
||||
|
||||
.field {
|
||||
break-inside: avoid;
|
||||
}
|
||||
.form-submit {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
column-span: all;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
Loading…
Reference in New Issue