Removes terms-list-linear and moves its logic back to terms-list-hierarchical.
This commit is contained in:
parent
83772fd023
commit
d70ec0f38b
|
@ -24,7 +24,9 @@
|
||||||
v-for="(column, columnIndex) in termColumns"
|
v-for="(column, columnIndex) in termColumns"
|
||||||
class="tainacan-hierarchical-list-column"
|
class="tainacan-hierarchical-list-column"
|
||||||
:key="column.name + '-' + columnIndex">
|
:key="column.name + '-' + columnIndex">
|
||||||
<div class="column-header">
|
<div
|
||||||
|
v-if="!searchString.length"
|
||||||
|
class="column-header">
|
||||||
<p class="column-name">
|
<p class="column-name">
|
||||||
<span>{{ column.name ? $i18n.getWithVariables('info_children_of_%s', [ column.name ]) : $i18n.get('label_root_terms') }}</span>
|
<span>{{ column.name ? $i18n.getWithVariables('info_children_of_%s', [ column.name ]) : $i18n.get('label_root_terms') }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
@ -77,7 +79,17 @@
|
||||||
:value="term.id"
|
:value="term.id"
|
||||||
type="checkbox">
|
type="checkbox">
|
||||||
<span class="check" />
|
<span class="check" />
|
||||||
<span class="control-label">{{ term.name }}</span>
|
<span class="control-label">
|
||||||
|
<span
|
||||||
|
v-if="isHierarchical && !searchString.length"
|
||||||
|
class="checkbox-name-text">
|
||||||
|
{{ term.name }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="checkbox-name-text"
|
||||||
|
v-html="renderTermHierarchyLabel(term)" />
|
||||||
|
</span>
|
||||||
<div class="actions-container">
|
<div class="actions-container">
|
||||||
<button
|
<button
|
||||||
v-if="currentUserCanEditTaxonomy"
|
v-if="currentUserCanEditTaxonomy"
|
||||||
|
@ -112,6 +124,7 @@
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<button
|
<button
|
||||||
|
v-if="isHierarchical && !searchString.length"
|
||||||
class="load-children-button"
|
class="load-children-button"
|
||||||
type="button"
|
type="button"
|
||||||
@click="fetchTerms(term, columnIndex)">
|
@click="fetchTerms(term, columnIndex)">
|
||||||
|
@ -212,19 +225,29 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapActions } from 'vuex';
|
||||||
|
import TermDeletionDialog from '../other/term-deletion-dialog.vue';
|
||||||
|
import TermParentSelectionDialog from '../other/term-parent-selection-dialog.vue';
|
||||||
import { tainacan as axios } from '../../js/axios';
|
import { tainacan as axios } from '../../js/axios';
|
||||||
import { termsListMixin } from '../../js/terms-list-mixin';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TermsListHierarchical',
|
name: 'TermsListHierarchical',
|
||||||
mixins: [
|
props: {
|
||||||
termsListMixin
|
taxonomyId: Number,
|
||||||
],
|
currentUserCanEditTaxonomy: Boolean,
|
||||||
|
selected: Array,
|
||||||
|
selectedColumnIndex: Number,
|
||||||
|
searchString: String
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
termColumns: [],
|
termColumns: [],
|
||||||
isColumnLoading: false,
|
isColumnLoading: false,
|
||||||
maxTermsPerColumn: 100,
|
maxTermsPerColumn: 100,
|
||||||
|
isHierarchical: true,
|
||||||
|
totalRemaining: {},
|
||||||
|
isEditingTerm: false,
|
||||||
|
editTerm: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -237,16 +260,56 @@ export default {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
searchString: {
|
||||||
|
handler(newValue, oldValue) {
|
||||||
|
if (newValue != oldValue) {
|
||||||
|
this.resetTermsListUI();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.fetchTerms();
|
this.fetchTerms();
|
||||||
|
this.$parent.$on('deleteSelectedTerms', this.deleteSelectedTerms);
|
||||||
|
this.$parent.$on('updateSelectedTermsParent', this.updateSelectedTermsParent);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.$parent.$off('deleteSelectedTerms', this.deleteSelectedTerms);
|
||||||
|
this.$parent.$off('updateSelectedTermsParent', this.updateSelectedTermsParent);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions('taxonomy', [
|
||||||
|
'updateTerm',
|
||||||
|
'deleteTerm',
|
||||||
|
'deleteTerms',
|
||||||
|
'changeTermsParent'
|
||||||
|
]),
|
||||||
|
renderTermHierarchyLabel(term) {
|
||||||
|
if ( term.hierarchy_path )
|
||||||
|
return '<span style="color: var(--tainacan-info-color);">' + term.hierarchy_path.replace(/>/g, ' <span class="hierarchy-separator"> > </span> ') + '</span>' + term.name;
|
||||||
|
|
||||||
|
return term.name;
|
||||||
|
},
|
||||||
|
isTermSelected(termId) {
|
||||||
|
return this.selected.findIndex(aSelectedTerm => aSelectedTerm.id == termId) >= 0;
|
||||||
|
},
|
||||||
|
getTermIdAsNumber(termId) {
|
||||||
|
return isNaN(Number(termId)) ? termId : Number(termId)
|
||||||
|
},
|
||||||
|
onEditTerm(term) {
|
||||||
|
this.editTerm = term;
|
||||||
|
this.isEditingTerm = true;
|
||||||
|
},
|
||||||
shouldShowMoreButton(columnIndex) {
|
shouldShowMoreButton(columnIndex) {
|
||||||
return this.totalRemaining[columnIndex].remaining === true || (this.termColumns[columnIndex].children.length < this.totalRemaining[columnIndex].remaining);
|
return this.totalRemaining[columnIndex].remaining === true || (this.termColumns[columnIndex].children.length < this.totalRemaining[columnIndex].remaining);
|
||||||
},
|
},
|
||||||
removeLevelsAfterIndex(parentColumnIndex){
|
removeLevelsAfterIndex(parentColumnIndex){
|
||||||
if (parentColumnIndex != undefined)
|
if (parentColumnIndex != undefined)
|
||||||
this.termColumns.length = parentColumnIndex + 1;
|
this.termColumns.length = parentColumnIndex + 1;
|
||||||
|
else
|
||||||
|
this.termColumns.length = 0;
|
||||||
},
|
},
|
||||||
removeLevelsAfterTerm(term) {
|
removeLevelsAfterTerm(term) {
|
||||||
for (let i = 0; i < this.termColumns.length; i++) {
|
for (let i = 0; i < this.termColumns.length; i++) {
|
||||||
|
@ -318,7 +381,15 @@ export default {
|
||||||
this.isColumnLoading = true;
|
this.isColumnLoading = true;
|
||||||
|
|
||||||
const parentId = parentTerm ? parentTerm.id : 0;
|
const parentId = parentTerm ? parentTerm.id : 0;
|
||||||
const route = `/taxonomy/${this.taxonomyId}/terms?order=asc&parent=${parentId}&number=${this.maxTermsPerColumn}&offset=0&hideempty=0`;
|
|
||||||
|
let route = `/taxonomy/${this.taxonomyId}/terms?order=asc&number=${this.maxTermsPerColumn}&offset=0&hideempty=0`;
|
||||||
|
|
||||||
|
if ( this.isHierarchical && !this.searchString.length)
|
||||||
|
route += '&parent=' + parentId;
|
||||||
|
|
||||||
|
if ( this.searchString.length )
|
||||||
|
route += '&searchterm=' + this.searchString;
|
||||||
|
|
||||||
axios.get(route)
|
axios.get(route)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
|
||||||
|
@ -327,7 +398,7 @@ export default {
|
||||||
remaining: res.headers['x-wp-total'],
|
remaining: res.headers['x-wp-total'],
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.removeLevelsAfterIndex(parentColumnIndex);
|
this.removeLevelsAfterIndex(parentColumnIndex);
|
||||||
this.createColumn(res, parentColumnIndex, parentTerm ? parentTerm.name : null, parentId);
|
this.createColumn(res, parentColumnIndex, parentTerm ? parentTerm.name : null, parentId);
|
||||||
|
|
||||||
|
@ -347,7 +418,14 @@ export default {
|
||||||
|
|
||||||
this.isColumnLoading = true;
|
this.isColumnLoading = true;
|
||||||
|
|
||||||
const route = `/taxonomy/${this.taxonomyId}/terms/?order=asc&parent=${parentId}&number=${this.maxTermsPerColumn}&offset=${offset}&hideempty=`;
|
let route = `/taxonomy/${this.taxonomyId}/terms/?order=asc&number=${this.maxTermsPerColumn}&offset=${offset}&hideempty=`;
|
||||||
|
|
||||||
|
if ( this.isHierarchical && !this.searchString.length)
|
||||||
|
route += '&parent=' + parentId;
|
||||||
|
|
||||||
|
if (this.searchString.length)
|
||||||
|
route += '&searchterm=' + this.searchString;
|
||||||
|
|
||||||
axios.get(route)
|
axios.get(route)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
|
||||||
|
@ -372,6 +450,108 @@ export default {
|
||||||
const newIndex = this.selectedColumnIndex != index ? index : -1;
|
const newIndex = this.selectedColumnIndex != index ? index : -1;
|
||||||
this.$emit('onUpdateSelectedColumnIndex', { index: newIndex, object: this.termColumns[newIndex] ? this.termColumns[newIndex] : null });
|
this.$emit('onUpdateSelectedColumnIndex', { index: newIndex, object: this.termColumns[newIndex] ? this.termColumns[newIndex] : null });
|
||||||
},
|
},
|
||||||
|
removeTerm(term) {
|
||||||
|
|
||||||
|
this.$buefy.modal.open({
|
||||||
|
parent: this,
|
||||||
|
component: TermDeletionDialog,
|
||||||
|
props: {
|
||||||
|
message: term.total_children && term.total_children != '0' ? this.$i18n.get('info_warning_term_with_child') : this.$i18n.get('info_warning_selected_term_delete'),
|
||||||
|
showDescendantsDeleteButton: term.total_children && term.total_children != '0',
|
||||||
|
amountOfTerms: 1,
|
||||||
|
onConfirm: (typeOfDelete) => {
|
||||||
|
|
||||||
|
// If all checks passed, term can be deleted
|
||||||
|
if ( typeOfDelete == 'descendants' ) {
|
||||||
|
this.deleteTerm({
|
||||||
|
taxonomyId: this.taxonomyId,
|
||||||
|
termId: term.id,
|
||||||
|
parent: term.parent,
|
||||||
|
deleteChildTerms: true })
|
||||||
|
.then(() => {
|
||||||
|
this.onTermRemovalFinished(term);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.$console.log(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.deleteTerm({
|
||||||
|
taxonomyId: this.taxonomyId,
|
||||||
|
termId: term.id,
|
||||||
|
parent: term.parent })
|
||||||
|
.then(() => {
|
||||||
|
this.onTermRemovalFinished(term);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.$console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trapFocus: true,
|
||||||
|
customClass: 'tainacan-modal',
|
||||||
|
closeButtonAriaLabel: this.$i18n.get('close')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteSelectedTerms() {
|
||||||
|
|
||||||
|
this.$buefy.modal.open({
|
||||||
|
parent: this,
|
||||||
|
component: TermDeletionDialog,
|
||||||
|
props: {
|
||||||
|
message: this.$i18n.get('info_warning_some_terms_with_child'),
|
||||||
|
showDescendantsDeleteButton: true,
|
||||||
|
amountOfTerms: this.amountOfTermsSelected,
|
||||||
|
onConfirm: (typeOfDelete) => {
|
||||||
|
// If all checks passed, term can be deleted
|
||||||
|
this.deleteTerms({
|
||||||
|
taxonomyId: this.taxonomyId,
|
||||||
|
terms: this.selectedColumnIndex >= 0 ? [] : this.selected.map((aTerm) => aTerm.id),
|
||||||
|
parent: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : undefined,
|
||||||
|
deleteChildTerms: typeOfDelete === 'descendants'
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.resetTermsListUI();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.$console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trapFocus: true,
|
||||||
|
customClass: 'tainacan-modal',
|
||||||
|
closeButtonAriaLabel: this.$i18n.get('close')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateSelectedTermsParent() {
|
||||||
|
|
||||||
|
this.$buefy.modal.open({
|
||||||
|
parent: this,
|
||||||
|
component: TermParentSelectionDialog,
|
||||||
|
props: {
|
||||||
|
amountOfTerms: this.amountOfTermsSelected,
|
||||||
|
excludeTree: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : this.selected.map((aTerm) => aTerm.id),
|
||||||
|
taxonomyId: this.taxonomyId,
|
||||||
|
onConfirm: (selectedParentTerm) => {
|
||||||
|
this.changeTermsParent({
|
||||||
|
taxonomyId: this.taxonomyId,
|
||||||
|
terms: this.selectedColumnIndex >= 0 ? [] : this.selected.map((aTerm) => aTerm.id),
|
||||||
|
parent: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : undefined,
|
||||||
|
newParentTerm: selectedParentTerm
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.resetTermsListUI();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.$console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trapFocus: true,
|
||||||
|
customClass: 'tainacan-modal',
|
||||||
|
closeButtonAriaLabel: this.$i18n.get('close')
|
||||||
|
});
|
||||||
|
},
|
||||||
updateSelectedTerms(selectedTerm) {
|
updateSelectedTerms(selectedTerm) {
|
||||||
this.$emit('onUpdateSelectedColumnIndex', { index: -1, object: null });
|
this.$emit('onUpdateSelectedColumnIndex', { index: -1, object: null });
|
||||||
|
|
||||||
|
@ -517,19 +697,15 @@ export default {
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
margin-left: 0px !important;
|
margin-left: 0px !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
-webkit-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
|
||||||
|
|
||||||
/deep/ .b-checkbox, /deep/ .b-radio {
|
/deep/ .b-checkbox, /deep/ .b-radio {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
min-height: 1.5em;
|
min-height: 1.875em;
|
||||||
margin-left: 0.7em;
|
margin-left: 0.7em;
|
||||||
margin-bottom: 0px !important;
|
margin-bottom: 0px !important;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
-webkit-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
|
||||||
|
|
||||||
.control-label {
|
.control-label {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
@ -538,7 +714,10 @@ export default {
|
||||||
padding-bottom: 0.125em;
|
padding-bottom: 0.125em;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
input:disabled+.check {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.control-label {
|
.control-label {
|
||||||
padding-top: 0.8125em;
|
padding-top: 0.8125em;
|
||||||
|
|
|
@ -1,434 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="tainacan-checkbox-list-container">
|
|
||||||
<a
|
|
||||||
v-if="searchResultsOffset"
|
|
||||||
role="button"
|
|
||||||
class="tainacan-checkbox-list-page-changer"
|
|
||||||
@click="previousSearchPage">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="tainacan-icon tainacan-icon-previous"/>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<ul class="tainacan-modal-checkbox-list-body">
|
|
||||||
<template v-if="searchResults.length">
|
|
||||||
<li
|
|
||||||
class="tainacan-li-checkbox-list"
|
|
||||||
v-for="(term, index) in searchResults"
|
|
||||||
:key="index">
|
|
||||||
<label class="b-checkbox checkbox">
|
|
||||||
<input
|
|
||||||
@input="updateSelectedTerms(term)"
|
|
||||||
:checked="isTermSelected(term.id)"
|
|
||||||
:value="getTermIdAsNumber(term.id)"
|
|
||||||
type="checkbox">
|
|
||||||
<span class="check" />
|
|
||||||
<span class="control-label">
|
|
||||||
<span
|
|
||||||
class="checkbox-name-text"
|
|
||||||
v-html="renderTermHierarchyLabel(term)" />
|
|
||||||
</span>
|
|
||||||
<div class="actions-container">
|
|
||||||
<button
|
|
||||||
v-if="currentUserCanEditTaxonomy"
|
|
||||||
type="button"
|
|
||||||
@click.prevent="onEditTerm(term)">
|
|
||||||
<span
|
|
||||||
v-tooltip="{
|
|
||||||
content: $i18n.get('edit'),
|
|
||||||
autoHide: true,
|
|
||||||
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
|
|
||||||
placement: 'bottom'
|
|
||||||
}"
|
|
||||||
class="icon">
|
|
||||||
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-edit"/>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
v-if="currentUserCanEditTaxonomy"
|
|
||||||
type="button"
|
|
||||||
@click.prevent="removeTerm(term)">
|
|
||||||
<span
|
|
||||||
v-tooltip="{
|
|
||||||
content: $i18n.get('delete'),
|
|
||||||
autoHide: true,
|
|
||||||
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
|
|
||||||
placement: 'bottom'
|
|
||||||
}"
|
|
||||||
class="icon">
|
|
||||||
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-delete"/>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<template v-if="!isLoadingSearch && !searchResults.length">
|
|
||||||
<li class="tainacan-li-checkbox-list result-info">
|
|
||||||
{{ $i18n.get('info_no_terms_found') }}
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<b-loading
|
|
||||||
:is-full-page="false"
|
|
||||||
:active.sync="isLoadingSearch"/>
|
|
||||||
</ul>
|
|
||||||
<button
|
|
||||||
v-if="hasMoreSearchPages"
|
|
||||||
type="button"
|
|
||||||
class="tainacan-checkbox-list-page-changer"
|
|
||||||
@click="nextSearchPage">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="tainacan-icon tainacan-icon-next"/>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<b-modal
|
|
||||||
v-model="isEditingTerm"
|
|
||||||
:width="768"
|
|
||||||
trap-focus
|
|
||||||
aria-role="dialog"
|
|
||||||
aria-modal
|
|
||||||
:can-cancel="['outside', 'escape']"
|
|
||||||
custom-class="tainacan-modal"
|
|
||||||
:close-button-aria-label="$i18n.get('close')">
|
|
||||||
<term-edition-form
|
|
||||||
:taxonomy-id="taxonomyId"
|
|
||||||
:is-modal="true"
|
|
||||||
@onEditionFinished="onTermEditionFinished($event.term, $event.hasChangedParent, $event.initialParent)"
|
|
||||||
:original-form="editTerm" />
|
|
||||||
</b-modal>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { tainacan as axios } from '../../js/axios';
|
|
||||||
import { termsListMixin } from '../../js/terms-list-mixin';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'TermsListLinear',
|
|
||||||
mixins: [
|
|
||||||
termsListMixin
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
searchString: String
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchResults: [],
|
|
||||||
maxSearchResultsPerPage: 20,
|
|
||||||
searchResultsOffset: 0,
|
|
||||||
isLoadingSearch: false,
|
|
||||||
hasMoreSearchPages: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
searchString: {
|
|
||||||
handler(newValue, oldValue) {
|
|
||||||
if (newValue != oldValue) {
|
|
||||||
this.hasMoreSearchPages = true;
|
|
||||||
this.searchResultsOffset = 0;
|
|
||||||
|
|
||||||
this.fetchTerms();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
previousSearchPage() {
|
|
||||||
|
|
||||||
this.hasMoreSearchPages = true;
|
|
||||||
|
|
||||||
this.searchResultsOffset -= this.maxSearchResultsPerPage;
|
|
||||||
if ( this.searchResultsOffset < 0 )
|
|
||||||
this.searchResultsOffset = 0;
|
|
||||||
|
|
||||||
this.fetchTerms();
|
|
||||||
|
|
||||||
},
|
|
||||||
nextSearchPage() {
|
|
||||||
|
|
||||||
if ( this.hasMoreSearchPages ) {
|
|
||||||
if ( this.searchResultsOffset === this.maxSearchResultsPerPage )
|
|
||||||
this.searchResultsOffset += this.maxSearchResultsPerPage - 1;
|
|
||||||
else
|
|
||||||
this.searchResultsOffset += this.maxSearchResultsPerPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fetchTerms();
|
|
||||||
},
|
|
||||||
fetchTerms: _.debounce( function () {
|
|
||||||
|
|
||||||
if (!this.searchString.length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.isLoadingSearch = true;
|
|
||||||
|
|
||||||
const query = `?order=asc&number=${this.maxSearchResultsPerPage}&searchterm=${this.searchString}&hideempty=0&offset=${this.searchResultsOffset}`;
|
|
||||||
|
|
||||||
const route = `/taxonomy/${this.taxonomyId}/terms/${query}`;
|
|
||||||
axios.get(route)
|
|
||||||
.then((res) => {
|
|
||||||
this.searchResults = res.data;
|
|
||||||
this.isLoadingSearch = false;
|
|
||||||
|
|
||||||
if (res.headers && res.headers['x-wp-total'])
|
|
||||||
this.hasMoreSearchPages = res.headers['x-wp-total'] > (this.searchResultsOffset + this.searchResults.length);
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$console.log(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
}, 500),
|
|
||||||
updateSelectedTerms(selectedTerm) {
|
|
||||||
|
|
||||||
let currentSelected = JSON.parse(JSON.stringify(this.selected));
|
|
||||||
|
|
||||||
const existingValueIndex = this.selected.findIndex(aSelectedTerm => aSelectedTerm.id == selectedTerm.id);
|
|
||||||
|
|
||||||
if (existingValueIndex >= 0)
|
|
||||||
currentSelected.splice(existingValueIndex, 1);
|
|
||||||
else
|
|
||||||
currentSelected.push(selectedTerm);
|
|
||||||
|
|
||||||
this.$emit('onUpdateSelectedTerms', currentSelected);
|
|
||||||
},
|
|
||||||
onTermRemovalFinished(term) {
|
|
||||||
const removedTermIndex = this.searchResults.findIndex((aTerm) => aTerm.id == term.id);
|
|
||||||
|
|
||||||
if ( removedTermIndex >= 0 )
|
|
||||||
this.searchResults.splice(removedTermIndex, 1);
|
|
||||||
},
|
|
||||||
onTermEditionFinished(term) {
|
|
||||||
const updatedTermIndex = this.searchResults.findIndex((aTerm) => aTerm.id == term.id);
|
|
||||||
|
|
||||||
if ( updatedTermIndex >= 0 )
|
|
||||||
this.searchResults.splice(updatedTermIndex, 1, term);
|
|
||||||
},
|
|
||||||
resetTermsListUI() {
|
|
||||||
this.$emit('onUpdateSelectedTerms', []);
|
|
||||||
this.fetchTerms();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
.tainacan-li-checkbox-list {
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 1;
|
|
||||||
max-width: 100%;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
margin: 0;
|
|
||||||
-webkit-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: stretch;
|
|
||||||
min-height: 1.5em;
|
|
||||||
|
|
||||||
/deep/ .b-checkbox, /deep/ .b-radio {
|
|
||||||
margin-right: 0px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
-webkit-break-inside: avoid;
|
|
||||||
break-inside: avoid;
|
|
||||||
|
|
||||||
.control-label {
|
|
||||||
white-space: normal;
|
|
||||||
overflow: visible;
|
|
||||||
padding-top: 0.125em;
|
|
||||||
padding-bottom: 0.125em;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
input:disabled+.check {
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.control-label {
|
|
||||||
padding-top: 0.8125em;
|
|
||||||
padding-bottom: 0.8125em;
|
|
||||||
padding-left: calc(0.875em - 1px);
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 1px solid var(--tainacan-gray1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&>a:not(.add-link),
|
|
||||||
&>button:not(.add-link) {
|
|
||||||
opacity: 0.0;
|
|
||||||
transition: opacity 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.load-children-button {
|
|
||||||
opacity: 0.95;
|
|
||||||
border-left: 1px dashed var(--tainacan-gray1);
|
|
||||||
}
|
|
||||||
.tainacan-icon {
|
|
||||||
color: var(--tainacan-blue5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-container {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
right: -0.5em;
|
|
||||||
opacity: 0.0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover:not(.result-info) {
|
|
||||||
background-color: var(--tainacan-gray1);
|
|
||||||
|
|
||||||
&>a:not(.add-link),
|
|
||||||
&>button:not(.add-link),
|
|
||||||
.actions-container {
|
|
||||||
opacity: 1.0;
|
|
||||||
background-color: var(--tainacan-gray2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.result-info {
|
|
||||||
padding: 0.5rem 0.25rem 0.25rem 0.25rem;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
column-span: all;
|
|
||||||
font-size: 0.75em;
|
|
||||||
color: var(--tainacan-info-color);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
// For Safari
|
|
||||||
-webkit-margin-after: 0;
|
|
||||||
-webkit-margin-start: 0;
|
|
||||||
-webkit-margin-end: 0;
|
|
||||||
-webkit-padding-start: 0;
|
|
||||||
-webkit-margin-before: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field:not(:last-child) {
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tainacan-checkbox-list-container {
|
|
||||||
border: 1px solid var(--tainacan-gray2);
|
|
||||||
min-height: 232px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
padding: 0 20px !important;
|
|
||||||
|
|
||||||
&>ul+.tainacan-checkbox-list-page-changer {
|
|
||||||
right: 0;
|
|
||||||
left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not(.add-link),
|
|
||||||
button:not(.add-link) {
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
font-size: 0.75em;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 8px 0.5rem;
|
|
||||||
|
|
||||||
.tainacan-icon {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tainacan-checkbox-list-page-changer {
|
|
||||||
height: calc(100% - 1px);
|
|
||||||
top: 1px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: auto;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
padding: 0 !important;
|
|
||||||
background-color: var(--tainacan-gray1) !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--tainacan-blue1) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tainacan-modal-checkbox-list-body {
|
|
||||||
-moz-column-count: 2;
|
|
||||||
-moz-column-gap: 0;
|
|
||||||
-moz-column-rule: none;
|
|
||||||
-webkit-column-count: 2;
|
|
||||||
-webkit-column-gap: 0;
|
|
||||||
-webkit-column-rule: none;
|
|
||||||
column-count: 2;
|
|
||||||
column-gap: 2em;
|
|
||||||
column-rule: none;
|
|
||||||
column-fill: auto;
|
|
||||||
list-style: none;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 !important;
|
|
||||||
max-height: 42vh;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tainacan-modal-checkbox-search-results-body {
|
|
||||||
list-style: none;
|
|
||||||
-moz-column-count: 2;
|
|
||||||
-moz-column-gap: 0;
|
|
||||||
-moz-column-rule: none;
|
|
||||||
-webkit-column-count: 2;
|
|
||||||
-webkit-column-gap: 0;
|
|
||||||
-webkit-column-rule: none;
|
|
||||||
column-count: 2;
|
|
||||||
column-gap: 2em;
|
|
||||||
column-rule: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b-checkbox .control-label {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
overflow: visible !important;
|
|
||||||
white-space: normal !important;
|
|
||||||
|
|
||||||
.checkbox-name-text {
|
|
||||||
line-height: 1.25em;
|
|
||||||
padding-right: 3px;
|
|
||||||
break-inside: avoid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
|
|
||||||
.tainacan-modal-checkbox-list-body,
|
|
||||||
.tainacan-modal-checkbox-search-results-body {
|
|
||||||
-moz-column-count: auto;
|
|
||||||
-webkit-column-count: auto;
|
|
||||||
column-count: auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.tainacan-modal-checkbox-search-results-body,
|
|
||||||
.tainacan-modal-checkbox-list-body {
|
|
||||||
font-size: 1.125em;
|
|
||||||
}
|
|
||||||
.tainacan-li-checkbox-list {
|
|
||||||
max-width: calc(100% - 20px) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
:mobile-modal="true"
|
:mobile-modal="true"
|
||||||
id="selected-terms-dropdown"
|
id="selected-terms-dropdown"
|
||||||
aria-role="list"
|
aria-role="list"
|
||||||
trap-focus>
|
trap-focus
|
||||||
|
position="is-bottom-left">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="button is-white"
|
class="button is-white"
|
||||||
|
@ -102,19 +103,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Search Results -->
|
|
||||||
<terms-list-linear
|
|
||||||
v-if="isSearching"
|
|
||||||
:search-string="searchString"
|
|
||||||
:taxonomy-id="taxonomyId"
|
|
||||||
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
|
|
||||||
:selected="selected"
|
|
||||||
@onUpdateSelectedTerms="(newSelected) => selected = newSelected"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Terms list with hierarchy -->
|
<!-- Terms list with hierarchy -->
|
||||||
<terms-list-hierarchical
|
<terms-list-hierarchical
|
||||||
v-else
|
:search-string="searchString"
|
||||||
:taxonomy-id="taxonomyId"
|
:taxonomy-id="taxonomyId"
|
||||||
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
|
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
|
||||||
:selected="selected"
|
:selected="selected"
|
||||||
|
@ -127,13 +118,11 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TermsListHierarchical from './terms-list-hierarchical.vue';
|
import TermsListHierarchical from './terms-list-hierarchical.vue';
|
||||||
import TermsListLinear from './terms-list-linear.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TermsList',
|
name: 'TermsList',
|
||||||
components: {
|
components: {
|
||||||
TermsListHierarchical,
|
TermsListHierarchical
|
||||||
TermsListLinear
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
taxonomyId: Number,
|
taxonomyId: Number,
|
||||||
|
@ -155,9 +144,6 @@ export default {
|
||||||
return this.selected.length;
|
return this.selected.length;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
},
|
|
||||||
isSearching() {
|
|
||||||
return !!this.searchString;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -249,10 +235,19 @@ export default {
|
||||||
/deep/ .dropdown-trigger {
|
/deep/ .dropdown-trigger {
|
||||||
font-size: 1.125em !important;
|
font-size: 1.125em !important;
|
||||||
}
|
}
|
||||||
|
/deep/ .dropdown-menu {
|
||||||
|
width: max-content;
|
||||||
|
max-width: 380px;
|
||||||
|
}
|
||||||
.checkbox-name-text {
|
.checkbox-name-text {
|
||||||
font-size: 1.375em !important;
|
font-size: 1.375em !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:not(.field) {
|
||||||
|
border: 1px solid var(--tainacan-input-border-color);
|
||||||
|
padding: 0.2rem 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
import { mapActions } from 'vuex';
|
|
||||||
import TermDeletionDialog from '../components/other/term-deletion-dialog.vue';
|
|
||||||
|
|
||||||
export const termsListMixin = {
|
|
||||||
props: {
|
|
||||||
taxonomyId: Number,
|
|
||||||
currentUserCanEditTaxonomy: Boolean,
|
|
||||||
selected: Array,
|
|
||||||
selectedColumnIndex: Number
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
totalRemaining: {},
|
|
||||||
isEditingTerm: false,
|
|
||||||
editTerm: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.$parent.$on('deleteSelectedTerms', this.deleteSelectedTerms);
|
|
||||||
this.$parent.$on('updateSelectedTermsParent', this.updateSelectedTermsParent);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
this.$parent.$off('deleteSelectedTerms', this.deleteSelectedTerms);
|
|
||||||
this.$parent.$off('updateSelectedTermsParent', this.updateSelectedTermsParent);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('taxonomy', [
|
|
||||||
'updateTerm',
|
|
||||||
'deleteTerm',
|
|
||||||
'deleteTerms',
|
|
||||||
'changeTermsParent'
|
|
||||||
]),
|
|
||||||
renderTermHierarchyLabel(term) {
|
|
||||||
if ( term.hierarchy_path )
|
|
||||||
return '<span style="color: var(--tainacan-info-color);">' + term.hierarchy_path.replace(/>/g, ' <span class="hierarchy-separator"> > </span> ') + '</span>' + term.name;
|
|
||||||
|
|
||||||
return term.name;
|
|
||||||
},
|
|
||||||
isTermSelected(termId) {
|
|
||||||
return this.selected.findIndex(aSelectedTerm => aSelectedTerm.id == termId) >= 0;
|
|
||||||
},
|
|
||||||
getTermIdAsNumber(termId) {
|
|
||||||
return isNaN(Number(termId)) ? termId : Number(termId)
|
|
||||||
},
|
|
||||||
onEditTerm(term) {
|
|
||||||
this.editTerm = term;
|
|
||||||
this.isEditingTerm = true;
|
|
||||||
},
|
|
||||||
removeTerm(term) {
|
|
||||||
|
|
||||||
this.$buefy.modal.open({
|
|
||||||
parent: this,
|
|
||||||
component: TermDeletionDialog,
|
|
||||||
props: {
|
|
||||||
message: term.total_children && term.total_children != '0' ? this.$i18n.get('info_warning_term_with_child') : this.$i18n.get('info_warning_selected_term_delete'),
|
|
||||||
showDescendantsDeleteButton: term.total_children && term.total_children != '0',
|
|
||||||
amountOfTerms: 1,
|
|
||||||
onConfirm: (typeOfDelete) => {
|
|
||||||
|
|
||||||
// If all checks passed, term can be deleted
|
|
||||||
if ( typeOfDelete == 'descendants' ) {
|
|
||||||
this.deleteTerm({
|
|
||||||
taxonomyId: this.taxonomyId,
|
|
||||||
termId: term.id,
|
|
||||||
parent: term.parent,
|
|
||||||
deleteChildTerms: true })
|
|
||||||
.then(() => {
|
|
||||||
this.onTermRemovalFinished(term);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$console.log(error);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.deleteTerm({
|
|
||||||
taxonomyId: this.taxonomyId,
|
|
||||||
termId: term.id,
|
|
||||||
parent: term.parent })
|
|
||||||
.then(() => {
|
|
||||||
this.onTermRemovalFinished(term);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trapFocus: true,
|
|
||||||
customClass: 'tainacan-modal',
|
|
||||||
closeButtonAriaLabel: this.$i18n.get('close')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deleteSelectedTerms() {
|
|
||||||
|
|
||||||
this.$buefy.modal.open({
|
|
||||||
parent: this,
|
|
||||||
component: TermDeletionDialog,
|
|
||||||
props: {
|
|
||||||
message: this.$i18n.get('info_warning_some_terms_with_child'),
|
|
||||||
showDescendantsDeleteButton: true,
|
|
||||||
amountOfTerms: this.amountOfTermsSelected,
|
|
||||||
onConfirm: (typeOfDelete) => {
|
|
||||||
// If all checks passed, term can be deleted
|
|
||||||
this.deleteTerms({
|
|
||||||
taxonomyId: this.taxonomyId,
|
|
||||||
terms: this.selectedColumnIndex >= 0 ? [] : this.selected.map((aTerm) => aTerm.id),
|
|
||||||
parent: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : undefined,
|
|
||||||
deleteChildTerms: typeOfDelete === 'descendants'
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.resetTermsListUI();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trapFocus: true,
|
|
||||||
customClass: 'tainacan-modal',
|
|
||||||
closeButtonAriaLabel: this.$i18n.get('close')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updateSelectedTermsParent() {
|
|
||||||
|
|
||||||
this.$buefy.modal.open({
|
|
||||||
parent: this,
|
|
||||||
component: TermParentSelectionDialog,
|
|
||||||
props: {
|
|
||||||
amountOfTerms: this.amountOfTermsSelected,
|
|
||||||
excludeTree: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : this.selected.map((aTerm) => aTerm.id),
|
|
||||||
taxonomyId: this.taxonomyId,
|
|
||||||
onConfirm: (selectedParentTerm) => {
|
|
||||||
this.changeTermsParent({
|
|
||||||
taxonomyId: this.taxonomyId,
|
|
||||||
terms: this.selectedColumnIndex >= 0 ? [] : this.selected.map((aTerm) => aTerm.id),
|
|
||||||
parent: this.selectedColumnIndex >= 0 ? this.termColumns[this.selectedColumnIndex].id : undefined,
|
|
||||||
newParentTerm: selectedParentTerm
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.resetTermsListUI();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.$console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trapFocus: true,
|
|
||||||
customClass: 'tainacan-modal',
|
|
||||||
closeButtonAriaLabel: this.$i18n.get('close')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
Reference in New Issue