Merge branch 'develop' into feature/783

This commit is contained in:
vnmedeiros 2023-11-10 15:04:01 -03:00
commit 6edd8df2e1
54 changed files with 661 additions and 194 deletions

43
package-lock.json generated
View File

@ -1294,6 +1294,22 @@
"regenerator-runtime": "^0.13.11"
}
},
"@babel/runtime-corejs3": {
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz",
"integrity": "sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw==",
"requires": {
"core-js-pure": "^3.30.2",
"regenerator-runtime": "^0.14.0"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
}
}
},
"@babel/template": {
"version": "7.21.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz",
@ -3001,6 +3017,11 @@
"browserslist": "^4.21.5"
}
},
"core-js-pure": {
"version": "3.33.1",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.1.tgz",
"integrity": "sha512-wCXGbLjnsP10PlK/thHSQlOLlLKNEkaWbTzVvHHZ79fZNeN1gUmw2gBlpItxPv/pvqldevEXFh/d5stdNvl6EQ=="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@ -4406,6 +4427,14 @@
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true
},
"imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/imask/-/imask-7.1.3.tgz",
"integrity": "sha512-jZCqTI5Jgukhl2ff+znBQd8BiHOTlnFYCIgggzHYDdoJsHmSSWr1BaejcYBxsjy4ZIs8Rm0HhbOxQcobcdESRQ==",
"requires": {
"@babel/runtime-corejs3": "^7.22.6"
}
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -6982,6 +7011,11 @@
"resolved": "https://registry.npmjs.org/vue-countup-v2/-/vue-countup-v2-4.0.0.tgz",
"integrity": "sha512-XjKeHo1ndRlJtXvHd6B1eWOpbrJDdNU3rdYZwVPv2YlUXbvthsBT4kms5Fc/mn9RdXPrMX2H/ktAAQtKjWFisw=="
},
"vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w=="
},
"vue-eslint-parser": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz",
@ -7003,6 +7037,15 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"dev": true
},
"vue-imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/vue-imask/-/vue-imask-7.1.3.tgz",
"integrity": "sha512-WkkEwx34UjNJhN5vwgfLNgydLoqyFxBGJibT2322Extl68kW6YHQrFIusLeEZ4EVGzmv2zWhuxXxke55I2x4Dw==",
"requires": {
"imask": "^7.1.3",
"vue-demi": "^0.14.5"
}
},
"vue-loader": {
"version": "15.10.1",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.1.tgz",

View File

@ -31,6 +31,7 @@
"vue-apexcharts": "^1.6.2",
"vue-blurhash": "^0.1.4",
"vue-countup-v2": "^4.0.0",
"vue-imask": "^7.1.3",
"vue-router": "^3.6.5",
"vue-the-mask": "^0.11.1",
"vue2-leaflet": "^2.7.1",

View File

@ -798,6 +798,10 @@
max-width: calc((90vh * 9) / 16); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-1-2 {
max-width: calc((90vh * 1) / 2); }
.tainacan-photoswipe-layer .pswp__container .pswp__content {
display: flex;
justify-content: center;
align-content: center; }
.tainacan-photoswipe-layer .pswp__container .pswp__content > .tainacan-content-embed:not(.attachment-without-image) {
margin-top: 60px; }
.tainacan-photoswipe-layer .pswp__container a:first-of-type,

File diff suppressed because one or more lines are too long

View File

@ -56,7 +56,7 @@ class REST_Sequence_Edit_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_item_in_sequence'),
'permission_callback' => array($this, 'sequence_edit_permissions_check'),
'args' => $this->get_sequence_params()
'args' => $this->get_sequence_index_params()
),
'schema' => [$this, 'get_sequence_index_schema']
)
@ -212,12 +212,36 @@ class REST_Sequence_Edit_Controller extends REST_Controller {
}
/**
/**
* @param string $method
*
* @return array|mixed
*/
public function get_sequence_params() {
$endpoint_args = [
'collection_id' => [
'type' => 'string',
'description' => __( 'Collection ID', 'tainacan' ),
'required' => true,
],
'group_id' => [
'type' => 'string',
'description' => __( 'Group ID', 'tainacan' ),
'required' => true,
]
];
return $endpoint_args;
}
/**
* @param string $method
*
* @return array|mixed
*/
public function get_sequence_index_params() {
$endpoint_args = [
'collection_id' => [
'type' => 'string',

View File

@ -285,13 +285,13 @@ class CSV extends Exporter {
$current_user = wp_get_current_user();
$author_name = $current_user->user_login;
$message = __('target collections:', 'tainacan');
$message = __('Target collections:', 'tainacan');
$message .= " <b>" . implode(", ", $this->get_collections_names() ) . "</b><br/>";
$message .= __('Exported by:', 'tainacan');
$message .= " <b> $author_name </b><br/>";
$message .= __('Your CSV file is ready! Access it in the link below:', 'tainacan');
$message .= '<br/><br/>';
$message .= '<a href="' . $file['url'] . '">Download</a>';
$message .= '<a target="_blank" href="' . $file['url'] . '">Download</a>';
return $message;

View File

@ -171,7 +171,7 @@
--tainacan-sidebar-width: 3.0em;
}
#primary-menu:not(.is-compressed)~.is-main-content {
--tainacan-sidebar-width: 10em;
--tainacan-sidebar-width: 11em;
}
.is-secondary-content {

View File

@ -362,7 +362,7 @@
<b-field
:addons="false"
:label="$i18n.get('label_metadata_related_features')">
<div class="status-radios">
<div class="options-checkboxes">
<b-checkbox
v-model="form.item_enable_metadata_collapses"
true-value="yes"
@ -477,7 +477,7 @@
<help-button
:title="$i18n.getHelperTitle('collections', 'submission_default_status')"
:message="$i18n.getHelperMessage('collections', 'submission_default_status')"/>
<div class="status-radios">
<div class="options-checkboxes">
<b-radio
v-model="form.submission_default_status"
v-for="(statusOption, index) of $statusHelper.getStatuses().filter((status) => status.slug != 'trash')"
@ -1771,7 +1771,20 @@ export default {
.status-radios {
display: flex;
margin: 5px 0;
.control-lable {
.control-label {
display: flex;
align-items: center;
}
}
.options-checkboxes {
display: flex;
margin: 5px 0;
justify-content: space-between;
/deep/ .b-checkbox.checkbox {
width: auto
}
.control-label {
display: flex;
align-items: center;
}

View File

@ -1344,7 +1344,7 @@ export default {
if (currentItemMetadatum) {
const itemMetadatumValues = Array.isArray(currentItemMetadatum.value) ? currentItemMetadatum.value : [ currentItemMetadatum.value ];
const conditionalValues = Array.isArray(eventBusItemMetadata.conditionalSections[conditionalSectionId].metadatumValues) ? eventBusItemMetadata.conditionalSections[conditionalSectionId].metadatumValues : [eventBusItemMetadata.conditionalSections[conditionalSectionId].metadatumValues];
eventBusItemMetadata.conditionalSections[conditionalSectionId].hide = itemMetadatumValues.every(aValue => conditionalValues.indexOf(aValue) < 0);
eventBusItemMetadata.conditionalSections[conditionalSectionId].hide = Array.isArray(itemMetadatumValues) ? itemMetadatumValues.every(aValue => conditionalValues.indexOf(aValue) < 0) : conditionalValues.indexOf(itemMetadatumValues) < 0;
}
}

View File

@ -179,8 +179,9 @@
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-select
v-model="selectedConditionalMetadatum"
:placeholder="$i18n.get('label_select_metadatum')">
v-model="selectedConditionalMetadatumId"
:placeholder="$i18n.get('label_select_metadatum')"
@input="reloadConditionalValueComponent()">
<option
v-for="conditionalMetadatum of availableConditionalMetadata"
:key="conditionalMetadatum.id"
@ -192,22 +193,23 @@
</transition>
<transition name="filter-item">
<b-field
v-if="isConditionalSection && selectedConditionalMetadatum"
v-if="isConditionalSection && selectedConditionalMetadatumId && selectedConditionalMetadatum && selectedConditionalMetadatum.name"
:addons="false"
:type="formErrors['conditional_section_rules'] != undefined ? 'is-danger' : ''"
:message="formErrors['conditional_section_rules'] != undefined ? formErrors['conditional_section_rules'] : ''">
<label class="label is-inline">
{{ availableConditionalMetadata.find((availableMetadatum) => availableMetadatum.id == selectedConditionalMetadatum).name }}
{{ selectedConditionalMetadatum.name }}
</label>
<div style="overflow-y: auto; overflow-x: hidden; max-height: 100px;">
<b-checkbox
v-model="selectedConditionalValue"
v-for="(conditionalValue, conditionalValueIndex) of availableConditionalMetadata.find((availableMetadatum) => availableMetadatum.id == selectedConditionalMetadatum).metadata_type_object.options.options.split('\n')"
:key="conditionalValueIndex"
:native-value="conditionalValue">
{{ conditionalValue }}
</b-checkbox>
</div>
<component
v-if="shouldUpdateConditionalValue"
:is="selectedConditionalMetadatum.metadata_type_object.component"
:forced-component-type="selectedConditionalMetadatum.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:item-metadatum="{ metadatum: selectedConditionalMetadatum }"
:value="selectedConditionalValue"
:allow-new="false"
:maxtags="1"
@input="selectConditionalValue"
/>
</b-field>
</transition>
</div>
@ -266,9 +268,10 @@
closedByForm: false,
entityName: 'metadataSection',
isUpdating: false,
selectedConditionalMetadatum: undefined,
selectedConditionalMetadatumId: undefined,
selectedConditionalValue: [],
hideConditionalSectionSettings: false
hideConditionalSectionSettings: false,
shouldUpdateConditionalValue: true
}
},
computed: {
@ -276,18 +279,21 @@
'getMetadataSections'
]),
availableConditionalMetadata() {
if (this.getMetadataSections.length) {
if ( this.getMetadataSections.length ) {
const otherMetadataSections = this.getMetadataSections.filter(aMetadataSection => aMetadataSection.id != this.form.id);
const availableMetadata = [];
for (let aMetadataSection of otherMetadataSections)
availableMetadata.push.apply(availableMetadata, aMetadataSection.metadata_object_list);
return availableMetadata.filter(aMetadatum => aMetadatum.metadata_type === 'Tainacan\\Metadata_Types\\Selectbox');
return availableMetadata.filter(aMetadatum => aMetadatum.metadata_type === 'Tainacan\\Metadata_Types\\Selectbox' || aMetadatum.metadata_type === 'Tainacan\\Metadata_Types\\Taxonomy');
}
return {};
return [];
},
isConditionalSection() {
return this.form.is_conditional_section == 'yes';
}
},
selectedConditionalMetadatum() {
return this.availableConditionalMetadata.find(aMetadatum => aMetadatum.id == this.selectedConditionalMetadatumId)
},
},
created() {
this.form = JSON.parse(JSON.stringify(this.originalMetadataSection));
@ -297,7 +303,7 @@
if ( this.form.is_conditional_section == 'yes' && Object.keys(this.form.conditional_section_rules).length ) {
const conditionalMetadatum = Object.keys(this.form.conditional_section_rules)[0];
this.selectedConditionalMetadatum = conditionalMetadatum;
this.selectedConditionalMetadatumId = conditionalMetadatum;
this.selectedConditionalValue = this.form.conditional_section_rules[conditionalMetadatum];
}
@ -316,10 +322,9 @@
'updateMetadataSection'
]),
saveEdition(metadataSection) {
if ( this.form.is_conditional_section == 'yes' && this.selectedConditionalMetadatum && this.selectedConditionalValue ) {
if ( this.form.is_conditional_section == 'yes' && this.selectedConditionalMetadatumId && this.selectedConditionalValue ) {
this.form.conditional_section_rules = {}
this.form.conditional_section_rules[this.selectedConditionalMetadatum] = this.selectedConditionalValue;
this.form.conditional_section_rules[this.selectedConditionalMetadatumId] = this.selectedConditionalValue;
} else
this.form.conditional_section_rules = null;
@ -359,6 +364,15 @@
this.closedByForm = true;
this.$emit('onEditionCanceled');
},
selectConditionalValue(selected) {
const selectedValues = Array.isArray(selected) ? selected : [ selected ];
this.selectedConditionalValue = selectedValues.map( aSelected => aSelected.value ? aSelected.value : aSelected );
},
reloadConditionalValueComponent() {
this.shouldUpdateConditionalValue = false;
this.selectedConditionalValue = [];
this.$nextTick(() => this.shouldUpdateConditionalValue = true);
}
}
}
</script>
@ -459,6 +473,23 @@
}
}
}
/deep/ .is-special-hidden-for-mobile,
/deep/ .is-special-hidden-for-mobile:focus,
/deep/ .is-special-hidden-for-mobile:focus-visible {
opacity: 0;
width: 0;
height: 0 !important;
min-height: 0;
min-width: 0;
padding: 0 !important;
line-height: 0px !important;
border: none !important;
border-color: transparent !important;
border-width: 0px !important;
font-size: 0px !important;
display: block !important;
}
.form-submit {
background-color: var(--tainacan-gray1);
position: sticky;

View File

@ -555,7 +555,7 @@
.status-radios {
display: flex;
}
.status-radios .control-lable {
.status-radios .control-label {
display: flex;
align-items: center;
}

View File

@ -9,7 +9,9 @@
<span>
<b-checkbox
@click.native="selectAllCollectionsOnPage()"
:value="allCollectionsOnPageSelected">{{ $i18n.get('label_select_all_collections_page') }}</b-checkbox>
:native-value="allCollectionsOnPageSelected">
{{ $i18n.get('label_select_all_collections_page') }}
</b-checkbox>
</span>
</div>
<div class="field is-pulled-right">
@ -575,7 +577,7 @@ export default {
.selection-control {
padding: 6px 0px 0px 12px;
background: var(--tainacan-white);
background: var(--tainacan-background-color);
height: 40px;
.select-all {

View File

@ -2693,7 +2693,7 @@ export default {
.selection-control {
margin-bottom: 6px;
padding: 6px 0px 0px 12px;
background: var(--tainacan-white);
background: var(--tainacan-background-color);
height: 40px;
display: flex;
align-items: center;

View File

@ -517,12 +517,16 @@
.sub-header {
@include logs-container();
.header-item {
min-height: 1.875em;
}
}
.selection-control {
padding: 6px 0px 0px 12px;
background: var(--tainacan-white);
background: var(--tainacan-background-color);
height: 40px;
.select-all {

View File

@ -10,7 +10,9 @@
<span>
<b-checkbox
@click.native="selectAllOnPage()"
:value="allOnPageSelected">{{ $i18n.get('label_select_all_taxonomies_page') }}</b-checkbox>
:native-value="allOnPageSelected">
{{ $i18n.get('label_select_all_taxonomies_page') }}
</b-checkbox>
</span>
</div>
<div class="field is-pulled-right">
@ -438,7 +440,7 @@
.selection-control {
padding: 6px 0px 0px 12px;
background: var(--tainacan-white);
background: var(--tainacan-background-color);
height: 40px;
.select-all {

View File

@ -19,11 +19,24 @@ class Core_Description extends Metadata_Type {
$this->set_core(true);
$this->set_related_mapped_prop('description');
$this->set_component('tainacan-textarea');
$this->set_form_component('tainacan-form-textarea');
$this->set_name( __('Core Description', 'tainacan') );
$this->set_description( __('The "Core Description" is a compulsory metadata automatically created for all collections by default. This is the main description displayed in items lists and where the basic research tools will do their searches.', 'tainacan') );
$this->set_sortable( false );
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'maxlength' => [
'title' => __( 'Maximum of characters', 'tainacan' ),
'description' => __( 'Limits the character input to a maximum value an displays a counter.', 'tainacan' ),
]
];
}
/**
* generate the metadata for this metadatum type
*/

View File

@ -69,6 +69,32 @@
</button>
</div>
</b-field>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-numeric', 'min') }}
<help-button
:title="$i18n.getHelperTitle('tainacan-numeric', 'min')"
:message="$i18n.getHelperMessage('tainacan-numeric', 'min')" />
</label>
<b-numberinput
v-model="min"
name="min"
step="1"
@input="onUpdateMin"/>
</b-field>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-numeric', 'max') }}
<help-button
:title="$i18n.getHelperTitle('tainacan-numeric', 'max')"
:message="$i18n.getHelperMessage('tainacan-numeric', 'max')" />
</label>
<b-numberinput
v-model="max"
name="max"
step="1"
@input="onUpdateMax"/>
</b-field>
</section>
</template>
@ -80,15 +106,25 @@
data() {
return {
step: [Number, String],
min: [Number, null],
max: [Number, null],
showEditStepOptions: false
}
},
created() {
this.step = this.value && this.value.step ? this.value.step : 0.01;
this.min = this.value && this.value.min ? Number(this.value.min) : null;
this.max = this.value && this.value.max ? Number(this.value.max) : null;
},
methods: {
onUpdateStep(value) {
this.$emit('input', { step: value });
this.$emit('input', { step: value, min: this.min, max: this.max });
},
onUpdateMin(value) {
this.$emit('input', { step: this.step, min: value, max: this.max });
},
onUpdateMax(value) {
this.$emit('input', { step: this.step, min: this.min, max: value });
}
}
}

View File

@ -1,15 +1,17 @@
<template>
<b-input
<b-numberinput
:disabled="disabled"
:ref="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : ''"
:value="value"
@input="onInput($event);"
@input="onInput"
@blur="onBlur"
@focus="onMobileSpecialFocus"
type="number"
lang="en"
:step="getStep"/>
:min="getMin"
:max="getMax"
:step="getStep" />
</template>
<script>
@ -25,10 +27,26 @@
return this.itemMetadatum.metadatum.metadata_type_options.step;
else
return 0.01;
},
getMin() {
if (this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.min !== null && this.itemMetadatum.metadatum.metadata_type_options.min !== undefined && this.itemMetadatum.metadatum.metadata_type_options.min !== '')
return Number(this.itemMetadatum.metadatum.metadata_type_options.min);
else
return undefined;
},
getMax() {
if (this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.max !== null && this.itemMetadatum.metadatum.metadata_type_options.max !== undefined && this.itemMetadatum.metadatum.metadata_type_options.max !== '')
return Number(this.itemMetadatum.metadatum.metadata_type_options.max);
else
return undefined;
}
},
methods: {
onInput(value) {
const inputRef = this.$refs['tainacan-item-metadatum_id-' + this.itemMetadatum.metadatum.id + (this.itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + this.itemMetadatum.parent_meta_id) : '')];
if ( inputRef && !inputRef.checkHtml5Validity())
return;
this.$emit('input', value);
},
onBlur() {
@ -40,3 +58,10 @@
}
}
</script>
<style scoped>
.b-numberinput {
border-bottom-width: 0px !important;
margin-left: 0 !important;
}
</style>

View File

@ -34,6 +34,14 @@ class Numeric extends Metadata_Type {
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on the metadatum control buttons. This also defines whether the input accepts decimal numbers.', 'tainacan' ),
],
'min' => [
'title' => __( 'Minimum', 'tainacan' ),
'description' => __( 'The minimum value that the input will accept.', 'tainacan' ),
],
'max' => [
'title' => __( 'Maximum', 'tainacan' ),
'description' => __( 'The maximum value that the input will accept.', 'tainacan' ),
]
];
}

View File

@ -25,7 +25,7 @@
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : $i18n.get('instruction_type_existing_item')"
:loading="isLoading"
:aria-close-label="$i18n.get('remove_value')"
:class="{'has-selected': selected != undefined && selected != []}"
:class="{ 'has-selected': selected != undefined && selected != [] }"
field="label"
@typing="search"
check-infinite-scroll

View File

@ -33,7 +33,7 @@
disabled: false,
},
computed: {
getOptions(){
getOptions() {
if (this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.options ) {
const metadata = this.itemMetadatum.metadatum.metadata_type_options.options;
return ( metadata ) ? metadata.split("\n") : [];

View File

@ -1,12 +1,10 @@
<template>
<div>
<taxonomy-tag-input
<tainacan-taxonomy-tag-input
v-if="getComponent == 'tainacan-taxonomy-tag-input'"
:disabled="disabled"
:is="getComponent"
:disabled="disabled || isFetchingTerms"
: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="allowNewFromOptions"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : $i18n.get('instruction_type_existing_term')"
:taxonomy-id="taxonomyId"
@ -48,41 +46,43 @@
</a>
</div>
<!-- Term creation modal, used on admin for a complete term creation -->
<b-modal
v-model="isTermCreationModalOpen"
: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
:metadatum-id="itemMetadatum.metadatum.id"
:item-id="itemMetadatum.item.id"
:is-hierarchical="isHierarchical"
:taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
:is-term-insertion-flow="true"
@onEditionFinished="($event) => addRecentlyCreatedTerm($event.term)"
@onEditionCanceled="() => $console.log('Editing canceled')"
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
</b-modal>
<template v-if="allowNew && itemMetadatum.item">
<!-- Term creation modal, used on admin for a complete term creation -->
<b-modal
v-model="isTermCreationModalOpen"
: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
:metadatum-id="itemMetadatum.metadatum.id"
:item-id="itemMetadatum.item.id"
:is-hierarchical="isHierarchical"
:taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
:is-term-insertion-flow="true"
@onEditionFinished="($event) => addRecentlyCreatedTerm($event.term)"
@onEditionCanceled="() => $console.log('Editing 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
:metadatum-id="itemMetadatum.metadatum.id"
:item-id="itemMetadatum.item.id"
:is-hierarchical="isHierarchical"
v-if="isTermCreationPanelOpen"
:taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
@onEditionFinished="($event) => addTermToBeCreated($event)"
@onEditionCanceled="() => isTermCreationPanelOpen = false"
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
</transition>
<!-- Term creation panel, used on item submission block for a simpler term creation -->
<transition name="filter-item">
<term-creation-panel
:metadatum-id="itemMetadatum.metadatum.id"
:item-id="itemMetadatum.item.id"
:is-hierarchical="isHierarchical"
v-if="isTermCreationPanelOpen"
:taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
@onEditionFinished="($event) => addTermToBeCreated($event)"
@onEditionCanceled="() => isTermCreationPanelOpen = false"
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
</transition>
</template>
</div>
</template>
@ -90,6 +90,7 @@
import TainacanTaxonomyTagInput from './TaxonomyTaginput.vue';
import CheckboxRadioMetadataInput from '../../other/checkbox-radio-metadata-input.vue';
import { tainacan as axios } from '../../../js/axios.js';
import { mapActions } from 'vuex';
export default {
components: {
@ -103,7 +104,6 @@
forcedComponentType: '',
maxtags: '',
allowNew: false,
allowSelectToCreate: false,
isMobileScreen: false,
},
data(){
@ -116,7 +116,8 @@
isTermCreationModalOpen: false,
isTermCreationPanelOpen: false,
newTermName: '',
allowNewFromOptions: false
allowNewFromOptions: false,
isFetchingTerms: false
}
},
computed: {
@ -171,15 +172,48 @@
this.getTermsId();
},
methods: {
...mapActions('taxonomy', [
'fetchTerms'
]),
getTermsId() {
let values = [];
if (this.value && this.itemMetadatum.metadatum && this.getComponent != 'tainacan-taxonomy-tag-input') {
if ( this.value && this.itemMetadatum.metadatum && this.getComponent != 'tainacan-taxonomy-tag-input' ) {
values = this.value.map(term => term.id).filter(term => term !== undefined);
this.valueComponent = (values.length > 0 && this.itemMetadatum.metadatum && this.itemMetadatum.metadatum.multiple === 'no') ? values[0] : values;
} else if (this.value && this.itemMetadatum.metadatum && this.getComponent == 'tainacan-taxonomy-tag-input') {
values = this.value.map((term) => { return { label: term.name, value: term.id } });
this.valueComponent = values;
// This first scenario happens in the item edition form, as the item metadata returns the terms as objects
if ( this.value[0] && this.value[0] && this.value[0].id ) {
values = this.value.map((term) => { return { label: term.name, value: term.id } });
this.valueComponent = values;
// If the term is not returned as object, we're in bulk edition modal or in the metadata section condition metadata input, where value is a an array of IDs
} else if ( this.value.length ) {
this.isFetchingTerms = true;
this.fetchTerms({
taxonomyId: this.taxonomyId,
fetchOnly: {
fetch_only: {
0: 'name',
1: 'id'
}
},
all: true,
include: this.value
}).then((res) => {
values = res.terms.map((term) => { return { label: term.name, value: term.id } });
this.valueComponent = values;
this.isFetchingTerms = false;
}).catch((error) => {
this.isFetchingTerms = false;
throw error;
});
} else {
this.valueComponent = [];
}
}
},
addRecentlyCreatedTerm(term) {

View File

@ -5,12 +5,11 @@
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
size="is-small"
icon="magnify"
:allow-new="false"
@add="emitAdd"
@remove="emitRemove"
v-model="selected"
:data="labels"
:maxtags="maxtags"
:data="options"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : '1')"
field="label"
:remove-on-keys="[]"
:dropdown-position="isLastMetadatum ? 'top' :'auto'"
@ -21,10 +20,12 @@
:loading="isFetching"
:class="{ 'has-selected': selected != undefined && selected != [] }"
autocomplete
@typing="loadTerms"
@typing="search"
check-infinite-scroll
@infinite-scroll="loadMoreTerms"
:has-counter="false">
@infinite-scroll="searchMore"
:has-counter="false"
:append-to-body="!itemMetadatum.item"
:open-on-focus="false">
<template slot-scope="props">
<div class="media">
<div class="media-content">
@ -33,12 +34,12 @@
</div>
</template>
<template
v-if="!isFetching"
v-if="!isFetching && options.length <= 0 && searchName.length > 0"
slot="empty">
{{ $i18n.get('info_no_terms_found') }}
</template>
<template
v-if="allowNew"
v-if="allowNew && !isFetching && searchName.length > 0"
slot="footer">
<a @click="$emit('showAddNewTerm', { name: searchName })">
{{ $i18n.get('label_create_new_term') + ' "' + searchName + '"' }}
@ -57,55 +58,64 @@
allowNew: Boolean,
taxonomyId: Number,
disabled: false,
allowSelectToCreate: false,
maxtags: '',
isLastMetadatum: false
},
data() {
return {
selected: [],
labels: [],
options: [],
isFetching: false,
offset: 0,
searchName: '',
totalTerms: 0
}
},
computed: {
maxMultipleValues() {
return (
this.itemMetadatum &&
this.itemMetadatum.metadatum &&
this.itemMetadatum.metadatum.cardinality &&
!isNaN(this.itemMetadatum.metadatum.cardinality) &&
this.itemMetadatum.metadatum.cardinality > 1
) ? this.itemMetadatum.metadatum.cardinality : undefined;
},
},
watch: {
selected() {
if (this.allowSelectToCreate && this.selected[0]) {
this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`);
this.selected[0].label = this.selected[0].label.split('(')[0];
}
value() {
if ( this.value && this.value.length > 0 && this.value[0].label )
this.selected = JSON.parse(JSON.stringify(this.value));
}
},
created() {
if (this.value && this.value.length > 0)
this.selected = this.value;
mounted() {
if ( this.value && this.value.length > 0 && this.value[0].label )
this.selected = JSON.parse(JSON.stringify(this.value));
},
methods: {
...mapActions('taxonomy', [
'fetchTerms'
]),
loadTerms: _.debounce( function(value) {
search: _.debounce( function(value) {
// String update
if (value != this.searchName) {
if ( value != this.searchName ) {
this.searchName = value;
this.labels = [];
this.options = [];
this.offset = 0;
}
// String cleared
if (!value.length) {
if ( !value.length ) {
this.searchName = value;
this.labels = [];
this.options = [];
this.offset = 0;
return;
}
// No need to load more
if (this.offset > 0 && this.labels.length >= this.totalTerms)
return
if ( this.offset > 0 && this.options.length >= this.totalTerms )
return;
this.isFetching = true;
@ -128,10 +138,7 @@
}).then((res) => {
for (let term of res.terms)
this.labels.push({ label: term.name, value: term.id });
if (res.terms.length <= 0 && this.allowSelectToCreate)
this.labels.push({ label: `${value} (${this.$i18n.get('select_to_create')})`, value: value })
this.options.push({ label: term.name, value: term.id });
this.offset += 12;
this.totalTerms = res.total;
@ -142,8 +149,8 @@
throw error;
});
}, 500),
loadMoreTerms: _.debounce(function () {
this.loadTerms(this.searchName)
searchMore: _.debounce(function () {
this.search(this.searchName)
}, 250),
updateSelectedValues(){
let selected = [];

View File

@ -14,6 +14,19 @@
:title="$i18n.getHelperTitle('tainacan-text', 'display_suggestions')"
:message="$i18n.getHelperMessage('tainacan-text', 'display_suggestions')"/>
</b-field>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-text', 'mask') }}
<help-button
:title="$i18n.getHelperTitle('tainacan-text', 'mask')"
:message="$i18n.getHelperMessage('tainacan-text', 'mask')" />
</label>
<b-input
:value="displaySuggestions === 'yes' ? '' : mask"
:disabled="displaySuggestions === 'yes'"
name="mask"
@input="onUpdateMask" />
</b-field>
</section>
</template>
@ -24,16 +37,22 @@
},
data() {
return {
displaySuggestions: String
displaySuggestions: String,
mask: String
}
},
created() {
this.displaySuggestions = this.value && this.value.display_suggestions ? this.value.display_suggestions : 'no';
this.mask = this.value && this.value.mask ? this.value.mask : '';
},
methods: {
onUpdateDisplaySuggestions(value) {
this.displaySuggestions = value;
this.$emit('input', { display_suggestions: value });
this.$emit('input', { display_suggestions: value, mask: value == 'yes' ? '' : this.mask });
},
onUpdateMask(value) {
this.mask = value;
this.$emit('input', { display_suggestions: this.displaySuggestions, mask: value });
}
}
}

View File

@ -1,14 +1,20 @@
<template>
<div>
<b-input
<div
v-if="!getDisplayAutocomplete"
:disabled="disabled"
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:value="value"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : ''"
@input="onInput($event)"
@blur="onBlur"
@focus="onMobileSpecialFocus" />
class="control is-clearfix">
<input
class="input"
:disabled="disabled"
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:value="value"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : ''"
@focus="onMobileSpecialFocus"
v-imask="getMask"
@complete="($event) => getMask ? onInput($event.detail.value) : null"
@input="($event) => getMask ? null : onInput($event.target.value)"
@blur="onBlur" >
</div>
<b-autocomplete
v-else
:disabled="disabled"
@ -44,8 +50,12 @@
<script>
import { isCancel } from '../../../js/axios';
import { dynamicFilterTypeMixin } from '../../../js/filter-types-mixin';
import { IMaskDirective } from 'vue-imask';
export default {
directives: {
imask: IMaskDirective
},
mixins: [dynamicFilterTypeMixin],
props: {
itemMetadatum: Object,
@ -72,6 +82,15 @@
return this.itemMetadatum.metadatum.metadata_type_options.display_suggestions == 'yes';
else
return false;
},
getMask() {
if (this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.mask)
return {
mask: this.itemMetadatum.metadatum.metadata_type_options.mask,
lazy: false
};
else
return false;
}
},
created() {

View File

@ -35,6 +35,14 @@ class Text extends Metadata_Type {
'display_suggestions' => [
'title' => __( 'Display suggestions', 'tainacan' ),
'description' => __( 'Show an autocomplete input suggesting values inserted previously on other items for this metadatum.', 'tainacan' ),
],
'mask' => [
'title' => __( 'Mask input', 'tainacan' ),
'description' => sprintf(
__( 'Define a pattern that will be used to mask the input. Learn how to build mask patterns <a target="_blank" href="%1$s">here</a> or, for a more advanced usage, type a <a target="_blank" href="%2$s">Regular Expression</a>.', 'tainacan' ),
'https://imask.js.org/guide.html#masked-pattern',
'https://en.wikipedia.org/wiki/Regular_expression'
)
]
];
}

View File

@ -0,0 +1,50 @@
<template>
<section>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-textarea', 'maxlength') }}
<help-button
:title="$i18n.getHelperTitle('tainacan-textarea', 'maxlength')"
:message="$i18n.getHelperMessage('tainacan-textarea', 'maxlength')" />
</label>
<b-numberinput
v-model="maxlength"
name="maxlength"
step="1"
min="0"
@input="onUpdateMaxlength"/>
</b-field>
</section>
</template>
<script>
export default {
props: {
value: [ String, Object, Array ]
},
data() {
return {
maxlength: [Number, null]
}
},
created() {
this.maxlength = this.value && this.value.maxlength ? Number(this.value.maxlength) : null;
},
methods: {
onUpdateMaxlength(value) {
if (value == 0) value = null;
this.$emit('input', { maxlength: value });
}
}
}
</script>
<style scoped>
section{
margin-bottom: 10px;
}
.tainacan-help-tooltip-trigger {
font-size: 1em;
}
</style>

View File

@ -1,13 +1,15 @@
<template>
<b-input
:disabled="disabled"
:ref="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : ''"
:value="value"
@input="onInput($event)"
@blur="onBlur"
type="textarea"
@focus="onMobileSpecialFocus" />
@focus="onMobileSpecialFocus"
:maxlength="getMaxlength" />
</template>
<script>
@ -17,8 +19,20 @@
value: [String, Number, Array],
disabled: false
},
computed: {
getMaxlength() {
if (this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.maxlength !== null && this.itemMetadatum.metadatum.metadata_type_options.maxlength !== undefined && this.itemMetadatum.metadatum.metadata_type_options.maxlength !== '')
return Number(this.itemMetadatum.metadatum.metadata_type_options.maxlength);
else
return undefined;
}
},
methods: {
onInput(value) {
const inputRef = this.$refs['tainacan-item-metadatum_id-' + this.itemMetadatum.metadatum.id + (this.itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + this.itemMetadatum.parent_meta_id) : '')];
if ( inputRef && this.getMaxlength && !inputRef.checkHtml5Validity() )
return;
this.$emit('input', value);
},
onBlur() {

View File

@ -15,6 +15,7 @@ class Textarea extends Metadata_Type {
parent::__construct();
$this->set_primitive_type('long_string');
$this->set_component('tainacan-textarea');
$this->set_form_component('tainacan-form-textarea');
$this->set_name( __('Textarea', 'tainacan') );
$this->set_description( __('A textarea with multiple lines', 'tainacan') );
$this->set_preview_template('
@ -27,6 +28,18 @@ class Textarea extends Metadata_Type {
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'maxlength' => [
'title' => __( 'Maximum of characters', 'tainacan' ),
'description' => __( 'Limits the character input to a maximum value an displays a counter.', 'tainacan' ),
]
];
}
public function get_multivalue_prefix() {
return '<p>';
}

View File

@ -92,7 +92,6 @@
:forced-component-type="bulkEditionProcedures[criterion].metadatum.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:item-metadatum="{ metadatum: bulkEditionProcedures[criterion].metadatum }"
:allow-new="false"
:allow-select-to-create="false"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
@ -111,7 +110,6 @@
:forced-component-type="bulkEditionProcedures[criterion].metadatum.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:item-metadatum="{ metadatum: bulkEditionProcedures[criterion].metadatum }"
:allow-new="false"
:allow-select-to-create="bulkEditionProcedures[criterion].metadatum.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
@ -197,7 +195,6 @@
:forced-component-type="bulkEditionProcedures[criterion].metadatum.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:item-metadatum="{ metadatum: bulkEditionProcedures[criterion].metadatum }"
:allow-new="false"
:allow-select-to-create="bulkEditionProcedures[criterion].metadatum.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:class="{ 'is-field-history': bulkEditionProcedures[criterion].isDone }"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-last"
@ -213,7 +210,7 @@
:style="{
marginRight: !bulkEditionProcedures[criterion].isDone && !bulkEditionProcedures[criterion].isExecuting ? '-7.4px': 0
}"
class="field buttons-r-bulk">
class="field bulk-last-field">
<button
v-if="!bulkEditionProcedures[criterion].isDone && !bulkEditionProcedures[criterion].isExecuting"
@ -643,7 +640,7 @@
padding-left: 0 !important;
}
.buttons-r-bulk {
.bulk-last-field {
margin-left: 0 !important;
justify-content: center !important;
}
@ -786,9 +783,26 @@
&:not(:first-child) {
padding-left: 13px;
}
/deep/ .is-special-hidden-for-mobile,
/deep/ .is-special-hidden-for-mobile:focus,
/deep/ .is-special-hidden-for-mobile:focus-visible {
opacity: 0;
width: 0;
height: 0 !important;
min-height: 0;
min-width: 0;
padding: 0 !important;
line-height: 0px !important;
border: none !important;
border-color: transparent !important;
border-width: 0px !important;
font-size: 0px !important;
display: block !important;
}
}
.buttons-r-bulk {
.bulk-last-field {
display: flex;
align-items: center;
height: 32px;

View File

@ -179,7 +179,7 @@ export default {
max-height: 100vh;
overflow: auto;
z-index: 9;
max-width: 10em;
max-width: 11em;
-webkit-transition: max-width 0.2s linear; /* Safari */
transition: max-width 0.2s linear;

View File

@ -192,7 +192,7 @@
}
.logo-area {
height: $header-height;
min-width: 10em;
min-width: 11em;
cursor: pointer;
h1 {

View File

@ -168,7 +168,7 @@ export default {
padding-top: 10px;
padding-bottom: 10px;
padding-right: 0;
padding-left: calc((var(--tainacan-one-column) - 6.666666667px) + 10em);
padding-left: calc((var(--tainacan-one-column) - 6.666666667px) + 11em);
margin: 0px;
display: flex;
vertical-align: middle;

View File

@ -187,7 +187,9 @@
:id="`${key}.${index}-tainacan-li-checkbox-model`"
:ref="`${key}.${index}-tainacan-li-checkbox-model`"
:key="index">
<label class="b-checkbox checkbox">
<label
@click="option.total_children > 0 && (!finderColumns[key + 1] || finderColumns[key + 1].label !== option.label) ? getOptionChildren(option, key, index) : null"
class="b-checkbox checkbox">
<input
@input="$emit('input', $event.target.value)"
:value="(isNaN(Number(option.value)) ? option.value : Number(option.value))"
@ -829,8 +831,8 @@
this.$emit('appliedCheckBoxModal');
},
renderHierarchicalPath(hierachyPath, label) {
return '<span style="color: var(--tainacan-info-color);">' + hierachyPath.replace(/>/g, '&nbsp;<span class="hierarchy-separator"> &gt; </span>&nbsp;') + '</span>' + label;
renderHierarchicalPath(hierarchyPath, label) {
return '<span style="color: var(--tainacan-info-color);">' + hierarchyPath.replace(/>/g, '&nbsp;<span class="hierarchy-separator"> &gt; </span>&nbsp;') + '</span>' + label;
}
}
}

View File

@ -196,7 +196,8 @@
'b-checkbox checkbox': isCheckbox,
'b-radio radio': !isCheckbox,
'is-disabled': !isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)
}" >
}"
@click="option.total_children > 0 && (!finderColumns[key + 1] || finderColumns[key + 1].label !== option.label) ? getOptionChildren(option, key, index) : null">
<input
:disabled="!isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)"
@input="updateLocalSelection($event.target.value)"
@ -305,8 +306,8 @@
</div>
</b-tab-item>
</b-tabs>
<!-- <pre>{{ hierarchicalPath }}</pre>
<pre>{{ finderColumns }}</pre> -->
<!-- <pre>{{ hierarchicalPath }}</pre> -->
<!-- <pre>{{ finderColumns }}</pre> -->
<!--<pre>{{ totalRemaining }}</pre>-->
<!-- <pre>{{ selected }}</pre> -->
<!--<pre>{{ options }}</pre>-->
@ -444,7 +445,11 @@
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.saveSelectedTagName(
term.id,
!this.isCheckbox && term.hierarchy_path ? ( term.hierarchy_path + term.name ) : term.name,
term.url
);
this.isSelectedTermsLoading = false;
})
@ -803,15 +808,15 @@
});
}
},
renderHierarchicalPath(hierachyPath, label) {
return '<span style="color: var(--tainacan-info-color);">' + hierachyPath.replace(/>/g, '&nbsp;<span class="hierarchy-separator"> &gt; </span>&nbsp;') + '</span>' + label;
renderHierarchicalPath(hierarchyPath, label) {
return '<span style="color: var(--tainacan-info-color);">' + hierarchyPath.replace(/>/g, '&nbsp;<span class="hierarchy-separator"> &gt; </span>&nbsp;') + '</span>' + label;
},
onMobileSpecialFocus($event) {
$event.target.blur();
this.$emit('mobileSpecialFocus');
},
isOptionSelected(optionValue) {
if (Array.isArray(this.selected))
if ( Array.isArray(this.selected) )
return (this.selected.indexOf((isNaN(Number(optionValue)) ? optionValue : Number(optionValue))) >= 0)
else
return optionValue == this.selected;
@ -1211,7 +1216,7 @@
padding: 0px !important;
display: inline;
.control {
.field.is-grouped > .control:not(:last-child) {
margin-bottom: 0.25rem;
margin-right: 0.25rem;
}
@ -1223,6 +1228,11 @@
section p {
font-size: 0.875em;
}
/deep/ .field {
padding: 0.25rem !important;
margin: 0 !important;
}
}
.tainacan-modal-checkbox-search-results-body {

View File

@ -48,6 +48,7 @@ import User from '../components/metadata-types/user/User.vue';
import GeoCoordinate from '../components/metadata-types/geocoordinate/GeoCoordinate.vue'
import FormText from '../components/metadata-types/text/FormText.vue';
import FormTextarea from '../components/metadata-types/textarea/FormTextarea.vue';
import FormRelationship from '../components/metadata-types/relationship/FormRelationship.vue';
import FormTaxonomy from '../components/metadata-types/taxonomy/FormTaxonomy.vue';
import FormSelectbox from '../components/metadata-types/selectbox/FormSelectbox.vue';
@ -202,6 +203,7 @@ export default (element) => {
/* Metadata Option forms */
Vue.component('tainacan-form-text', FormText);
Vue.component('tainacan-form-textarea', FormTextarea);
Vue.component('tainacan-form-relationship', FormRelationship);
Vue.component('tainacan-form-taxonomy', FormTaxonomy);
Vue.component('tainacan-form-selectbox', FormSelectbox);

View File

@ -142,6 +142,7 @@ UserPrefsPlugin.install = function (Vue, options = {}) {
'taxonomies_order_by': 'title',
'collections_order': 'desc',
'collections_order_by': 'date',
'collections_author_filter': '',
'map_view_mode_selected_geocoordinate_metadatum': 0
},
init() {

View File

@ -98,7 +98,7 @@ export const eventBusItemMetadata = new Vue({
for (let conditionalSectionId in updatedConditionalSections) {
if ( updatedConditionalSections[conditionalSectionId].metadatumId == metadatumId ) {
const conditionalValues = Array.isArray(updatedConditionalSections[conditionalSectionId].metadatumValues) ? updatedConditionalSections[conditionalSectionId].metadatumValues : [ this.conditionalSections[conditionalSectionId].metadatumValues ];
updatedConditionalSections[conditionalSectionId].hide = values.every(aValue => conditionalValues.indexOf(aValue) < 0);
updatedConditionalSections[conditionalSectionId].hide = Array.isArray(values) ? values.every(aValue => conditionalValues.indexOf(aValue) < 0) : conditionalValues.indexOf(values) < 0 ;
}
}
this.conditionalSections = updatedConditionalSections;

View File

@ -149,6 +149,10 @@ export default {
this.$store.dispatch('search/set_postquery', this.$route.query);
}
// Finally, loads items even berfore facets so they won't stuck them
if (to.fullPath != from.fullPath)
this.loadItems();
// Checks current metaqueries and taxqueries to alert filters that should reload
// For some reason, this process is not working accessing to.query, so we need to check the path string.
const oldQueryString = from.fullPath.replace(from.path + '?', '');
@ -174,10 +178,6 @@ export default {
) {
this.$emit('has-to-reload-facets', true);
}
// Finally, loads items
if (to.fullPath != from.fullPath)
this.loadItems();
}
}
},

View File

@ -146,7 +146,7 @@ export const deleteItem = ({ commit }, { itemId, isPermanently }) => {
});
};
export const fetchCollections = ({commit} , { page, collectionsPerPage, status, contextEdit, order, orderby, search, collectionTaxonomies }) => {
export const fetchCollections = ({commit} , { page, collectionsPerPage, status, contextEdit, order, orderby, search, collectionTaxonomies, authorid }) => {
return new Promise((resolve, reject) => {
let endpoint = '/collections?paged='+page+'&perpage='+collectionsPerPage;
@ -187,6 +187,9 @@ export const fetchCollections = ({commit} , { page, collectionsPerPage, status,
endpoint = endpoint + '&' + qs.stringify(taxQuery);
}
if (authorid != '' && authorid != undefined)
endpoint = endpoint + '&authorid=' + authorid;
axios.tainacan.get(endpoint)
.then(res => {
let collections = res.data;

View File

@ -123,7 +123,7 @@ export const fetchTaxonomyName = ({ commit }, taxonomyId) => {
};
// TAXONOMY TERMS
export const fetchTerms = ({}, {taxonomyId, fetchOnly, search, all, order, offset, number, exclude }) => {
export const fetchTerms = ({}, {taxonomyId, fetchOnly, search, all, order, offset, number, exclude, include }) => {
let query = '';
@ -148,6 +148,9 @@ export const fetchTerms = ({}, {taxonomyId, fetchOnly, search, all, order, offse
if (exclude != undefined)
query += '&' + qs.stringify({ exclude: exclude });
if (include != undefined)
query += '&' + qs.stringify({ include: include });
return new Promise((resolve, reject) => {
axios.tainacan.get(`/taxonomy/${taxonomyId}/terms${query}`)
.then(res => {

View File

@ -420,7 +420,7 @@
.header-item {
margin-bottom: 0 !important;
min-height: 2em;
min-height: 1.875em;
display: flex;
align-items: center;

View File

@ -199,10 +199,9 @@
top: calc(-1 * var(--tainacan-container-padding));
z-index: 2;
background: var(--tainacan-background-color);
min-height: $header-height;
min-height: 2.5em;
padding: 0.5em 0;
height: auto;
padding-left: 0;
padding-right: 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
@ -212,7 +211,7 @@
.header-item {
margin-bottom: 0 !important;
min-height: 2em;
min-height: 1.875em;
&:first-child {
margin-right: auto;

View File

@ -102,8 +102,27 @@
</b-field>
</template>
<!-- Author filtering options ---- -->
<b-field
id="collections-page-author-filter"
class="header-item">
<label class="label">{{ $i18n.get('label_show_only_created_by_me') }}&nbsp;</label>
<b-switch
size="is-small"
class="author-filter-switch"
:disabled="collections.length <= 0 && isLoading"
@input="onChangeAuthorFilter($event)"
:value="authorFilter"
:true-value="'current-author'"
:false-value="''"
:label="$i18n.get('label_show_only_created_by_me')" />
</b-field>
<!-- Sorting options ---- -->
<b-field class="header-item">
<b-field
id="collections-page-sorting-options"
class="header-item">
<label class="label">{{ $i18n.get('label_sort') }}&nbsp;</label>
<b-dropdown
:mobile-modal="true"
@ -172,7 +191,9 @@
</b-field>
<!-- Textual Search -------------->
<b-field class="header-item">
<b-field
id="collection-page-search"
class="header-item">
<b-input
:placeholder="$i18n.get('instruction_search')"
type="search"
@ -252,6 +273,8 @@
</p>
<p v-if="status == undefined || status == ''">{{ $i18n.get('info_no_collection_created') }}</p>
<p v-else>{{ $i18n.get('info_no_collections_' + status) }}</p>
<p v-if="searchQuery">{{ $i18n.get('info_try_empting_the_textual_search') }}</p>
<p v-if="authorFilter !== '' && !searchQuery">{{ $i18n.get('info_try_selecting_all_collections_in_filter') }}</p>
<div v-if="!$adminOptions.hideCollectionsListCreationDropdown && $userCaps.hasCapability('tnc_rep_edit_collections') && status == undefined || status == ''">
<b-dropdown
id="collection-creation-options-dropdown"
@ -372,6 +395,7 @@ export default {
order: 'desc',
orderBy: 'date',
searchQuery: '',
authorFilter: '',
sortingOptions: [
{ label: this.$i18n.get('label_title'), value: 'title' },
{ label: this.$i18n.get('label_creation_date'), value: 'date' },
@ -439,6 +463,13 @@ export default {
this.$userPrefs.set('collections_order_by', 'date');
}
if (this.authorFilter != this.$userPrefs.get('collections_author_filter'))
this.authorFilter = this.$userPrefs.get('collections_author_filter');
if (this.authorFilter === undefined) {
this.authorFilter = '';
this.$userPrefs.set('collections_author_filter', '');
}
this.loadCollections();
},
methods: {
@ -483,6 +514,19 @@ export default {
this.orderBy = newOrderBy;
this.loadCollections();
},
onChangeAuthorFilter(newAuthorFilter) {
if (newAuthorFilter != this.authorFilter) {
this.$userPrefs.set('collections_author_filter', newAuthorFilter)
.then((newAuthorFilter) => {
this.authorFilter = newAuthorFilter;
})
.catch(() => {
this.$console.log("Error settings user prefs for collections author filter")
});
}
this.authorFilter = newAuthorFilter;
this.loadCollections();
},
onChangeCollectionsPerPage(value) {
if (value != this.collectionsPerPage) {
@ -521,6 +565,7 @@ export default {
orderby: this.orderBy,
search: this.searchQuery,
collectionTaxonomies: this.collectionTaxonomies,
authorid: this.authorFilter === 'current-author' && tainacan_plugin.user_data && tainacan_plugin.user_data.ID ? tainacan_plugin.user_data.ID : ''
})
.then((res) => {
this.isLoading = false;
@ -568,20 +613,20 @@ export default {
@import '../../scss/_variables.scss';
.sub-header {
min-height: $header-height;
min-height: 2.5em;
padding: 0.5em 0;
height: auto;
padding-left: 0;
padding-right: 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
width: 100%;
gap: 4px;
.header-item {
margin-bottom: 0 !important;
min-height: 2em;
min-height: 1.875em;
&:first-child {
margin-right: auto;
@ -593,9 +638,11 @@ export default {
.label {
font-size: 0.875em;
font-weight: normal;
margin-top: 5px;
margin-top: 2px;
margin-bottom: 2px;
cursor: default;
display: flex;
align-items: center;
}
&:not(:first-child) {
@ -629,7 +676,9 @@ export default {
font-size: 1.125em !important;
height: 1.75em
}
.collections-page-author-filter {
display: flex;
}
.dropdown-menu {
display: block;
@ -660,7 +709,6 @@ export default {
}
@media screen and (max-width: 769px) {
height: 120px;
margin-top: -0.5em;
padding-top: 0.9em;

View File

@ -387,10 +387,9 @@
@import '../../scss/_variables.scss';
.sub-header {
min-height: $header-height;
height: auto;
padding-left: 0;
padding-right: 0;
min-height: 2.5em;
padding: 0.5em 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
@ -400,7 +399,7 @@
.header-item {
margin-bottom: 0 !important;
min-height: 2em;
min-height: 1.875em;
&:first-child {
margin-right: auto;

View File

@ -46,8 +46,13 @@ button.link-style:active {
background: var(--tainacan-success) !important;
color: var(--tainacan-white) !important;
}
&.is-white, &.is-white:hover, &.is-white:focus, &.is-outlined:hover, &.is-outlined:focus {
background-color: transparent !important;
&.is-white,
&.is-outlined:hover, &.is-outlined:focus {
transition: background-color 0.2s ease-out;
background-color: rgba(125,125,125,0.0) !important;
}
&.is-white:hover, &.is-white:focus {
background-color: rgba(125,125,125,0.05) !important;
}
&.is-loading, &.is-loading:hover, &.is-loading:focus,
&.is-loading.is-success, &.is-loading.is-success:hover, &.is-loading.is-success:focus,

View File

@ -150,10 +150,14 @@
background-color: var(--tainacan-success) !important;
color: var(--tainacan-white) !important;
}
.is-white,
.is-white {
color: var(--tainacan-black) !important;
transition: background-color 0.2s ease-out;
background-color: rgba(125,125,125,0.0) !important;
}
.is-white:hover,
.is-white:focus {
background-color: transparent !important;
background-color: rgba(125,125,125,0.05) !important;
color: var(--tainacan-black) !important;
}
.button.is-loading, .button.is-loading:hover, .button.is-loading:focus,

View File

@ -18,7 +18,7 @@
font-family: var(--tainacan-font-family, inherit);
line-height: 1.75em !important;
height: auto !important;
padding: calc(0.375em - 1px) 20px calc(0.375em - 1px) 10px !important;
padding: calc(0.375em - 1px) 24px calc(0.375em - 1px) 10px !important;
margin-top: 0px !important;
margin-bottom: 0px !important;
color: var(--tainacan-input-color);

View File

@ -47,7 +47,7 @@
&.is-narrow {
tbody td {
height: 42px;
height: 44px;
}
}

View File

@ -191,15 +191,15 @@ $checkbox-border-width: 1px;
top: calc(-1 * var(--tainacan-container-padding));
z-index: 2;
background: var(--tainacan-background-color);
min-height: $header-height;
height: auto;
padding-left: 0;
padding-right: 0;
min-height: 2.5em;
padding: 0.5em 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
gap: 4px;
}
// A copy of bootstrap's screen reader only class to be used for accessibility.

View File

@ -542,13 +542,13 @@
<!-- Default loading, to be used view modes without any skeleton-->
<b-loading
v-if="!(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].skeleton_template != undefined)"
v-if="registeredViewModes[viewMode] != undefined && !registeredViewModes[viewMode].implements_skeleton && !registeredViewModes[viewMode].skeleton_template"
:is-full-page="false"
:active.sync="showLoading"/>
<!-- Custom skeleton templates used by some view modes -->
<div
v-if="(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].skeleton_template != undefined)"
v-if="registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].implements_skeleton && registeredViewModes[viewMode].skeleton_template"
v-html="registeredViewModes[viewMode].skeleton_template"/>
</div>

View File

@ -598,6 +598,11 @@
max-width: calc((90vh * 1) / 2);
}
}
.pswp__content {
display: flex;
justify-content: center;
align-content: center;
}
.pswp__content>.tainacan-content-embed:not(.attachment-without-image) {
margin-top: 60px;
}

View File

@ -407,9 +407,6 @@ export default {
'setTaxonomyTerms',
'setReportLatestCachedOn'
]),
...mapActions('metadata', [
'fetchMetadata'
]),
buildMetadatumTermsChart() {
this.isBuildingChart = true;

View File

@ -96,6 +96,7 @@ return apply_filters( 'tainacan-i18n', [
'delete' => __( 'Delete', 'tainacan' ),
'skip' => __( 'Skip', 'tainacan' ),
'add' => __( 'Add', 'tainacan' ),
'show' => __( 'Show', 'tainacan' ),
// Wordpress Comments Status
'comments_status_open' => __( 'Open', 'tainacan' ),
@ -302,6 +303,8 @@ return apply_filters( 'tainacan-i18n', [
/* translators: 'Published' here refers to the sum of public and private items, not including draft or trashed ones. The are visible to those with permission */
'label_all_items' => __( 'All items', 'tainacan' ),
'label_all_collections' => __( 'All collections', 'tainacan' ),
'label_show_only_created_by_me' => __( 'Show only created by me', 'tainacan' ),
'label_collections_that_i_can_edit' => __( 'Collections that I can edit', 'tainacan' ),
'label_all_taxonomies' => __( 'All taxonomies', 'tainacan' ),
'label_bulk_actions' => __( 'Bulk actions', 'tainacan' ),
'label_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -1049,6 +1052,8 @@ return apply_filters( 'tainacan-i18n', [
'info_you_searched_for_%s' => __( 'You searched for %s', 'tainacan' ),
'info_try_enabling_search_by_word' => __( 'Try enabling the search by words.', 'tainacan' ),
'info_try_disabling_search_by_word' => __( 'Try disabling the search by words, to search for the complete phrase.', 'tainacan' ),
'info_try_empting_the_textual_search' => __( 'Try empting the textual search.', 'tainacan' ),
'info_try_selecting_all_collections_in_filter' => __( 'Try selecting All Collections in the filter above.', 'tainacan' ),
'info_details_about_search_by_word' => __( 'They may be located on different metadata and order, but you will still be able to use quotes to group them.', 'tainacan' ),
'info_item_submission_draft_status' => __( 'Warning: draft items may be submitted even without filling all required metadata.', 'tainacan' ),
'info_empty_geocoordinate_metadata_list' => __( 'No geocoordinate metadata was found. Try enabling it in the "displayed metadata" dropdown.', 'tainacan' ),