Merge pull request #603 from tainacan/feature/573

Feature/573: create terms on submission item
This commit is contained in:
Mateus Machado Luna 2021-09-10 10:53:31 -03:00 committed by GitHub
commit 90b8a7e3db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 466 additions and 81 deletions

View File

@ -5,7 +5,6 @@ namespace Tainacan\API\EndPoints;
use \Tainacan\API\REST_Controller;
use Tainacan\Repositories;
use Tainacan\Entities;
use Tainacan\Tests\Collections;
/**
* Represents the Items REST Controller
@ -38,6 +37,7 @@ class REST_Items_Controller extends REST_Controller {
$this->item_metadata = Repositories\Item_Metadata::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
$this->metadatum_repository = Repositories\Metadata::get_instance();
$this->terms_repository = \Tainacan\Repositories\Terms::get_instance();
}
/**
@ -897,11 +897,13 @@ class REST_Items_Controller extends REST_Controller {
return $this->item_metadata->suggest( $item_metadata );
}
else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response( [
'error_message' => __( 'The metadatum does not accept suggestions', 'tainacan' ),
], 400 );
}
} else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response( [
'error_message' => __( 'Please verify, invalid value(s)', 'tainacan' ),
'errors' => $item_metadata->get_errors(),
@ -910,6 +912,43 @@ class REST_Items_Controller extends REST_Controller {
}
}
private $new_terms_ids = [];
private function submission_process_terms ($value, $taxonomy) {
if (is_numeric($value)) return $value;
$split_value = explode(">>", $value);
if(count($split_value) == 1 ) {
$exist = $this->terms_repository->term_exists($split_value[0], $taxonomy, null, true);
if ($exist)
return $split_value[0];
$new_term = new Entities\Term();
$new_term->set_taxonomy( $taxonomy->get_db_identifier() );
$new_term->set('name', $split_value[0]);
if ( $new_term->validate() ) {
$new_term = $this->terms_repository->insert( $new_term );
$this->new_terms_ids[] = ['term_id' => $new_term->get_term_id(), 'taxonomy' => $new_term->get_taxonomy()];
}
return $new_term;
} else if (count($split_value) == 2 ) {
$new_term = new Entities\Term();
$new_term->set_taxonomy( $taxonomy->get_db_identifier() );
$new_term->set('name', $split_value[1]);
$new_term->set('parent', $split_value[0]);
if ( $new_term->validate() ) {
$new_term = $this->terms_repository->insert( $new_term );
$this->new_terms_ids[] = ['term_id' => $new_term->get_term_id(), 'taxonomy' => $new_term->get_taxonomy()];
}
return $new_term;
}
return count($split_value) > 1 ? $value : filter_var($value, FILTER_SANITIZE_STRING);
}
private function submission_rollback_new_terms () {
foreach($this->new_terms_ids as $term) {
$remove_term = new Entities\Term($term['term_id'], $term['taxonomy']);
$this->terms_repository->delete( $remove_term, true );
}
}
public function submission_item ($request) {
$collection_id = $request['collection_id'];
$item = json_decode($request->get_body(), true);
@ -936,7 +975,7 @@ class REST_Items_Controller extends REST_Controller {
if ( $item->validate() ) {
$item = $this->items_repository->insert( $item );
$item_id = $item->get_id();
foreach ( $metadata as $m ) {
if ( !isset($m['value']) || $m['value'] == null ) continue;
$value = $m['value'];
@ -988,6 +1027,25 @@ class REST_Items_Controller extends REST_Controller {
$parent_meta_id = $item_metadata_child->get_parent_meta_id();
}
}
} else if ($metadatum->get_metadata_type_object()->get_primitive_type() == 'term') {
$taxonomy_id = $metadatum->get_metadata_type_object()->get_option( 'taxonomy_id' );
$taxonomy = new Entities\Taxonomy( $taxonomy_id );
if (is_array($value) == true) {
$value = array_map( function($v) use ($taxonomy) {
return $this->submission_process_terms($v, $taxonomy);
}, $value);
} else {
$value = $this->submission_process_terms($value, $taxonomy);
}
if ($item_metadata->is_multiple()) {
$item_metadata->set_value( is_array($value) ? $value : [$value] );
} else {
$item_metadata->set_value( is_array($value) ? implode(' ', $value) : $value);
}
$item_metadata = $this->submission_item_metadada($item_metadata, $request);
if ($item_metadata instanceof \WP_REST_Response) {
return $item_metadata;
}
} else {
if (is_array($value) == true) {
$value = array_map( function($v) { return is_numeric($v) ? $v : filter_var($v, FILTER_SANITIZE_STRING); }, $value);
@ -1011,14 +1069,19 @@ class REST_Items_Controller extends REST_Controller {
$fake_id = md5(uniqid(mt_rand(), true));
$id = $item->get_id();
if (set_transient('tnc_transient_submission_' . $fake_id, $id, 300) == true) {
set_transient('tnc_transient_submission_' . $fake_id . '_new_terms_ids', $this->new_terms_ids, 300);
$response_item = $this->prepare_item_for_response($item, $request);
$response_item['id'] = $fake_id;
return new \WP_REST_Response($response_item, 201 );
} else return new \WP_REST_Response([
'error_message' => __('unable create submission ID.', 'tainacan'),
], 400);
} else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response([
'error_message' => __('unable create submission ID.', 'tainacan'),
], 400);
}
} else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
'errors' => $item->get_errors(),
@ -1026,6 +1089,7 @@ class REST_Items_Controller extends REST_Controller {
], 400);
}
} else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
'errors' => $item->get_errors(),
@ -1033,6 +1097,7 @@ class REST_Items_Controller extends REST_Controller {
], 400);
}
} catch (\Exception $exception){
$this->submission_rollback_new_terms();
return new \WP_REST_Response($exception->getMessage(), 400);
}
}
@ -1047,6 +1112,7 @@ class REST_Items_Controller extends REST_Controller {
'error_message' => __('submission ID not exist.', 'tainacan'),
], 400);
}
$this->new_terms_ids = get_transient('tnc_transient_submission_' . $submission_id . '_new_terms_ids');
$item = $this->items_repository->fetch($item_id);
$collection = $this->collections_repository->fetch($collection_id);
@ -1120,6 +1186,7 @@ class REST_Items_Controller extends REST_Controller {
delete_transient('tnc_transient_submission_' . $submission_id);
return new \WP_REST_Response($this->prepare_item_for_response($item, $request), 201 );
} else {
$this->submission_rollback_new_terms();
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
'errors' => array_merge($item->get_errors(), $entities_erros),

View File

@ -8,14 +8,14 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
* Represents the Entity Term
*/
class Term extends Entity {
protected
$term_id,
$name,
$parent,
$description,
$user,
protected
$term_id,
$name,
$parent,
$description,
$user,
$header_image_id,
$taxonomy;
$taxonomy;
static $post_type = false;
@ -34,22 +34,22 @@ class Term extends Entity {
*/
function __construct($which = 0, $taxonomy = false ) {
if ($taxonomy)
$this->set_taxonomy( $taxonomy );
if ($taxonomy)
$this->set_taxonomy( $taxonomy );
if ( is_numeric( $which ) && $which > 0) {
$post = get_term_by('id', $which, $taxonomy);
if ( $post instanceof \WP_Term) {
$this->WP_Term = get_term_by('id', $which, $taxonomy);
}
if ( is_numeric( $which ) && $which > 0) {
$post = get_term_by('id', $which, $taxonomy);
if ( $post instanceof \WP_Term) {
$this->WP_Term = get_term_by('id', $which, $taxonomy);
}
} elseif ( $which instanceof \WP_Term ) {
$this->WP_Term = $which;
} else {
$this->WP_Term = new \StdClass();
}
}
} elseif ( $which instanceof \WP_Term ) {
$this->WP_Term = $which;
} else {
$this->WP_Term = new \StdClass();
}
}
public function __toString() {
return (string) apply_filters("tainacan-term-to-string", $this->get_name(), $this);
@ -70,7 +70,7 @@ class Term extends Entity {
return apply_filters('tainacan-term-to-array', $term_array, $this);
}
// Getters
// Getters
/**
* Return the unique identifier
@ -78,11 +78,11 @@ class Term extends Entity {
* @return integer
*/
function get_id() {
return $this->get_term_id();
}
return $this->get_term_id();
}
function get_term_id() {
return $this->get_mapped_property('term_id');
}
return $this->get_mapped_property('term_id');
}
/**
* Return the name
@ -90,8 +90,8 @@ class Term extends Entity {
* @return string
*/
function get_name() {
return $this->get_mapped_property('name');
}
return $this->get_mapped_property('name');
}
/**
* Return the parent ID
@ -99,8 +99,8 @@ class Term extends Entity {
* @return integer
*/
function get_parent() {
return $this->get_mapped_property('parent');
}
return $this->get_mapped_property('parent');
}
/**
* Return the description
@ -108,8 +108,8 @@ class Term extends Entity {
* @return string
*/
function get_description() {
return $this->get_mapped_property('description');
}
return $this->get_mapped_property('description');
}
/**
* Return the user ID
@ -117,8 +117,8 @@ class Term extends Entity {
* @return integer
*/
function get_user() {
return $this->get_mapped_property('user');
}
return $this->get_mapped_property('user');
}
/**
* Return the taxonomy
@ -126,8 +126,8 @@ class Term extends Entity {
* @return integer
*/
function get_taxonomy() {
return $this->get_mapped_property('taxonomy');
}
return $this->get_mapped_property('taxonomy');
}
/**
* Get Header Image ID attribute
@ -155,7 +155,7 @@ class Term extends Entity {
return $url;
}
// Setters
// Setters
/**
* Define the name
@ -163,8 +163,8 @@ class Term extends Entity {
* @param [string] $value
*/
function set_name($value) {
$this->set_mapped_property('name', $value);
}
$this->set_mapped_property('name', $value);
}
/**
* Define the parent ID
@ -172,8 +172,8 @@ class Term extends Entity {
* @param [integer] $value
*/
function set_parent($value) {
$this->set_mapped_property('parent', $value);
}
$this->set_mapped_property('parent', $value);
}
/**
* Define the description
@ -181,8 +181,8 @@ class Term extends Entity {
* @param [string] $value
*/
function set_description($value) {
$this->set_mapped_property('description', $value);
}
$this->set_mapped_property('description', $value);
}
/**
* Define the user associated
@ -190,8 +190,8 @@ class Term extends Entity {
* @param [integer] $value
*/
function set_user($value) {
$this->set_mapped_property('user', $value);
}
$this->set_mapped_property('user', $value);
}
/**
* Define the taxonomy associated
@ -199,8 +199,8 @@ class Term extends Entity {
* @param [integer] $value
*/
function set_taxonomy($value) {
$this->set_mapped_property('taxonomy', $value);
}
$this->set_mapped_property('taxonomy', $value);
}
/**
* Set Header Image ID

View File

@ -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 {

View File

@ -7,7 +7,7 @@
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : 1)"
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"
@ -33,7 +33,7 @@
/>
<div
v-if="displayCreateNewTerm"
v-if="displayCreateNewTerm && !isTermCreationPanelOpen"
class="add-new-term">
<a
@click="openTermCreationModal"
@ -46,6 +46,7 @@
</a>
</div>
<!-- Term creation modal, used on admin for a complete term creation -->
<b-modal
v-model="isTermCreationModalOpen"
trap-focus
@ -61,6 +62,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>
@ -80,9 +92,8 @@
disabled: false,
forcedComponentType: '',
maxtags: '',
allowNew: false,
allowSelectToCreate: false,
isTermCreationModalOpen: false,
newTermName: ''
},
data(){
return {
@ -90,8 +101,11 @@
taxonomyId: '',
taxonomy: '',
terms:[],
allowNew: false,
isAddingNewTermVaue: false
isAddingNewTermVaue: false,
isTermCreationModalOpen: false,
isTermCreationPanelOpen: false,
newTermName: '',
allowNewFromOptions: false
}
},
computed: {
@ -107,7 +121,10 @@
return '';
},
displayCreateNewTerm() {
return this.allowNew && (this.maxMultipleValues === undefined || this.maxMultipleValues > this.value.length);
return this.allowNewFromOptions;
},
isOnItemSubmissionForm() {
return !this.itemMetadatum.item || !this.itemMetadatum.item.id;
},
maxMultipleValues() {
return (this.itemMetadatum && this.itemMetadatum.metadatum && this.itemMetadatum.metadatum.cardinality && !isNaN(this.itemMetadatum.metadatum.cardinality)) ? this.itemMetadatum.metadatum.cardinality : undefined;
@ -124,9 +141,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: {
@ -168,9 +184,21 @@
}
}
},
addTermToBeCreated(term) {
this.isTermCreationPanelOpen = false;
if (this.itemMetadatum.metadatum.multiple === 'no')
this.valueComponent = term.parent ? (term.parent + '>>' + term.name) : term.name;
else
this.valueComponent.push(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;
}
}
}

View File

@ -291,7 +291,7 @@
closable
class="is-small"
@close="selected instanceof Array ? selected.splice(index, 1) : selected = ''">
<span v-html="(isTaxonomy || metadatum_type === 'Tainacan\\Metadata_Types\\Relationship') ? selectedTagsName[term] : term" />
<span v-html="(isTaxonomy || metadatum_type === 'Tainacan\\Metadata_Types\\Relationship') ? selectedTagsName[term] : term" />
</b-tag>
</div>
</b-field>
@ -441,23 +441,33 @@
},
fetchSelectedLabels() {
let selected = this.selected instanceof Array ? this.selected : [this.selected];
let allSelected = this.selected instanceof Array ? this.selected : [this.selected];
if (this.taxonomy_id && selected.length) {
// If a new item was added from item submission block, the value will be a string, and the term does not exists yet.
let selected = allSelected.filter((aValue) => !isNaN(aValue));
let selectedFromItemSubmission = allSelected.filter((aValue) => isNaN(aValue));
this.isSelectedTermsLoading = true;
if (this.taxonomy_id) {
axios.get(`/taxonomy/${this.taxonomy_id}/terms/?${qs.stringify({ hideempty: 0, include: selected})}`)
.then((res) => {
for (const term of res.data)
this.saveSelectedTagName(term.id, term.name, term.url);
if (selected.length) {
this.isSelectedTermsLoading = true;
axios.get(`/taxonomy/${this.taxonomy_id}/terms/?${qs.stringify({ hideempty: 0, include: selected})}`)
.then((res) => {
for (const term of res.data)
this.saveSelectedTagName(term.id, term.name, term.url);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
if (selectedFromItemSubmission) {
for (const term of selectedFromItemSubmission)
this.saveSelectedTagName(term, term.split('>')[term.split('>').length - 1], '');
}
} else if (this.metadatum_type === 'Tainacan\\Metadata_Types\\Relationship' && selected.length) {
this.isSelectedTermsLoading = true;

View File

@ -67,7 +67,7 @@ export default {
padding: 0.8em 0.8em 0em 0.8em;
h5 {
font-size: 0.875em;
font-size: 0.875em !important;
font-weight: bold;
color: var(--tainacan-secondary);
margin-bottom: 0;

View File

@ -108,7 +108,7 @@ export default {
padding: 0.8em 0.8em 0em 0.8em;
h5 {
font-size: 0.875em;
font-size: 0.875em !important;
font-weight: bold;
color: var(--tainacan-red2);
margin-bottom: 0;

View File

@ -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';
@ -83,6 +84,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({

View File

@ -0,0 +1,278 @@
<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 !important;
}
&>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>