Merge branch 'release/0.20.3'

This commit is contained in:
vnmedeiros 2023-05-30 17:01:42 -03:00
commit 9ee79dee50
91 changed files with 6853 additions and 4125 deletions

View File

@ -37,6 +37,7 @@ do
case $i in case $i in
--prod) --prod)
is_prod_build=true is_prod_build=true
rm -r ./src/assets/js/*
;; ;;
esac esac
done done

3970
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,70 +1,70 @@
{ {
"name": "tainacan", "name": "tainacan",
"description": "Tainacan", "description": "Tainacan",
"author": "Eduardo <eduardo.humberto1992@gmail.com>", "author": "Tainacan <tainacan.l3p@gmail.com>",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "cross-env NODE_ENV=development webpack --config webpack.dev.js --progress --mode development", "build": "cross-env NODE_ENV=development webpack --config webpack.dev.js --progress --mode development",
"build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js --progress --mode production" "build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js --progress --mode production"
}, },
"dependencies": { "dependencies": {
"apexcharts": "^3.37.1", "apexcharts": "^3.40.0",
"axios": "^1.1.3", "axios": "^1.4.0",
"blurhash": "^2.0.5", "blurhash": "^2.0.5",
"buefy": "^0.9.22", "buefy": "^0.9.23",
"bulma": "^0.9.4", "bulma": "^0.9.4",
"conditioner-core": "^2.3.3", "conditioner-core": "^2.3.3",
"countup.js": "^2.5.0", "countup.js": "^2.6.2",
"css-vars-ponyfill": "^2.4.8", "css-vars-ponyfill": "^2.4.8",
"floating-vue": "^1.0.0-beta.19", "floating-vue": "^1.0.0-beta.19",
"leaflet": "^1.9.3", "leaflet": "^1.9.4",
"leaflet-active-area": "^1.2.1", "leaflet-active-area": "^1.2.1",
"masonry-layout": "^4.2.2", "masonry-layout": "^4.2.2",
"moment": "^2.29.4", "moment": "^2.29.4",
"node-sass": "^7.0.3", "node-sass": "^7.0.3",
"photoswipe": "^5.3.6", "photoswipe": "^5.3.7",
"qs": "^6.11.0", "qs": "^6.11.2",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"swiper": "^8.4.5", "swiper": "^8.4.5",
"t": "^0.5.1",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-apexcharts": "^1.6.2", "vue-apexcharts": "^1.6.2",
"vue-blurhash": "^0.1.4", "vue-blurhash": "^0.1.4",
"vue-countup-v2": "^4.0.0", "vue-countup-v2": "^4.0.0",
"vue-router": "^3.5.4", "vue-router": "^3.6.5",
"vue-the-mask": "^0.11.1", "vue-the-mask": "^0.11.1",
"vue2-leaflet": "^2.7.1", "vue2-leaflet": "^2.7.1",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.18.5", "@babel/core": "^7.21.0",
"@babel/preset-env": "^7.18.2", "@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.17.12", "@babel/preset-react": "^7.18.6",
"@types/leaflet": "^1.9.0", "@types/leaflet": "^1.9.1",
"@types/masonry-layout": "^4.2.5", "@types/masonry-layout": "^4.2.5",
"acorn": "^8.7.1", "acorn": "^8.8.2",
"autoprefixer": "^10.4.7", "ajv": "^7.2.4",
"babel-loader": "^8.2.5", "autoprefixer": "^10.4.14",
"babel-loader": "^9.1.2",
"circular-dependency-plugin": "5.2.2", "circular-dependency-plugin": "5.2.2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "^6.7.1", "css-loader": "^6.7.3",
"eslint": "^8.18.0", "eslint": "^8.35.0",
"eslint-plugin-vue": "^9.1.1", "eslint-plugin-vue": "^9.9.0",
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^4.0.0",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"moment-locales-webpack-plugin": "^1.2.0", "moment-locales-webpack-plugin": "^1.2.0",
"postcss-loader": "7.0.0", "postcss-loader": "7.0.2",
"sass-loader": "^13.0.0", "sass-loader": "^13.2.0",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"terser-webpack-plugin": "5.3.3", "terser-webpack-plugin": "5.3.7",
"vue-loader": "^15.9.8", "vue-loader": "^15.10.1",
"vue-template-compiler": "^2.6.14", "vue-template-compiler": "^2.6.14",
"webpack": "^5.73.0", "webpack": "^5.76.0",
"webpack-bundle-analyzer": "^4.6.1", "webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^4.10.0", "webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.9.2", "webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0" "webpack-merge": "^5.8.0"
} }
} }

View File

@ -224,7 +224,7 @@
.tainacan-media-component__swiper-thumbs li.swiper-slide { .tainacan-media-component__swiper-thumbs li.swiper-slide {
text-align: center; text-align: center;
vertical-align: top; vertical-align: top;
word-break: break-all; word-break: break-word;
font-size: 0.875em; font-size: 0.875em;
max-width: calc(var(--tainacan-media-thumbs-carousel-item-size, 136px) + 17px); } max-width: calc(var(--tainacan-media-thumbs-carousel-item-size, 136px) + 17px); }
@media only screen and (max-width: 380px) { @media only screen and (max-width: 380px) {
@ -255,14 +255,17 @@
.tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__name { .tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__name {
font-size: 1em; font-size: 1em;
color: var(--tainacan-media-metadata-color, #454647); color: var(--tainacan-media-metadata-color, #454647);
opacity: 0.75; } opacity: 0.75;
word-break: break-word; }
.tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__caption { .tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__caption {
font-size: 0.9375em; font-size: 0.9375em;
color: var(--tainacan-media-metadata-color, #454647); } color: var(--tainacan-media-metadata-color, #454647);
word-break: break-word; }
.tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__caption { .tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata__caption {
font-size: 0.875em; font-size: 0.875em;
color: var(---tainacan-media-metadata-color, #454647); color: var(---tainacan-media-metadata-color, #454647);
opacity: 0.85; } opacity: 0.85;
word-break: break-word; }
.tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata { .tainacan-media-component__swiper-thumbs li.swiper-slide .swiper-slide-metadata {
text-align: center; text-align: center;
display: block; display: block;

File diff suppressed because one or more lines are too long

View File

@ -93,6 +93,7 @@ class REST_Controller extends \WP_REST_Controller {
'hierarchical' => 'hierarchical', 'hierarchical' => 'hierarchical',
'exclude' => 'post__not_in', 'exclude' => 'post__not_in',
'excludetree' => 'exclude_tree', 'excludetree' => 'exclude_tree',
'exclude_tree' => 'exclude_tree',
'include' => 'include', 'include' => 'include',
'sentence' => 'sentence' 'sentence' => 'sentence'
]; ];

View File

@ -251,9 +251,9 @@ class REST_Collections_Controller extends REST_Controller {
* @return mixed|string|void|\WP_Error|\WP_REST_Response * @return mixed|string|void|\WP_Error|\WP_REST_Response
*/ */
public function prepare_item_for_response($item, $request){ public function prepare_item_for_response($item, $request){
if(!empty($item)){ if ( !empty($item) ) {
if(!isset($request['fetch_only'])) { if( !isset($request['fetch_only']) ) {
$item_arr = $item->_toArray(); $item_arr = $item->_toArray();
@ -305,16 +305,16 @@ class REST_Collections_Controller extends REST_Controller {
$item_arr['url'] = get_permalink( $item_arr['id'] ); $item_arr['url'] = get_permalink( $item_arr['id'] );
} }
if(isset($request['fetch_preview_image_items']) && $request['fetch_preview_image_items'] != 0) { if ( isset($request['fetch_preview_image_items']) && $request['fetch_preview_image_items'] != 0 ) {
$item_arr['preview_image_items'] = $this->get_preview_image_items($item, $request['fetch_preview_image_items']); $item_arr['preview_image_items'] = $this->get_preview_image_items($item, $request['fetch_preview_image_items']);
} }
$total_items = wp_count_posts( $item->get_db_identifier(), 'readable' ); $total_items = wp_count_posts( $item->get_db_identifier(), 'readable' );
if (isset($total_items->publish) || if (isset($total_items->publish) ||
isset($total_items->private) || isset($total_items->private) ||
isset($total_items->trash) || isset($total_items->trash) ||
isset($total_items->draft)) { isset($total_items->draft)) {
$item_arr['total_items']['trash'] = $total_items->trash; $item_arr['total_items']['trash'] = $total_items->trash;
$item_arr['total_items']['publish'] = $total_items->publish; $item_arr['total_items']['publish'] = $total_items->publish;

View File

@ -155,6 +155,7 @@ class REST_Facets_Controller extends REST_Controller {
remove_filter( 'tainacan-item-to-array', $add_attt_item, 10); remove_filter( 'tainacan-item-to-array', $add_attt_item, 10);
return $val; return $val;
}, $all_values['values']); }, $all_values['values']);
} }

View File

@ -111,8 +111,8 @@ class REST_Taxonomies_Controller extends REST_Controller {
* @return array|\WP_Error|\WP_REST_Response * @return array|\WP_Error|\WP_REST_Response
*/ */
public function prepare_item_for_response( $item, $request ) { public function prepare_item_for_response( $item, $request ) {
if(!empty($item)) { if ( !empty($item) ) {
if(!isset($request['fetch_only'])) { if ( !isset($request['fetch_only']) ) {
$item_arr = $item->_toArray(); $item_arr = $item->_toArray();
if ( $request['context'] === 'edit' ) { if ( $request['context'] === 'edit' ) {
@ -161,6 +161,24 @@ class REST_Taxonomies_Controller extends REST_Controller {
$item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter); $item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter);
} }
$total_terms = wp_count_terms( array(
'taxonomy' => $item->get_db_identifier(),
'hide_empty' => false
), 'readable' );
$total_root_terms = wp_count_terms( array(
'taxonomy' => $item->get_db_identifier(),
'parent' => 0,
'hide_empty' => false
), 'readable' );
$total_not_empty = wp_count_terms( array(
'taxonomy' => $item->get_db_identifier(),
'hide_empty' => true
), 'readable' );
$item_arr['total_terms']['total'] = $total_terms;
$item_arr['total_terms']['root'] = $total_root_terms;
$item_arr['total_terms']['not_empty'] = $total_not_empty;
/** /**
* Use this filter to add additional post_meta to the api response * Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables * Use the $request object to get the context of the request and other variables

View File

@ -9,7 +9,7 @@ use Tainacan\Repositories;
class REST_Terms_Controller extends REST_Controller { class REST_Terms_Controller extends REST_Controller {
private $term; private $term;
private $terms_repository; private $terms_repository;
private $taxonomy; private $items_repository;
private $taxonomy_repository; private $taxonomy_repository;
/** /**
@ -27,12 +27,22 @@ class REST_Terms_Controller extends REST_Controller {
public function init_objects() { public function init_objects() {
$this->term = new Entities\Term(); $this->term = new Entities\Term();
$this->terms_repository = Repositories\Terms::get_instance(); $this->terms_repository = Repositories\Terms::get_instance();
$this->taxonomy = new Entities\Taxonomy();
$this->taxonomy_repository = Repositories\Taxonomies::get_instance(); $this->taxonomy_repository = Repositories\Taxonomies::get_instance();
$this->items_repository = Repositories\Items::get_instance(); $this->items_repository = Repositories\Items::get_instance();
} }
public function register_routes() { public function register_routes() {
register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base . '/bulkinsert',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_multiples_items'),
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base, register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base,
array( array(
array( array(
@ -47,6 +57,12 @@ class REST_Terms_Controller extends REST_Controller {
'permission_callback' => array($this, 'get_items_permissions_check'), 'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_wp_query_params() 'args' => $this->get_wp_query_params()
), ),
array(
'methods' => \WP_REST_Server::DELETABLE,
'callback' => array($this, 'delete_items'),
'permission_callback' => array($this, 'delete_items_permissions_check'),
'args' => $this->get_wp_query_params()
),
'schema' => [$this, 'get_schema'] 'schema' => [$this, 'get_schema']
) )
); );
@ -60,7 +76,11 @@ class REST_Terms_Controller extends REST_Controller {
'permanently' => [ 'permanently' => [
'description' => __('Delete term permanently.'), 'description' => __('Delete term permanently.'),
'default' => '1' 'default' => '1'
] ],
'delete_child_terms' => [
'description' => __('Delete all child terms.'),
'default' => false
],
] ]
), ),
array( array(
@ -78,6 +98,17 @@ class REST_Terms_Controller extends REST_Controller {
'schema' => [$this, 'get_schema'] 'schema' => [$this, 'get_schema']
) )
); );
register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base . '/newparent/(?P<new_parent_id>[\d]+)',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array($this, 'update_parent_terms'),
'permission_callback' => array($this, 'update_parent_terms_permissions_check'),
'args' => $this->get_wp_query_params()
),
'schema' => [$this, 'get_schema']
)
);
} }
/** /**
@ -96,6 +127,57 @@ class REST_Terms_Controller extends REST_Controller {
$this->term->set_taxonomy($taxonomy); $this->term->set_taxonomy($taxonomy);
} }
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
*/
public function create_multiples_items( $request ) {
$taxonomy_id = $request['taxonomy_id'];
$body = json_decode($request->get_body(), true);
if( is_array($body) ){
$taxonomy = $this->taxonomy_repository->fetch($taxonomy_id);
$taxonomy_db_identifier = $taxonomy->get_db_identifier();
$terms_errors = [];
$to_insert_terms = [];
$new_terms = [];
foreach($body as $item) {
$term = new Entities\Term();
$term->set_taxonomy($taxonomy_db_identifier);
foreach ($item as $attribute => $value){
$term->set($attribute, $value);
}
if ( !$term->validate() ) {
$terms_errors[] = [
'error_message' => 'One or more attributes are invalid.',
'errors' => $term->get_errors(),
'term_name' => $term->get_name()
];
} else {
$to_insert_terms[] = $term;
}
}
if ( count($terms_errors) > 0 )
return new \WP_REST_Response($terms_errors, 400);
foreach($to_insert_terms as $new_term) {
$new = $this->terms_repository->insert($new_term);
$new_terms[] = $this->prepare_item_for_response($new, $request);
}
return new \WP_REST_Response($new_terms, 200);
}
return new \WP_REST_Response([
'error_message' => 'The body couldn\'t be empty.',
'body' => $body,
], 400);
}
/** /**
* @param \WP_REST_Request $request * @param \WP_REST_Request $request
* *
@ -160,6 +242,52 @@ class REST_Terms_Controller extends REST_Controller {
return false; return false;
} }
/**
* @param \WP_REST_Request $request
*
* @return bool|\WP_Error
*/
public function delete_items_permissions_check( $request ) {
$taxonomy = $this->taxonomy_repository->fetch($request['taxonomy_id']);
$args = $this->prepare_filters($request);
$terms = $this->terms_repository->fetch($args, $taxonomy);
foreach ($terms as $term) {
if (!$term instanceof Entities\Term || !$term->can_delete()) {
return false ;
}
}
return true;
}
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
* @throws \Exception
*/
public function delete_items( $request ) {
$taxonomy_id = $request['taxonomy_id'];
$taxonomy = $this->taxonomy_repository->fetch($taxonomy_id);
$delete_child_terms = isset($request['delete_child_terms']) && $request['delete_child_terms'] == true;
$args = $this->prepare_filters($request);
$terms = $this->terms_repository->fetch($args, $taxonomy);
$response = [];
foreach ($terms as $term) {
if($delete_child_terms) {
$this->terms_repository->delete_child_terms($term);
}
$response[] = $this->terms_repository->delete($term);
}
$response = new \WP_REST_Response($response, 200);
return $response;
}
/** /**
* @param \WP_REST_Request $request * @param \WP_REST_Request $request
* *
@ -181,6 +309,10 @@ class REST_Terms_Controller extends REST_Controller {
], 400); ], 400);
} }
if( isset($request['delete_child_terms']) && $request['delete_child_terms'] == true ) {
$this->terms_repository->delete_child_terms($term);
}
$is_deleted = $this->terms_repository->delete($term); $is_deleted = $this->terms_repository->delete($term);
return new \WP_REST_Response($is_deleted, 200); return new \WP_REST_Response($is_deleted, 200);
@ -203,6 +335,54 @@ class REST_Terms_Controller extends REST_Controller {
return false; return false;
} }
/**
* @param \WP_REST_Request $request
*
* @return bool|\WP_Error
*/
public function update_parent_terms_permissions_check( $request ) {
$taxonomy = $this->taxonomy_repository->fetch($request['taxonomy_id']);
$args = $this->prepare_filters($request);
$terms = $this->terms_repository->fetch($args, $taxonomy);
foreach ($terms as $term) {
if (!$term instanceof Entities\Term || !$term->can_edit()) {
return false ;
}
}
return true;
}
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
* @throws \Exception
*/
public function update_parent_terms($request)
{
$taxonomy_id = $request['taxonomy_id'];
$new_parent_id = $request['new_parent_id'];
$taxonomy = $this->taxonomy_repository->fetch($taxonomy_id);
$tax_name = $taxonomy->get_db_identifier();
$args = $this->prepare_filters($request);
$terms = $this->terms_repository->fetch($args, $taxonomy);
$response = [];
foreach ($terms as $term) {
$term->set_parent($new_parent_id);
if ($term->validate()) {
$updated_term = $this->terms_repository->update($term, $tax_name);
$response[] = $this->prepare_item_for_response($updated_term, $request);
}
}
$response = new \WP_REST_Response($response, 200);
return $response;
}
/** /**
* @param \WP_REST_Request $request * @param \WP_REST_Request $request
* *
@ -314,7 +494,7 @@ class REST_Terms_Controller extends REST_Controller {
*/ */
public function prepare_item_for_response( $item, $request ) { public function prepare_item_for_response( $item, $request ) {
if(!empty($item)){ if(!empty($item)){
if(!isset($request['fetch_only'])) { if (!isset($request['fetch_only'])) {
$item_arr = $item->_toArray(); $item_arr = $item->_toArray();
if ( $request['context'] === 'edit' ) { if ( $request['context'] === 'edit' ) {
@ -333,8 +513,24 @@ class REST_Terms_Controller extends REST_Controller {
} else { } else {
$attributes_to_filter = $request['fetch_only']; $attributes_to_filter = $request['fetch_only'];
$item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter); $item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter);
if ( !is_array($attributes_to_filter) )
$attributes_to_filter = explode(',', $attributes_to_filter);
foreach ( $attributes_to_filter as $attribute ) {
if ( $attribute == 'total_children' ) {
$children = get_terms([
'taxonomy' => $item_arr['taxonomy'],
'parent' => $item_arr['id'],
'fields' => 'ids',
'hide_empty' => false,
]);
$item_arr['total_children'] = count($children);
}
}
} }
if(isset($request['fetch_preview_image_items']) && $request['fetch_preview_image_items'] != 0) { if(isset($request['fetch_preview_image_items']) && $request['fetch_preview_image_items'] != 0) {

View File

@ -581,7 +581,8 @@ class Item extends Entity {
'before_title' => '<h3>', 'before_title' => '<h3>',
'after_title' => '</h3>', 'after_title' => '</h3>',
'before_value' => '<p>', 'before_value' => '<p>',
'after_value' => '</p>' 'after_value' => '</p>',
'metadatum_index' => null
); );
$args = wp_parse_args($args, $defaults); $args = wp_parse_args($args, $defaults);
$item_metadata = array(); $item_metadata = array();
@ -669,7 +670,7 @@ class Item extends Entity {
} }
// Loop item metadata to print their "values" as html // Loop item metadata to print their "values" as html
$metadatum_index = 0; $metadatum_index = is_numeric($args['metadatum_index']) && count($item_metadata) === 1 ? $args['metadatum_index'] : 0;
foreach ( $item_metadata as $item_metadatum ) { foreach ( $item_metadata as $item_metadatum ) {
// Gets the metadata type object to perform some checks // Gets the metadata type object to perform some checks
@ -688,7 +689,6 @@ class Item extends Entity {
// Get the metadatum representation in html, with its label and value // Get the metadatum representation in html, with its label and value
$return .= $this->get_item_metadatum_as_html($item_metadatum, $args, $metadatum_index); $return .= $this->get_item_metadatum_as_html($item_metadatum, $args, $metadatum_index);
$metadatum_index++; $metadatum_index++;
} }
@ -1169,14 +1169,16 @@ class Item extends Entity {
$return = ''; $return = '';
if($metadata_section->is_conditional_section()) { if ( $metadata_section->is_conditional_section() ) {
$rules = $metadata_section->get_conditional_section_rules(); $rules = $metadata_section->get_conditional_section_rules();
$item_id = $this->get_id(); $item_id = $this->get_id();
foreach($rules as $meta_id => $meta_values_conditional) {
foreach ( $rules as $meta_id => $meta_values_conditional ) {
$meta_values = get_post_meta( $item_id, $meta_id ); $meta_values = get_post_meta( $item_id, $meta_id );
if (!array_intersect($meta_values, $meta_values_conditional)) { if (!array_intersect($meta_values, $meta_values_conditional))
return $return; return $return;
}
} }
} }
@ -1268,19 +1270,20 @@ class Item extends Entity {
} }
// Renders the section metadata list wrapper // Renders the section metadata list wrapper
$return .= $before_metadata_list; $return .= $before_metadata_list . $before_description;
// Renders the section metadata list, using Items' get_metadata_as_html() // Renders the section metadata list, using Items' get_metadata_as_html()
// Note that this is already escaped in the calling function // Note that this is already escaped in the calling function
if ($has_metadata_list) { if ($has_metadata_list) {
$has_some_metadata_value = false; $has_some_metadata_value = false;
$metadatum_index = 0;
foreach( $metadata_section_metadata_list as $metadata_object) { foreach( $metadata_section_metadata_list as $metadata_object) {
$the_metadata_list = $this->get_metadata_as_html( wp_parse_args($args['metadata_list_args'], [ 'metadata' => $metadata_object ]) ); $the_metadata_list = $this->get_metadata_as_html( wp_parse_args($args['metadata_list_args'], [ 'metadata' => $metadata_object, 'metadatum_index' => $metadatum_index ]) );
if (!$has_some_metadata_value && !empty($the_metadata_list)) if (!$has_some_metadata_value && !empty($the_metadata_list))
$has_some_metadata_value = true; $has_some_metadata_value = true;
$return .= $the_metadata_list; $return .= $the_metadata_list;
$metadatum_index++;
} }
// If no metadata value was found, this section may not be necessary // If no metadata value was found, this section may not be necessary
@ -1302,7 +1305,7 @@ class Item extends Entity {
} }
// Renders the section metadata list wrapper // Renders the section metadata list wrapper
$return .= $after_metadata_list; $return .= $after_description . $after_metadata_list;
// Gets the wrapper closer // Gets the wrapper closer
$after = $args['after']; $after = $args['after'];

View File

@ -220,7 +220,7 @@ class Metadata_Section extends Entity {
if ($this->is_conditional_section()) { if ($this->is_conditional_section()) {
$metadata_section_id = $this->get_id(); $metadata_section_id = $this->get_id();
if ($metadata_section_id == static::$default_section_slug) { if ($metadata_section_id == static::$default_section_slug) {
$this->add_error($this->get_id(), __("conditional section cannot be enabled in default section", 'tainacan')); $this->add_error('is_conditional_section', __("A conditional section cannot be enabled in default section", 'tainacan'));
$no_errors = false; $no_errors = false;
} else { } else {
$metadata_list = $this->get_metadata_object_list(); $metadata_list = $this->get_metadata_object_list();
@ -230,19 +230,19 @@ class Metadata_Section extends Entity {
if ( count($required_metadata_list) ) { if ( count($required_metadata_list) ) {
$no_errors = false; $no_errors = false;
foreach($required_metadata_list as $metadata) { foreach($required_metadata_list as $metadata) {
$this->add_error($metadata->get_id(), __("metadata cannot be required", 'tainacan')); $this->add_error('is_conditional_section', sprintf(__("Metadatum %s cannot be required inside a conditional section", 'tainacan'), $metadata->get_name()));
} }
} }
} }
} }
if( empty($collection) ) { if( empty($collection) ) {
$this->add_error($this->get_id(), __("collection is required", 'tainacan')); $this->add_error('required', __("Collection is required", 'tainacan'));
$no_errors = false; $no_errors = false;
} }
if ( !isset($name) ) { if ( !isset($name) ) {
$this->add_error($this->get_id(), __("name is required", 'tainacan')); $this->add_error('required', __("Name is required", 'tainacan'));
$no_errors = false; $no_errors = false;
} }
if($no_errors) { if($no_errors) {

View File

@ -14,6 +14,7 @@ class Taxonomy extends Entity {
$name, $name,
$description, $description,
$allow_insert, $allow_insert,
$hierarchical,
$slug; $slug;
/** /**
@ -74,7 +75,7 @@ class Taxonomy extends Entity {
$show_ui = is_array($enabled_post_types) ? true : false; $show_ui = is_array($enabled_post_types) ? true : false;
$args = array( $args = array(
'hierarchical' => true, 'hierarchical' => $this->get_hierarchical() !== 'no',
'labels' => $labels, 'labels' => $labels,
'show_ui' => $show_ui, 'show_ui' => $show_ui,
'show_in_rest' => $show_ui, 'show_in_rest' => $show_ui,
@ -152,6 +153,15 @@ class Taxonomy extends Entity {
return $this->get_mapped_property('allow_insert'); return $this->get_mapped_property('allow_insert');
} }
/**
* Return 'yes' if terms hierarchy is allowd and 'no' otherwise
*
* @return boolean
*/
function get_hierarchical() {
return $this->get_mapped_property('hierarchical');
}
/** /**
* Return the slug * Return the slug
* *
@ -214,12 +224,21 @@ class Taxonomy extends Entity {
/** /**
* Define if allow insert or not * Define if allow insert or not
* *
* @param [boolean] $value * @param [String] $value
*/ */
function set_allow_insert($value) { function set_allow_insert($value) {
$this->set_mapped_property('allow_insert', $value); $this->set_mapped_property('allow_insert', $value);
} }
/**
* Define if hierarchical is 'yes' or 'no'
*
* @param [String] $value
*/
function set_hierarchical($value) {
$this->set_mapped_property('hierarchical', $value);
}
/** /**
* Sets enabled post types * Sets enabled post types
* *

View File

@ -65,9 +65,12 @@ class Term extends Entity {
unset($term_array['term_id']); unset($term_array['term_id']);
unset($term_array['status']); unset($term_array['status']);
$term_array['id'] = $term_id; $term_array['id'] = $term_id;
$term_array['header_image'] = $this->get_header_image(); $term_array['thumbnail'] = $this->get_thumbnail();
$term_array['url'] = get_term_link( $this->get_id() ); $term_array['thumbnail_alt'] = get_post_meta( $this->get_header_image_id(), '_wp_attachment_image_alt', true );
$term_array['thumbnail_id'] = $this->get_header_image_id();
$term_array['header_image'] = $this->get_header_image();
$term_array['url'] = get_term_link( $this->get_id() );
$term_array['hierarchy_path'] = get_term_parents_list($term_id, $taxonomy_slug, ['format'=>'name', 'separator'=>$separator, 'link'=>false, 'inclusive'=>false]); $term_array['hierarchy_path'] = get_term_parents_list($term_id, $taxonomy_slug, ['format'=>'name', 'separator'=>$separator, 'link'=>false, 'inclusive'=>false]);
return apply_filters('tainacan-term-to-array', $term_array, $this); return apply_filters('tainacan-term-to-array', $term_array, $this);
@ -158,6 +161,41 @@ class Term extends Entity {
return $url; return $url;
} }
/**
* Gets the thumbnail
*
* Each size is represented as an array in the format returned by
* @see https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/
*
* @return array
*/
function get_thumbnail() {
$sizes = get_intermediate_image_sizes();
$blurhash = $this->get_thumbnail_blurhash();
array_unshift($sizes, 'full');
foreach ( $sizes as $size ) {
$thumbs[$size] = wp_get_attachment_image_src( $this->get_header_image_id(), $size );
if (is_array($thumbs[$size]) && count($thumbs[$size]) == 4) {
$thumbs[$size][] = $blurhash;
}
}
return apply_filters("tainacan-term-get-thumbnail", $thumbs, $this);
}
function get_thumbnail_blurhash() {
$attachment_metadata = wp_get_attachment_metadata($this->get_header_image_id());
if($attachment_metadata != false && isset($attachment_metadata['image_meta'])) {
$image_meta = $attachment_metadata['image_meta'];
if($image_meta != false && isset($image_meta['blurhash'])) {
return $image_meta['blurhash'];
}
}
return \Tainacan\Media::get_instance()->get_default_image_blurhash();
}
// Setters // Setters
/** /**

View File

@ -171,6 +171,26 @@ class CSV extends Exporter {
$meta_type = explode('\\', $meta->get_metadata_type()) ; $meta_type = explode('\\', $meta->get_metadata_type()) ;
$meta_type = strtolower($meta_type[sizeof($meta_type)-1]); $meta_type = strtolower($meta_type[sizeof($meta_type)-1]);
$meta_section_name = '';
if ($this->get_option('add_section_name') == 'yes' && $current_collection = $this->get_current_collection_object()) {
$meta_section_id = $meta->get_metadata_section_id();
$collection_id = $current_collection->get_id();
if($meta->is_repository_level()) {
foreach($meta_section_id as $section_id ) {
if($collection_id == get_post_meta($section_id, 'collection_id', true)) {
$meta_section_name = '(' . get_the_title($section_id) . ')';
continue;
}
}
} else {
if($meta_section_id != \Tainacan\Entities\Metadata_Section::$default_section_slug) {
$meta_section_name = '(' . get_the_title($meta_section_id) . ')';
}
}
}
if($meta_type == 'compound') { if($meta_type == 'compound') {
$enclosure = $this->get_option('enclosure'); $enclosure = $this->get_option('enclosure');
$delimiter = $this->get_option('delimiter'); $delimiter = $this->get_option('delimiter');
@ -185,12 +205,14 @@ class CSV extends Exporter {
$meta_type .= "(" . implode($delimiter, $desc_childrens) . ")"; $meta_type .= "(" . implode($delimiter, $desc_childrens) . ")";
$desc_title_meta = $desc_title_meta =
$meta->get_name() . $meta->get_name() .
$meta_section_name .
('|' . $meta_type) . ('|' . $meta_type) .
($meta->is_multiple() ? '|multiple': '') . ($meta->is_multiple() ? '|multiple': '') .
('|display_' . $meta->get_display()); ('|display_' . $meta->get_display());
} else { } else {
$desc_title_meta = $desc_title_meta =
$meta->get_name() . $meta->get_name() .
$meta_section_name .
('|' . $meta_type) . ('|' . $meta_type) .
($meta->is_multiple() ? '|multiple': '') . ($meta->is_multiple() ? '|multiple': '') .
($meta->is_required() ? '|required': '') . ($meta->is_required() ? '|required': '') .
@ -266,7 +288,7 @@ class CSV extends Exporter {
$message = __('target collections:', 'tainacan'); $message = __('target collections:', 'tainacan');
$message .= " <b>" . implode(", ", $this->get_collections_names() ) . "</b><br/>"; $message .= " <b>" . implode(", ", $this->get_collections_names() ) . "</b><br/>";
$message .= __('Exported by:', 'tainacan'); $message .= __('Exported by:', 'tainacan');
$message .= " <b> ${author_name} </b><br/>"; $message .= " <b> $author_name </b><br/>";
$message .= __('Your CSV file is ready! Access it in the link below:', 'tainacan'); $message .= __('Your CSV file is ready! Access it in the link below:', 'tainacan');
$message .= '<br/><br/>'; $message .= '<br/><br/>';
$message .= '<a href="' . $file['url'] . '">Download</a>'; $message .= '<a href="' . $file['url'] . '">Download</a>';
@ -360,6 +382,34 @@ class CSV extends Exporter {
</div> </div>
</div> </div>
<div class="field">
<label class="label"><?php _e('Include metadata section name', 'tainacan'); ?></label>
<span class="help-wrapper">
<a class="help-button has-text-secondary">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-help" ></i>
</span>
</a>
<div class="help-tooltip">
<div class="help-tooltip-header">
<h5><?php _e('Include metadata section name', 'tainacan'); ?></h5>
</div>
<div class="help-tooltip-body">
<p><?php _e('Include metadatum section name after the metadatum name. Metadata inside the default section are not modified', 'tainacan'); ?></p>
</div>
</div>
</span>
<div class="control is-clearfix">
<label class="checkbox">
<input
type="checkbox"
name="add_section_name" checked value="yes"
>
<?php _e('Yes', 'tainacan'); ?>
</label>
</div>
</div>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }

View File

@ -298,6 +298,7 @@ class Collections extends Repository {
'capabilities' => (array) $this->get_capabilities(), 'capabilities' => (array) $this->get_capabilities(),
'map_meta_cap' => true, 'map_meta_cap' => true,
'show_in_rest' => true, 'show_in_rest' => true,
'show_in_nav_menus' => true,
'supports' => [ 'supports' => [
'title', 'title',
'editor', 'editor',

View File

@ -266,9 +266,9 @@ class Metadata extends Repository {
'public' => true, 'public' => true,
'show_ui' => tnc_enable_dev_wp_interface(), 'show_ui' => tnc_enable_dev_wp_interface(),
'show_in_menu' => tnc_enable_dev_wp_interface(), 'show_in_menu' => tnc_enable_dev_wp_interface(),
'publicly_queryable' => true, 'publicly_queryable' => false,
'exclude_from_search' => true, 'exclude_from_search' => true,
'has_archive' => true, 'has_archive' => false,
'query_var' => true, 'query_var' => true,
'can_export' => true, 'can_export' => true,
'rewrite' => true, 'rewrite' => true,

View File

@ -390,7 +390,7 @@ abstract class Repository {
'map' => 'post_status', 'map' => 'post_status',
'title' => __( 'Status', 'tainacan' ), 'title' => __( 'Status', 'tainacan' ),
'type' => 'string', 'type' => 'string',
'description' => __( 'Status', 'tainacan' ), 'description' => __( 'Status for control of visibility', 'tainacan' ),
//'validation' => v::stringType(), //'validation' => v::stringType(),
), ),
'id' => array( 'id' => array(

View File

@ -65,6 +65,15 @@ class Taxonomies extends Repository {
'validation' => v::stringType()->in( [ 'yes', 'no' ] ), // yes or no 'validation' => v::stringType()->in( [ 'yes', 'no' ] ), // yes or no
'default' => 'yes' 'default' => 'yes'
], ],
'hierarchical' => [
'map' => 'meta',
'title' => __( 'Allow terms hierarchy', 'tainacan' ),
'type' => 'string',
'description' => __( 'Allow/Deny the existence of terms children to build a hierarchy', 'tainacan' ),
'on_error' => __( 'Invalid insertion, allowed values are ( yes/no )', 'tainacan' ),
'validation' => v::stringType()->in( [ 'yes', 'no' ] ), // yes or no
'default' => 'yes'
],
'enabled_post_types' => [ 'enabled_post_types' => [
'map' => 'meta_multi', 'map' => 'meta_multi',
'title' => __( 'Enabled for post types', 'tainacan' ), 'title' => __( 'Enabled for post types', 'tainacan' ),
@ -117,15 +126,17 @@ class Taxonomies extends Repository {
'public' => true, 'public' => true,
'show_ui' => tnc_enable_dev_wp_interface(), 'show_ui' => tnc_enable_dev_wp_interface(),
'show_in_menu' => tnc_enable_dev_wp_interface(), 'show_in_menu' => tnc_enable_dev_wp_interface(),
'publicly_queryable' => false, 'publicly_queryable' => true,
'exclude_from_search' => true, 'exclude_from_search' => true,
'has_archive' => false, 'has_archive' => true,
'query_var' => true, 'query_var' => true,
'can_export' => true, 'can_export' => true,
'rewrite' => true, /* Translators: The Taxonomies slug - will be the URL for the collections archive */
'map_meta_cap' => true, 'rewrite' => ['slug' => sanitize_title(_x('taxonomies', 'Slug: the string that will be used to build the URL', 'tainacan'))],
'show_in_nav_menus' => false,
'capabilities' => (array) $this->get_capabilities(), 'capabilities' => (array) $this->get_capabilities(),
'map_meta_cap' => true,
'show_in_rest' => true,
'show_in_nav_menus' => true,
'supports' => [ 'supports' => [
'title', 'title',
'editor', 'editor',

View File

@ -249,6 +249,31 @@ class Terms extends Repository {
return $this->insert( $object ); return $this->insert( $object );
} }
/**
* @param Entities\Term $parentTerm
* @param bool $permanent this parameter is not used by Terms repository. Delete is always permanent
*
* @return bool|int|mixed|\WP_Error
*/
public function delete_child_terms(Entities\Entity $parentTerm, $permanent = true) {
$parent_id = $parentTerm->get_id();
$taxonomy = $parentTerm->get_taxonomy();
$args = [
"taxonomy" => $taxonomy ,
"hide_empty" => false,
"offset" => 0,
"number" => 100,
"child_of" => $parent_id
];
do {
$terms = get_terms($args);
foreach($terms as $term) {
$tainacan_term = new Entities\Term($term);
$this->delete($tainacan_term, $permanent);
}
} while(!empty($terms) && !$terms instanceof \WP_Error);
}
/** /**
* @param Entities\Term $term * @param Entities\Term $term
* @param bool $permanent this parameter is not used by Terms repository. Delete is always permanent * @param bool $permanent this parameter is not used by Terms repository. Delete is always permanent

View File

@ -26,7 +26,11 @@ class Theme_Helper {
private function __construct() { private function __construct() {
if ( !defined('TAINACAN_DISABLE_ITEM_THE_CONTENT_FILTER') || true !== TAINACAN_DISABLE_ITEM_THE_CONTENT_FILTER ) { if ( !defined('TAINACAN_DISABLE_ITEM_THE_CONTENT_FILTER') || true !== TAINACAN_DISABLE_ITEM_THE_CONTENT_FILTER ) {
add_filter( 'the_content', [$this, 'the_content_filter'] ); add_filter( 'the_content', [$this, 'the_content_filter_item'] );
}
if ( !defined('TAINACAN_DISABLE_TAXONOMY_THE_CONTENT_FILTER') || true !== TAINACAN_DISABLE_TAXONOMY_THE_CONTENT_FILTER ) {
add_filter( 'the_content', [$this, 'the_content_filter_taxonomy'] );
} }
// Replace collections permalink to post type archive if cover not enabled // Replace collections permalink to post type archive if cover not enabled
@ -39,9 +43,10 @@ class Theme_Helper {
// make archive for terms work with items // make archive for terms work with items
add_action('pre_get_posts', array($this, 'tax_archive_pre_get_posts')); add_action('pre_get_posts', array($this, 'tax_archive_pre_get_posts'));
add_action('archive_template_hierarchy', array($this, 'items_template_hierachy')); add_action('archive_template_hierarchy', array($this, 'collection_items_template_hierarchy'));
add_action('taxonomy_template_hierarchy', array($this, 'tax_template_hierachy')); add_action('taxonomy_template_hierarchy', array($this, 'taxonomy_term_items_template_hierarchy'));
add_action('single_template_hierarchy', array($this, 'items_template_hierachy')); add_action('single_template_hierarchy', array($this, 'item_template_hierarchy'));
add_action('single_template_hierarchy', array($this, 'taxonomy_terms_template_hierarchy'));
add_filter('theme_mod_header_image', array($this, 'header_image')); add_filter('theme_mod_header_image', array($this, 'header_image'));
@ -137,6 +142,11 @@ class Theme_Helper {
$prefix = substr( $post_type, 0, strlen( Entities\Collection::$db_identifier_prefix ) ); $prefix = substr( $post_type, 0, strlen( Entities\Collection::$db_identifier_prefix ) );
return $prefix == Entities\Collection::$db_identifier_prefix; return $prefix == Entities\Collection::$db_identifier_prefix;
} }
public function is_post_a_tainacan_taxonomy_postype(\WP_Post $post) {
$post_type = $post->post_type;
return $post_type == Entities\Taxonomy::$post_type;
}
public function is_taxonomy_a_tainacan_tax($tax_slug) { public function is_taxonomy_a_tainacan_tax($tax_slug) {
$prefix = substr( $tax_slug, 0, strlen( Entities\Taxonomy::$db_identifier_prefix ) ); $prefix = substr( $tax_slug, 0, strlen( Entities\Taxonomy::$db_identifier_prefix ) );
@ -165,18 +175,24 @@ class Theme_Helper {
return $title; return $title;
} }
public function the_content_filter($content) { /**
* Filters the post content to create Tainacan default
* item single, including its metadata sections and the
* item media gallery.
*
* @return string content tweaked to the item features
*/
public function the_content_filter_item($content) {
if (!is_single()) if (!is_single())
return $content; return $content;
$post = get_queried_object(); $post = get_queried_object();
// Is it a collection Item? // Is it a collection Item
if ( !$this->is_post_an_item($post) ) { if ( !$this->is_post_an_item($post) )
return $content; return $content;
}
$item = new Entities\Item($post); $item = new Entities\Item($post);
$content = ''; $content = '';
@ -207,6 +223,33 @@ class Theme_Helper {
return $content; return $content;
} }
/**
* Filters the post content to create Tainacan default
* taxonomy single, which works as a "terms archive"
*
* @return string content tweaked to show the taxonomy terms list
*/
public function the_content_filter_taxonomy($content) {
if ( !is_single() )
return $content;
$post = get_queried_object();
// Is it a taxonomy-post-type post?
if ( !$this->is_post_a_tainacan_taxonomy_postype($post) )
return $content;
$content .= tainacan_get_taxonomies_orderby();
$content .= tainacan_get_taxonomies_search();
$taxonomy_terms_list = tainacan_get_single_taxonomy_content($post);
$content .= $taxonomy_terms_list['content'];
$content .= tainacan_get_taxonomies_pagination($taxonomy_terms_list['total_terms']);
return $content;
}
/** /**
* Filters the permalink for posts to: * Filters the permalink for posts to:
@ -241,14 +284,24 @@ class Theme_Helper {
} }
function tax_archive_pre_get_posts($wp_query) { function tax_archive_pre_get_posts($wp_query) {
if ( is_single() && get_query_var('post_type') === 'tainacan-taxonomy' && $wp_query->is_main_query() ) {
if ( !isset($_GET['orderby']) )
$wp_query->set('orderby', 'name');
if ( !isset($_GET['order']) )
$wp_query->set('order', 'ASC');
return;
}
if (!$wp_query->is_tax() || !$wp_query->is_main_query()) if (!$wp_query->is_tax() || !$wp_query->is_main_query())
return; return;
$term = get_queried_object(); $term = get_queried_object();
if ($term instanceof \WP_Term && $this->is_term_a_tainacan_term($term)) { if ($term instanceof \WP_Term && $this->is_term_a_tainacan_term($term)) {
$tax_id = \Tainacan\Repositories\Taxonomies::get_instance()->get_id_by_db_identifier($term->taxonomy); $tax_id = \Tainacan\Repositories\Taxonomies::get_instance()->get_id_by_db_identifier($term->taxonomy);
$tax = \Tainacan\Repositories\Taxonomies::get_instance()->fetch($tax_id); $tax = \Tainacan\Repositories\Taxonomies::get_instance()->fetch($tax_id);
@ -266,9 +319,7 @@ class Theme_Helper {
status_header( 404 ); status_header( 404 );
} }
} }
} }
function collection_single_redirect() { function collection_single_redirect() {
@ -304,68 +355,117 @@ class Theme_Helper {
} }
} }
function items_template_hierachy($templates) { /**
* Allows themes to create a tainacan/single-items.php file which will
* be used to represent all items single page.
*/
function item_template_hierarchy($templates) {
if (is_post_type_archive() || is_single()) { if ( !is_single() )
return $templates;
$collections_post_types = \Tainacan\Repositories\Repository::get_collections_db_identifiers();
$current_post_type = get_post_type();
if ( in_array($current_post_type, $collections_post_types) ) {
$collections_post_types = \Tainacan\Repositories\Repository::get_collections_db_identifiers(); $last_template = array_pop($templates);
$current_post_type = get_post_type();
if (in_array($current_post_type, $collections_post_types)) { array_push($templates, 'tainacan/single-items.php');
$last_template = array_pop($templates); array_push($templates, $last_template);
}
if (is_post_type_archive()) {
array_push($templates, 'tainacan/archive-items.php'); return $templates;
} elseif (is_single()) { }
array_push($templates, 'tainacan/single-items.php');
/**
* Allows themes to create a tainacan/archive-items.php file which will
* be used to represent all collection items archive page (the list of items
* of a collection).
*/
function collection_items_template_hierarchy($templates) {
if ( !is_post_type_archive() )
return $templates;
$collections_post_types = \Tainacan\Repositories\Repository::get_collections_db_identifiers();
$current_post_type = get_post_type();
if ( in_array($current_post_type, $collections_post_types) ) {
$last_template = array_pop($templates);
array_push($templates, 'tainacan/archive-items.php');
array_push($templates, $last_template);
}
return $templates;
}
/**
* Allows themes to create a tainacan/taxonomy-items.php file which will
* be used to represent all taxonomy term items archive page (the list of
* items of a taxonomy term).
*/
function taxonomy_term_items_template_hierarchy($templates) {
if ( !is_tax() )
return $templates;
$term = get_queried_object();
if ( isset($term->taxonomy) && $this->is_taxonomy_a_tainacan_tax($term->taxonomy)) {
$tax_id = \Tainacan\Repositories\Taxonomies::get_instance()->get_id_by_db_identifier($term->taxonomy);
$tax = \Tainacan\Repositories\Taxonomies::get_instance()->fetch($tax_id);
if ( $tax ) {
$post_types = $tax->get_enabled_post_types();
if (sizeof($post_types)) {
// if taxonomy is enabled for other post types, we disable
// custom template ans use default list
// TODO: This needs discussion
return $templates;
} }
array_push($templates, $last_template);
} }
$last_template = array_pop($templates);
array_push($templates, 'tainacan/archive-taxonomy.php');
array_push($templates, $last_template);
} }
return $templates; return $templates;
} }
function tax_template_hierachy($templates) { /**
* Allows themes to create a tainacan/archive-terms.php file which will
* be used to represent all taxonomies single (the list or terms of a taxonomy)
*/
function taxonomy_terms_template_hierarchy($templates) {
if (is_tax()) { if ( !is_single() )
return $templates;
$post = get_queried_object();
// Is it a taxonomy-post-type post?
if ( $this->is_post_a_tainacan_taxonomy_postype($post) ) {
$term = get_queried_object(); $last_template = array_pop($templates);
if ( isset($term->taxonomy) && $this->is_taxonomy_a_tainacan_tax($term->taxonomy)) { array_push($templates, 'tainacan/archive-terms.php');
$tax_id = \Tainacan\Repositories\Taxonomies::get_instance()->get_id_by_db_identifier($term->taxonomy);
$tax = \Tainacan\Repositories\Taxonomies::get_instance()->fetch($tax_id);
if ( $tax ) {
$post_types = $tax->get_enabled_post_types();
if (sizeof($post_types)) {
// if taxonomy is enabled for other post types, we disable
// custom template ans use default list
// TODO: This needs discussion
return $templates;
}
}
$last_template = array_pop($templates);
array_push($templates, 'tainacan/archive-taxonomy.php');
array_push($templates, $last_template);
}
array_push($templates, $last_template);
} }
return $templates; return $templates;
} }
function header_image($image) { function header_image($image) {
@ -590,7 +690,6 @@ class Theme_Helper {
} }
function rewrite_rules( &$wp_rewrite ) { function rewrite_rules( &$wp_rewrite ) {
$items_base = $this->get_items_list_slug(); $items_base = $this->get_items_list_slug();
$new_rules = array( $new_rules = array(
@ -603,6 +702,8 @@ class Theme_Helper {
function rewrite_rules_query_vars( $public_query_vars ) { function rewrite_rules_query_vars( $public_query_vars ) {
$public_query_vars[] = "tainacan_repository_archive"; $public_query_vars[] = "tainacan_repository_archive";
$public_query_vars[] = "termspaged";
$public_query_vars[] = "termsparent";
return $public_query_vars; return $public_query_vars;
} }
@ -784,6 +885,8 @@ class Theme_Helper {
$excerpt = strip_tags(tainacan_get_the_collection_description()); $excerpt = strip_tags(tainacan_get_the_collection_description());
} elseif ( is_post_type_archive('tainacan-collection') ) { } elseif ( is_post_type_archive('tainacan-collection') ) {
$title = __('Collections', 'tainacan'); $title = __('Collections', 'tainacan');
} elseif ( is_post_type_archive('tainacan-taxonomy') ) {
$title = __('Taxonomies', 'tainacan');
} else { } else {
$title = get_the_archive_title(); $title = get_the_archive_title();
} }
@ -1284,10 +1387,11 @@ class Theme_Helper {
// Gets the current Item. This way, the function can be used in the loop without needing to pass it // Gets the current Item. This way, the function can be used in the loop without needing to pass it
$item = isset($args['itemId']) ? $this->tainacan_get_item($args['itemId']) : $this->tainacan_get_item(); $item = isset($args['itemId']) ? $this->tainacan_get_item($args['itemId']) : $this->tainacan_get_item();
$item_id = $item->get_id(); if ( !$item )
if (!$item)
return; return;
$item_id = $item->get_id();
// Gets options from block attributes // Gets options from block attributes
$block_id = $args['blockId']; $block_id = $args['blockId'];
$layout_elements = $args['layoutElements']; $layout_elements = $args['layoutElements'];
@ -1892,7 +1996,7 @@ class Theme_Helper {
} }
// Renders the section metadata list wrapper // Renders the section metadata list wrapper
$return .= $before_metadata_list; $return .= $before_metadata_list . $before_description;
// Renders the section metadata list, using get_tainacan_item_metadata_template // Renders the section metadata list, using get_tainacan_item_metadata_template
if ($has_metadata_list) { if ($has_metadata_list) {
@ -1924,7 +2028,7 @@ class Theme_Helper {
} }
// Renders the section metadata list wrapper // Renders the section metadata list wrapper
$return .= $after_metadata_list; $return .= $after_description . $after_metadata_list;
// Gets the wrapper closer // Gets the wrapper closer
$after = $args['after']; $after = $args['after'];
@ -2087,4 +2191,16 @@ class Theme_Helper {
return '<div ' . $wrapper_attributes . '>' . $placeholder_content . '</div>'; return '<div ' . $wrapper_attributes . '>' . $placeholder_content . '</div>';
} }
}
function get_taxonomies_query_args() {
return array(
'order' => get_query_var( 'order', apply_filters('tainacan-default-taxonomy-terms-order', 'ASC') ),
'orderby' => get_query_var( 'orderby', apply_filters('tainacan-default-taxonomy-terms-orderby', 'name') ),
'termspaged' => get_query_var( 'termspaged', 1 ),
'perpage' => get_query_var( 'perpage', apply_filters('tainacan-default-taxonomy-terms-perpage', 12) ),
'search' => get_query_var( 'search', '' ),
'termsparent' => get_query_var( 'termsparent', '0' )
);
}
}

View File

@ -1198,4 +1198,474 @@ function tainacan_get_the_metadata_sections($args = array(), $item_id = 0) {
function tainacan_the_metadata_sections($args = array()) { function tainacan_the_metadata_sections($args = array()) {
echo tainacan_get_the_metadata_sections($args); echo tainacan_get_the_metadata_sections($args);
}
/**
* Render the taxonomy single template HTML string.
*
* This works as an archive of the taxonomy terms, and uses the CPT tainacan-taxonomy.
*
* It should display the list of terms, and it is used in the the_content filter of the theme helper to override the cpt single.
*
* @param object $post The original tainacan-taxonomy post object. It contains the $post->ID, which can be used to query the taxonomy of slug tnc_tax_<$post-id>
* @param array|string $args {
* Optional. Array or string of arguments.
* @type bool $hide_hierarchy_header Do not display the Term hiearachy header before the list. Default false
* @type bool $hide_term_thumbnail Do not display the Term thumbnail. Default false
* @type bool $hide_term_thumbnail_placeholder Do not display the Term thumbnail placeholder (if no image is found). Default true
* @type bool $hide_term_hierarchy_path Do not display the Term hierarchy path. Default true
* @type bool $hide_term_name Do not display the Term name. Default false
* @type bool $hide_term_description Do not display the Term description. Default true
* @type bool $hide_term_children_link Do not display the Term children link. Default false
* @type bool $hide_term_items_link Do not display the Term items list link. Default false
* @type bool $hide_term_children_count Do not display the Term children count. Default true
* @type string $term_children_count_position Position of the term children count relative to the term 'children' label. Default 'after'
* @type bool $hide_term_items_count Do not display the Term items count. Default true
* @type string $term_items_count_position Position of the term items count relative to the term 'items' label. Default 'after'
* @type bool $hide_term_empty_name Do not display the Term name area if it is empty. Default true
* @type bool $hide_term_empty_hierarchy_path Do not display the Term hierarchy path area if it is empty. Default true
* @type bool $hide_term_empty_description Do not display the Term description area if it is empty. Default true
* @type bool $hide_term_empty_children_link Do not display the Term children link area if it has no children. Default true
* @type bool $hide_term_empty_items_link Do not display the Term items list link area if it has no item. Default true
* @type string $term_empty_name_message Term name area if it is empty. Default 'Term without name'
* @type string $term_empty_hierarchy_path_message Term hierarchy path area if the term is root-level. Default 'Root term'
* @type string $term_empty_description_message Term description area if it is empty. Default 'Term without description'
* @type string $term_empty_children_link_message Term children link area if it is empty. Default 'Term without children'
* @type string $term_empty_items_link_message Term items list link area if it is empty. Default 'Term without items'
* @type integer $trim_description_words Amount of words to trim the term description by. Default -1, which means no trimming
* @type string $before_terms_list_container String to be added before the taxonomy terms list container
* Default '<div class="wp-block-query tainacan-taxonomy-terms-list-container">'
* @type string $after_terms_list_container String to be added after the taxonomy terms list container
* Default '</div>'
* @type string $before_terms_list String to be added before the taxonomy terms list
* Default '<ul class="wp-block-post-template is-layout-flow tainacan-taxonomy-terms-list" style="list-style: none; padding: 0;">'
* @type string $after_terms_list String to be added after the taxonomy terms list
* Default '</ul>'
* @type string $before_term String to be added before each term inside the loop
* Default '<li class="wp-block-post tainacan-term-single" id="term-id-$id">'
* @type string $after_term String to be added after each term inside the loop
* Default '</li>'
* @type string $before_term_thumbnail String to be added before each term thumbnail
* Default '<figure class="term-thumbnail wp-block-post-featured-image">'
* @type string $after_term_thumbnail String to be added after each term thumbnail
* Default '</figure>'
* @type string $before_term_information String to be added before each term information area (everything except thumbnail)
* Default ''
* @type string $after_term_information String to be added after each term information area (everything except thumbnail)
* Default ''
* @type string $before_term_hierarchy_path String to be added before each term hierarchy path
* Default '<span class="term-hierarchy-path"><em>'
* @type string $after_term_hierarchy_path String to be added after each term hierarchy path
* Default '</em></span>'
* @type string $before_term_name String to be added before each term name
* Default '<h2 class="term-name">'
* @type string $after_term_name String to be added after each term name
* Default '</h2>'
* @type string $before_term_description String to be added before each term description
* Default '<p class="term-description">'
* @type string $after_term_description String to be added after each term description
* Default '</p>'
* @type string $before_term_links String to be added before each term links area
* Default ''
* @type string $after_term_links String to be added after each term links area
* Default ''
* @type string $before_term_children_link String to be added before each term children link
* Default '<span class="term-children-link">'
* @type string $after_term_children_link String to be added after each term children link
* Default '</span>'
* @type string $before_term_items_link String to be added before each term items link
* Default '<span class="term-items-link">'
* @type string $after_term_items_link String to be added after each term items link
* Default '</span>'
* @type string $thumbnails_size String to be added after each term items link
* Default 'tainacan-large-full'
* }
*
* @return string The HTML output
*/
function tainacan_get_single_taxonomy_content($post, $args = []) {
$args = array_merge(array(
'hide_hierarchy_header' => false,
'hide_term_thumbnail' => false,
'hide_term_thumbnail_placeholder' => true,
'hide_term_hierarchy_path' => true,
'hide_term_name' => false,
'hide_term_description' => true,
'hide_term_children_link' => false,
'hide_term_items_link' => false,
'hide_term_children_count' => true,
'term_children_count_position' => 'after',
'hide_term_items_count' => true,
'term_items_count_position' => 'after',
'hide_term_empty_name' => true,
'hide_term_empty_hierarchy_path' => true,
'hide_term_empty_description' => true,
'hide_term_empty_children_link' => true,
'hide_term_empty_items_link' => true,
'term_empty_name_message' => __( 'Term without name', 'tainacan' ),
'term_empty_hierarchy_path_message' => __( 'Root term', 'tainacan' ),
'term_empty_description_message' => __( 'Term without description', 'tainacan' ),
'term_empty_children_link_message' => __( 'Term without children', 'tainacan' ),
'term_empty_items_link_message' => __( 'Term without items', 'tainacan' ),
'trim_description_words' => -1,
'before_terms_list_container' => '<div class="wp-block-query tainacan-taxonomy-terms-list-container">',
'after_terms_list_container' => '</div>',
'before_terms_list' => '<ul class="wp-block-post-template is-layout-flow tainacan-taxonomy-terms-list" style="list-style: none; padding: 0;">',
'after_terms_list' => '</ul>',
'before_term' => '<li class="wp-block-post tainacan-term-single" id="term-id-$id">',
'after_term' => '</li>',
'before_term_thumbnail' => '<figure class="term-thumbnail wp-block-post-featured-image">',
'after_term_thumbnail' => '</figure>',
'before_term_information' => '',
'after_term_information' => '',
'before_term_hierarchy_path' => '<span class="term-hierarchy-path"><em>',
'after_term_hierarchy_path' => '</em></span>',
'before_term_name' => '<h2 class="term-name wp-block-post-title">',
'after_term_name' => '</h2>',
'before_term_description' => '<div class="term-description wp-block-post-excerpt"><p class="wp-block-post-excerpt__excerpt">',
'after_term_description' => '</p></div>',
'before_term_links' => '',
'after_term_links' => '',
'before_term_children_link' => '<span class="term-children-link">',
'after_term_children_link' => '</span>',
'before_term_items_link' => '<span class="term-items-link">',
'after_term_items_link' => '</span>',
'thumbnails_size' => 'tainacan-large-full'
), $args);
/* Gets query arguments to build fetch params */
$current_args = \Tainacan\Theme_Helper::get_instance()->get_taxonomies_query_args();
$terms_query_args = array(
'taxonomy' => 'tnc_tax_' . $post->ID,
'order' => $current_args['order'],
'orderby' => $current_args['orderby'],
'hide_empty' => false,
'offset' => ($current_args['termspaged'] - 1) * $current_args['perpage'],
'number' => $current_args['perpage'],
'search' => $current_args['search'],
'parent' => $current_args['termsparent']
);
$terms_query_args = apply_filters('tainacan_single_taxonomy_terms_query', $terms_query_args, $post);
$terms = get_terms( $terms_query_args );
unset( $terms_query_args['number'], $terms_query_args['offset'] ); // necessary so wp_count_terms can work
$total_terms = wp_count_terms( 'tnc_tax_' . $post->ID, $terms_query_args );
$content = '';
if ( !empty( $terms ) && !is_wp_error( $terms ) ) {
$content = $args['before_terms_list_container'] . $content;
$separator = strip_tags(apply_filters('tainacan-terms-hierarchy-html-separator', '>'));
if ( !$args['hide_hierarchy_header'] && isset($current_args['termsparent']) && $current_args['termsparent'] ) {
$content .= '<div class="terms-hierarachy-header"><p>' . __('Showing terms children of', 'tainacan') . '&nbsp;';
$parent = get_term($current_args['termsparent']);
$tainacan_parent_term = new Entities\Term( $parent );
$content .= '<em>' . $tainacan_parent_term->get_name() . '</em>.&nbsp;';
if ( $tainacan_parent_term->get_parent() ) {
$grandparent = get_term($tainacan_parent_term->get_parent());
$tainacan_grandparent_term = new Entities\Term( $grandparent );
$content .= '<a href="' . add_query_arg( 'termsparent', $tainacan_parent_term->get_parent() ) . '">' . __('Return to the list of terms children of ', 'tainacan') . '<em>' . $tainacan_grandparent_term->get_name() . '</em>.</a>';
} else
$content .= '<a href="' . remove_query_arg( 'termsparent' ) . '">' . __('Return to the terms list.', 'tainacan') . '</a>';
$content .= '</p></div>';
}
$content .= $args['before_terms_list'];
foreach ( $terms as $term ) {
$tainacan_term = new Entities\Term( $term );
ob_start();
$before_term = $args['before_term'];
$before_term = str_replace('$id', $tainacan_term->get_id(), $before_term);
echo $before_term;
// If the term children is hidden but not the items, we set the whole area as a link for the term items list.
if ( !$args['hide_term_items_link'] && $args['hide_term_children_link'] )
echo '<a href="' . $tainacan_term->get_url() .'">';
if ( !$args['hide_term_thumbnail'] ) {
$thumbnail = wp_get_attachment_image( $tainacan_term->get_header_image_id(), $args['thumbnails_size'], false );
if ( !$thumbnail && !$args['hide_term_thumbnail_placeholder'] )
echo $args['before_term_thumbnail'] . '<img src="' . esc_url(tainacan_get_the_mime_type_icon('empty', $args['thumbnails_size'])) . '">' . $args['after_term_thumbnail'];
else
echo $thumbnail ? ($args['before_term_thumbnail'] . $thumbnail . $args['after_term_thumbnail'] ) : '';
}
echo $args['before_term_information'];
if ( !$args['hide_term_hierarchy_path'] ) {
$term_hierarchy_path = get_term_parents_list($tainacan_term->get_id(), 'tnc_tax_' . $post->ID, [ 'format' => 'name', 'separator' => $separator, 'link' => false, 'inclusive' => false ]);
if ( $tainacan_term->get_parent() )
echo $args['before_term_hierarchy_path'] . $term_hierarchy_path . $args['after_term_hierarchy_path'];
else if ( $tainacan_term->get_parent() && !$args['hide_term_empty_hierarchy_path'] )
echo $args['before_term_hierarchy_path'] . $args['term_empty_hierarchy_path_message'] . $args['after_term_hierarchy_path'];
}
if ( !$args['hide_term_name'] ) {
$term_name = $tainacan_term->get_name();
if ( !empty($term_name) )
echo $args['before_term_name'] . $tainacan_term->get_name() . $args['after_term_name'];
else if ( empty($term_name) && !$args['hide_term_empty_name'] )
echo $args['before_term_name'] . $args['term_empty_name_message'] . $args['after_term_name'];
}
if ( !$args['hide_term_description'] ) {
$term_description = $tainacan_term->get_description();
if ( !empty($term_description) ) {
if ($args['trim_description_words'] > -1)
$term_description = wp_trim_words( $term_description, $args['trim_description_words'], '[...]' );
echo $args['before_term_description'] . $term_description . $args['after_term_description'];
} else if ( empty($term_description) && !$args['hide_term_empty_description'] ) {
echo $args['before_term_description'] . $args['term_empty_description_message'] . $args['after_term_description'];
}
}
echo $args['before_term_links'];
if ( !$args['hide_term_children_link'] ) {
$total_children = get_term_children( $tainacan_term->get_id(), 'tnc_tax_' . $post->ID );
$total_children = is_array($total_children) && count($total_children) ? count($total_children) : 0;
if ( $total_children ) {
echo $args['before_term_children_link'] . '<a href="' . add_query_arg( 'termsparent', $tainacan_term->get_id() ) . '">';
if ( !$args['hide_term_children_count'] && $args['term_children_count_position'] === 'before' )
echo '<span class="term-children-count">' . $total_children . '</span>&nbsp;';
echo ($total_children == 1 || $total_children == '1') ? __('Child', 'tainacan') : __('Children', 'tainacan');
if ( !$args['hide_term_children_count'] && $args['term_children_count_position'] !== 'before' )
echo '&nbsp;<span class="term-children-count">(' . $total_children . ')</span>';
echo '</a>' . $args['after_term_children_link'] . '&nbsp;&nbsp;';
} else if ( !$total_children && !$args['hide_term_empty_children_link'] )
echo $args['before_term_children_link'] . $args['term_empty_children_link_message'] . $args['after_term_children_link'] . '&nbsp;&nbsp;';
}
if ( !$args['hide_term_items_link'] && !$args['hide_term_children_link'] ) {
if ( $term->count ) {
echo $args['before_term_items_link'] . '<a href="' . $tainacan_term->get_url() . '">';
if ( !$args['hide_term_items_count'] && $args['term_items_count_position'] === 'before' )
echo '<span class="term-items-count">' . $term->count . '</span>&nbsp;';
echo ($term->count == 1 || $term->count == '1') ? __('Item', 'tainacan') : __('Itens', 'tainacan');
if ( !$args['hide_term_items_count'] && $args['term_items_count_position'] !== 'before' )
echo '&nbsp;<span class="term-items-count">(' . $term->count . ')</span>';
echo '</a>' . $args['after_term_items_link'];
} else if ( !$term->count && !$args['hide_term_empty_items_link'] )
echo $args['before_term_items_link'] . $args['term_empty_items_link_message'] . $args['after_term_items_link'];
}
echo $args['after_term_links'];
echo $args['after_term_information'];
if ( !$args['hide_term_items_link'] && $args['hide_term_children_link'] )
echo '</a>';
echo $args['after_term'];
$html = ob_get_contents();
ob_end_clean();
$content .= $html;
}
$content .= $args['after_terms_list'];
$content .= $args['after_terms_list_container'];
} else {
$content = $args['before_terms_list_container'] . $content;
$content .= '<p>' . __('No term was found.', 'tainacan') . '</p>';
$content .= $args['after_terms_list_container'];
}
return apply_filters('tainacan_get_single_taxonomy_content', ['content' => $content, 'total_terms' => $total_terms] , $post);
}
function tainacan_get_taxonomies_orderby($args = []) {
$args = array_merge(array(
'hide_orderby_label' => false,
'hide_order_label' => false,
'hide_orderby' => false,
'hide_order' => false,
), $args);
$current_args = \Tainacan\Theme_Helper::get_instance()->get_taxonomies_query_args();
ob_start();
?>
<form id="tainacan-taxonomy-sorting-field">
<div
class="wp-block-group is-wrap is-layout-flex"
style="display: flex; flex-wrap: wrap">
<?php if ( !$args['hide_order'] ): ?>
<?php if ( !$args['hide_order_label'] ): ?>
<label for="tainacan-taxonomy-order-select">
<?php _e( 'Sort', 'tainacan' ); ?>
</label>
<?php endif; ?>
<select
id="tainacan-taxonomy-order-select"
name="order"
onchange="location = this.value;">
<option value="<?php echo add_query_arg( 'order', 'ASC' ); ?>" <?php echo $current_args['order'] == 'ASC' ? 'selected' : ''; ?>>
<?php _e( 'Ascending', 'tainacan' ); ?>
</option>
<option value="<?php echo add_query_arg( 'order', 'DESC' ); ?>" <?php echo $current_args['order'] == 'DESC' ? 'selected' : ''; ?>>
<?php _e( 'Descending', 'tainacan' ); ?>
</option>
</select>
<?php endif; ?>
<?php if ( !$args['hide_orderby'] ): ?>
<?php if ( !$args['hide_orderby_label'] ): ?>
<label
for="tainacan-taxonomy-orderby-select">
<?php _e( 'by', 'tainacan' ); ?>
</label>
<?php endif; ?>
<select
id="tainacan-taxonomy-orderby-select"
name="orderby"
onchange="location = this.value;">
<option value="<?php echo add_query_arg( 'orderby', 'name' ); ?>" <?php echo $current_args['orderby'] == 'name' ? 'selected' : ''; ?>>
<?php _e( 'Name', 'tainacan' ); ?>
</option>
<option value="<?php echo add_query_arg( 'orderby', 'count' ); ?>" <?php echo $current_args['orderby'] == 'count'? 'selected' : ''; ?>>
<?php _e( 'Amount of items', 'tainacan' ); ?>
</option>
</select>
<?php endif; ?>
</div>
</form>
<?php
$html = ob_get_contents();
ob_end_clean();
return apply_filters('tainacan_get_taxonomies_orderby', $html );
}
function tainacan_the_taxonomies_orderby($args = []) {
echo tainacan_get_taxonomies_orderby($args);
}
function tainacan_get_taxonomies_search($args = []) {
$args = array_merge(array(
'hide_label' => false,
), $args);
$current_args = \Tainacan\Theme_Helper::get_instance()->get_taxonomies_query_args();
ob_start();
?>
<form
id="tainacan-taxonomy-search-field"
role="search"
method="get"
action=""
class="wp-block-search__button-outside wp-block-search__text-button wp-block-search">
<?php if ( !$args['hide_label'] ): ?>
<label
for="tainacan-taxonomy-search-field--input"
class="wp-block-search__label">
<?php echo __( 'Search', 'tainacan'); ?>
</label>
<?php endif; ?>
<div class="wp-block-search__inside-wrapper">
<input
type="search"
id="tainacan-taxonomy-search-field--input"
class="wp-block-search__input wp-block-search__input"
name="search"
value="<?php echo $current_args['search']; ?>"
placeholder="<?php echo __( 'Search by a term name', 'tainacan'); ?>">
<button
type="submit"
class="wp-block-search__button wp-element-button">
<?php echo __( 'Search', 'tainacan'); ?>
</button>
</div>
<?php foreach ($_GET as $key => $value) {
if ($key !== 'search' && $key !== 'termspaged') {
$key = htmlspecialchars($key);
$value = htmlspecialchars($value);
echo "<input type='hidden' name='$key' value='$value'/>";
}
} ?>
</form>
<?php
$html = ob_get_contents();
ob_end_clean();
return apply_filters('tainacan_get_taxonomies_search', $html );
}
function tainacan_the_taxonomies_search($args = []) {
echo tainacan_get_taxonomies_search($args);
}
function tainacan_get_taxonomies_pagination($total_terms, $args = []) {
$args = array_merge(array(
'before_pagination' => '<p class="tainacan-taxonomies-pagination-links">',
'after_pagination' => '</p>',
'paginate_links_extra_args' => []
), $args);
$current_args = \Tainacan\Theme_Helper::get_instance()->get_taxonomies_query_args();
if ( $total_terms <= $current_args['perpage'] )
return '';
$paginate_links_args = array_merge(array(
'format' => '?termspaged=%#%',
'total' => ceil( $total_terms / $current_args['perpage'] ),
'current' => max( 1, get_query_var('termspaged') ),
'add_args' => array(
'order' => $current_args['order'],
'orderby' => $current_args['orderby'],
'perpage' => $current_args['perpage'],
'search' => $current_args['search'],
'termsparent' => $current_args['termsparent'],
)
), $args['paginate_links_extra_args']);
$html = $args['before_pagination'] . paginate_links($paginate_links_args) . $args['after_pagination'];
return apply_filters('tainacan_get_taxonomies_pagination', $html );
}
function tainacan_the_taxonomies_pagination($total_terms, $args = []) {
echo tainacan_get_taxonomies_pagination($total_terms, $args);
} }

View File

@ -2,9 +2,9 @@
Contributors: andrebenedito, daltonmartins, fabianobn, jacsonp, leogermani, weryques, wetah, eduardohumberto, ravipassos, jessicafpx, marinagiolo, omarceloavila, vnmedeiros, tainacan, r-guimaraes, suelanesilva, ccaio, alanargomes, ateneagarcia123, rodrigo0freire, clarandreozzi Contributors: andrebenedito, daltonmartins, fabianobn, jacsonp, leogermani, weryques, wetah, eduardohumberto, ravipassos, jessicafpx, marinagiolo, omarceloavila, vnmedeiros, tainacan, r-guimaraes, suelanesilva, ccaio, alanargomes, ateneagarcia123, rodrigo0freire, clarandreozzi
Tags: museums, libraries, archives, GLAM, collections, repository Tags: museums, libraries, archives, GLAM, collections, repository
Requires at least: 5.0 Requires at least: 5.0
Tested up to: 6.1 Tested up to: 6.2.2
Requires PHP: 5.6 Requires PHP: 5.6
Stable tag: 0.20.2 Stable tag: 0.20.3
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html License URI: http://www.gnu.org/licenses/gpl-3.0.html

View File

@ -4,17 +4,17 @@ Plugin Name: Tainacan
Plugin URI: https://tainacan.org/ Plugin URI: https://tainacan.org/
Description: Open source, powerful and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional repository platform. Description: Open source, powerful and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional repository platform.
Author: Tainacan.org Author: Tainacan.org
Version: 0.20.2 Version: 0.20.3
Requires at least: 5.0 Requires at least: 5.0
Tested up to: 6.1 Tested up to: 6.2.2
Requires PHP: 5.6 Requires PHP: 5.6
Stable tag: 0.19.3 Stable tag: 0.20.3
Text Domain: tainacan Text Domain: tainacan
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/ */
const TAINACAN_VERSION = '0.20.2'; const TAINACAN_VERSION = '0.20.3';
defined( 'ABSPATH' ) or die( 'No script kiddies please!' ); defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
$TAINACAN_BASE_URL = plugins_url('', __FILE__); $TAINACAN_BASE_URL = plugins_url('', __FILE__);

View File

@ -636,7 +636,7 @@
</div> </div>
<!-- Form submit -------------------------------- --> <!-- Form submit -------------------------------- -->
<div class="field is-grouped form-submit"> <footer class="footer field is-grouped form-submit">
<div class="control"> <div class="control">
<button <button
id="button-cancel-collection-creation" id="button-cancel-collection-creation"
@ -667,8 +667,7 @@
@click.prevent="onSubmit('items')" @click.prevent="onSubmit('items')"
class="button is-success">{{ $i18n.get('finish') }}</button> class="button is-success">{{ $i18n.get('finish') }}</button>
</div> </div>
</div> </footer>
<br>
</form> </form>
<div v-if="!isLoading && ((isNewCollection && !$userCaps.hasCapability('tnc_rep_edit_collections')) || (!isNewCollection && collection && collection.current_user_can_edit != undefined && collection.current_user_can_edit == false))"> <div v-if="!isLoading && ((isNewCollection && !$userCaps.hasCapability('tnc_rep_edit_collections')) || (!isNewCollection && collection && collection.current_user_can_edit != undefined && collection.current_user_can_edit == false))">
@ -1492,6 +1491,66 @@ export default {
} }
} }
.tainacan-form {
padding-bottom: 48px;
}
.footer {
padding: 14px var(--tainacan-one-column);
position: fixed;
bottom: 0;
right: 0;
z-index: 9999;
background-color: var(--tainacan-gray1);
width: calc(100% - var(--tainacan-sidebar-width, 3.25em));
height: 60px;
display: flex;
justify-content: flex-end;
align-items: center;
transition: bottom 0.5s ease, width 0.2s linear;
.footer-message {
display: flex;
align-items: center;
}
.update-info-section {
color: var(--tainacan-info-color);
margin-right: auto;
display: flex;
flex-wrap: nowrap;
}
.help {
display: inline-flex;
font-size: 1.0em;
margin-top: 0;
margin-left: 24px;
.tainacan-help-tooltip-trigger {
margin-left: 0.25em;
}
}
.link-button {
background-color: transparent;
border: none;
}
@media screen and (max-width: 769px) {
padding: 13px 0.5em;
width: 100%;
flex-wrap: wrap;
height: auto;
position: fixed;
.update-info-section {
margin-left: auto;margin-bottom: 0.75em;
margin-top: -0.25em;
}
}
}
</style> </style>

View File

@ -434,6 +434,9 @@
:metadata-name-filter-string="metadataNameFilterString" :metadata-name-filter-string="metadataNameFilterString"
:is-collapsed="metadataCollapses[index]" :is-collapsed="metadataCollapses[index]"
:hide-collapses="$adminOptions.hideItemEditionCollapses || isMetadataNavigation" :hide-collapses="$adminOptions.hideItemEditionCollapses || isMetadataNavigation"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="false"
:help-info-bellow-label="false"
:is-mobile-screen="isMobileScreen" :is-mobile-screen="isMobileScreen"
:is-last-metadatum="index > 2 && (index == itemMetadata.length - 1)" :is-last-metadatum="index > 2 && (index == itemMetadata.length - 1)"
:is-focused="focusedMetadatum === index" :is-focused="focusedMetadatum === index"

View File

@ -124,6 +124,7 @@
</div> </div>
<div <div
v-if="form.id !== 'default_section'"
@click="hideConditionalSectionSettings = !hideConditionalSectionSettings;" @click="hideConditionalSectionSettings = !hideConditionalSectionSettings;"
class="metadata-form-section"> class="metadata-form-section">
<span class="icon"> <span class="icon">
@ -136,7 +137,9 @@
</div> </div>
<transition name="filter-item"> <transition
v-if="form.id !== 'default_section'"
name="filter-item">
<div <div
v-show="!hideConditionalSectionSettings" v-show="!hideConditionalSectionSettings"
class="options-columns"> class="options-columns">

View File

@ -6,229 +6,261 @@
{ path: $routerHelper.getTaxonomiesPath(), label: $i18n.get('taxonomies') }, { path: $routerHelper.getTaxonomiesPath(), label: $i18n.get('taxonomies') },
{ path: '', label: (taxonomy != null && taxonomy.name != undefined) ? taxonomy.name : $i18n.get('taxonomy') } { path: '', label: (taxonomy != null && taxonomy.name != undefined) ? taxonomy.name : $i18n.get('taxonomy') }
]"/> ]"/>
<b-tabs
@change="onChangeTab($event)" <form
v-model="tabIndex"> v-if="taxonomy != null && taxonomy != undefined && (($route.name == 'TaxonomyCreationForm' && $userCaps.hasCapability('tnc_rep_edit_taxonomies')) || ($route.name == 'TaxonomyEditionForm' && taxonomy.current_user_can_edit))"
<b-tab-item :label="$i18n.get('taxonomy')"> class="tainacan-form"
<form label-width="120px">
v-if="taxonomy != null && taxonomy != undefined && (($route.name == 'TaxonomyCreationForm' && $userCaps.hasCapability('tnc_rep_edit_taxonomies')) || ($route.name == 'TaxonomyEditionForm' && taxonomy.current_user_can_edit))" <div class="columns">
class="tainacan-form" <div class="column is-3">
label-width="120px">
<div class="columns"> <!-- Name -------------------------------- -->
<div class="column"> <b-field
<!-- Name -------------------------------- --> :addons="false"
<b-field :label="$i18n.get('label_name')"
:addons="false" :type="editFormErrors['name'] != undefined ? 'is-danger' : ''"
:label="$i18n.get('label_name')" :message="isUpdatingSlug ? $i18n.get('info_validating_slug') : (editFormErrors['name'] != undefined ? editFormErrors['name'] : '')">
:type="editFormErrors['name'] != undefined ? 'is-danger' : ''" <span class="required-metadatum-asterisk">*</span>
:message="isUpdatingSlug ? $i18n.get('info_validating_slug') : (editFormErrors['name'] != undefined ? editFormErrors['name'] : '')"> <help-button
<span class="required-metadatum-asterisk">*</span> :title="$i18n.getHelperTitle('taxonomies', 'name')"
:message="$i18n.getHelperMessage('taxonomies', 'name')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@focus="clearErrors('name')"
@blur="updateSlug()"
:disabled="isUpdatingSlug"
:loading="isUpdatingSlug"/>
</b-field>
<!-- Hook for extra Form options -->
<template v-if="hasBeginLeftForm">
<form
id="form-taxonomy-begin-left"
class="form-hook-region"
v-html="getBeginLeftForm"/>
</template>
<!-- Description -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_description')"
:type="editFormErrors['description'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['description'] != undefined ? editFormErrors['description'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'description')"
:message="$i18n.getHelperMessage('taxonomies', 'description')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
id="tainacan-text-description"
type="textarea"
rows="3"
v-model="form.description"
@focus="clearErrors('description')"/>
</b-field>
<!-- Allow Insert -->
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.get('label_taxonomy_allow_new_terms') }}
<b-switch
id="tainacan-checkbox-allow-insert"
size="is-small"
v-model="form.allowInsert"
true-value="yes"
false-value="no" />
<help-button <help-button
:title="$i18n.getHelperTitle('taxonomies', 'name')" :title="$i18n.getHelperTitle('taxonomies', 'allow_insert')"
:message="$i18n.getHelperMessage('taxonomies', 'name')" :message="$i18n.getHelperMessage('taxonomies', 'allow_insert')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@focus="clearErrors('name')"
@blur="updateSlug()"
:disabled="isUpdatingSlug"
:loading="isUpdatingSlug"/>
</b-field>
<!-- Hook for extra Form options -->
<template v-if="hasBeginLeftForm">
<form
id="form-taxonomy-begin-left"
class="form-hook-region"
v-html="getBeginLeftForm"/>
</template>
<!-- Description -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_description')"
:type="editFormErrors['description'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['description'] != undefined ? editFormErrors['description'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'description')"
:message="$i18n.getHelperMessage('taxonomies', 'description')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
id="tainacan-text-description"
type="textarea"
v-model="form.description"
@focus="clearErrors('description')"/>
</b-field>
<!-- Allow Insert -->
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.get('label_taxonomy_allow_new_terms') }}
<b-switch
id="tainacan-checkbox-allow-insert"
size="is-small"
v-model="form.allowInsert"
true-value="yes"
false-value="no" />
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'allow_insert')"
:message="$i18n.getHelperMessage('taxonomies', 'allow_insert')"
extra-classes="tainacan-repository-tooltip"/>
</label>
</b-field>
</div>
<div class="column">
<!-- Status -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_status')"
:type="editFormErrors['status'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['status'] != undefined ? editFormErrors['status'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'status')"
:message="$i18n.getHelperMessage('taxonomies', 'status')"
extra-classes="tainacan-repository-tooltip"/>
<div class="status-radios">
<b-radio
v-model="form.status"
v-for="(statusOption, index) of $statusHelper.getStatuses()"
:key="index"
:native-value="statusOption.slug">
<span class="icon has-text-gray">
<i
class="tainacan-icon tainacan-icon-18px"
:class="$statusHelper.getIcon(statusOption.slug)"/>
</span>
{{ statusOption.name }}
</b-radio>
</div>
</b-field>
<!-- Slug -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_slug')"
:type="editFormErrors['slug'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['slug'] != undefined ? editFormErrors['slug'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'slug')"
:message="$i18n.getHelperMessage('taxonomies', 'slug')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
@input="updateSlug()"
id="tainacan-text-slug"
v-model="form.slug"
@focus="clearErrors('slug')"
:disabled="isUpdatingSlug"/>
</b-field>
<!-- Activate for other post types -->
<b-field
:addons="false"
:label="$i18n.getHelperTitle('taxonomies', 'enabled_post_types')"
:type="editFormErrors['enabled_post_types'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['enabled_post_types'] != undefined ? editFormErrors['enabled_post_types'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'enabled_post_types')"
:message="$i18n.getHelperMessage('taxonomies', 'enabled_post_types')"
extra-classes="tainacan-repository-tooltip"/> extra-classes="tainacan-repository-tooltip"/>
</label>
</b-field>
<div <!-- Allow Insert -->
v-for="wpPostType in wpPostTypes" <b-field :addons="false">
:key="wpPostType.slug" <label class="label is-inline">
class="field"> {{ $i18n.getHelperTitle('taxonomies', 'hierarchical') }}
<b-checkbox <b-switch
:native-value="wpPostType.slug" id="tainacan-checkbox-allow-insert"
:true-value="wpPostType.slug" size="is-small"
false-value="" v-model="form.hierarchical"
v-model="form.enabledPostTypes" true-value="yes"
name="enabled_post_types" > false-value="no" />
{{ wpPostType.label }} <help-button
</b-checkbox> :title="$i18n.getHelperTitle('taxonomies', 'hierarchical')"
</div> :message="$i18n.getHelperMessage('taxonomies', 'hierarchical')"
</b-field> extra-classes="tainacan-repository-tooltip"/>
</label>
</b-field>
<!-- Slug -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_slug')"
:type="editFormErrors['slug'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['slug'] != undefined ? editFormErrors['slug'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'slug')"
:message="$i18n.getHelperMessage('taxonomies', 'slug')"
extra-classes="tainacan-repository-tooltip"/>
<b-input
@input="updateSlug()"
id="tainacan-text-slug"
v-model="form.slug"
@focus="clearErrors('slug')"
:disabled="isUpdatingSlug"/>
</b-field>
<!-- Hook for extra Form options --> <!-- Activate for other post types -->
<template v-if="hasEndLeftForm"> <b-field
<form :addons="false"
id="form-taxonomy-end-left" :label="$i18n.getHelperTitle('taxonomies', 'enabled_post_types')"
class="form-hook-region" :type="editFormErrors['enabled_post_types'] != undefined ? 'is-danger' : ''"
v-html="getEndLeftForm"/> :message="editFormErrors['enabled_post_types'] != undefined ? editFormErrors['enabled_post_types'] : ''">
</template> <help-button
</div> :title="$i18n.getHelperTitle('taxonomies', 'enabled_post_types')"
</div> :message="$i18n.getHelperMessage('taxonomies', 'enabled_post_types')"
extra-classes="tainacan-repository-tooltip"/>
<!-- Submit --> <div class="two-columns-fields">
<div class="field is-grouped form-submit"> <div
<div v-for="wpPostType in wpPostTypes"
v-if="$route.query.recent" :key="wpPostType.slug"
class="control"> class="field">
<button <b-checkbox
id="button-another-taxonomy-creation" :native-value="wpPostType.slug"
@click.prevent="goToCreateAnotherTaxonomy()" :true-value="wpPostType.slug"
class="button is-secondary">{{ $i18n.get('label_create_another_taxonomy') }}</button> false-value=""
v-model="form.enabledPostTypes"
name="enabled_post_types" >
{{ wpPostType.label }}
</b-checkbox>
</div>
</div> </div>
<div </b-field>
v-if="!$route.query.recent"
style="margin-right: auto;"
class="control">
<button
id="button-cancel-taxonomy-creation"
class="button is-outlined"
type="button"
@click="cancelBack">{{ $i18n.get('cancel') }}</button>
</div>
<p
style="margin: 0 12px;"
class="help is-danger">
{{ formErrorMessage }}
</p>
<p
v-if="updatedAt != undefined"
class="updated-at">
{{ ($i18n.get('info_updated_at') + ' ' + updatedAt) }}
</p>
<div class="control">
<button
:class="{ 'is-loading': isLoadingTaxonomy, 'is-success': !isLoadingTaxonomy }"
id="button-submit-taxonomy-creation"
@click.prevent="onSubmit"
class="button">{{ $i18n.get('save') }}</button>
</div>
</div>
</form>
<div v-if="!isLoading && (($route.name == 'TaxonomyCreationForm' && !$userCaps.hasCapability('tnc_rep_edit_taxonomies')) || ($route.name == 'TaxonomyEditionForm' && taxonomy && taxonomy.current_user_can_edit != undefined && !taxonomy.current_user_can_edit))">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>
<span class="icon">
<i class="tainacan-icon tainacan-icon-30px tainacan-icon-taxonomies"/>
</span>
</p>
<p>{{ $i18n.get('info_can_not_edit_taxonomy') }}</p>
</div>
</section>
</div> </div>
</b-tab-item> <div class="column is-9">
<b-tab-item :label="$i18n.get('terms')"> <!-- Status -------------------------------- -->
<!-- Terms List --> <b-field
<terms-list :addons="false"
:key="shouldReloadTermsList ? 'termslistreloaded' : 'termslist'" :label="$i18n.get('label_status')"
@isEditingTermUpdate="isEditingTermUpdate" :type="editFormErrors['status'] != undefined ? 'is-danger' : ''"
:taxonomy-id="taxonomyId" :message="editFormErrors['status'] != undefined ? editFormErrors['status'] : ''">
:current-user-can-edit-taxonomy="taxonomy ? taxonomy.current_user_can_edit : false"/> <help-button
</b-tab-item> :title="$i18n.getHelperTitle('taxonomies', 'status')"
:message="$i18n.getHelperMessage('taxonomies', 'status')"
extra-classes="tainacan-repository-tooltip"/>
<div class="status-radios">
<b-radio
v-model="form.status"
v-for="(statusOption, index) of $statusHelper.getStatuses().filter((status) => status.slug != 'draft')"
:key="index"
:native-value="statusOption.slug">
<span class="icon has-text-gray">
<i
class="tainacan-icon tainacan-icon-18px"
:class="$statusHelper.getIcon(statusOption.slug)"/>
</span>
{{ statusOption.name }}
</b-radio>
</div>
</b-field>
<!-- Terms List -->
<b-field
:addons="false"
:label="$i18n.get('terms')">
<help-button
:title="$i18n.get('terms')"
:message="$i18n.get('info_taxonomy_terms_list')"
extra-classes="tainacan-repository-tooltip"/>
<terms-list
:is-hierarchical="form.hierarchical !== 'no'"
:key="shouldReloadTermsList ? 'termslistreloaded' : 'termslist'"
:taxonomy-id="taxonomyId"
:current-user-can-edit-taxonomy="taxonomy ? taxonomy.current_user_can_edit : false"/>
</b-field>
<!-- Hook for extra Form options -->
<template v-if="hasEndLeftForm">
<form
id="form-taxonomy-end-left"
class="form-hook-region"
v-html="getEndLeftForm"/>
</template>
</div>
</div>
<!-- Submit -->
<footer class="footer field is-grouped form-submit">
<div
v-if="$route.query.recent"
class="control">
<button
id="button-another-taxonomy-creation"
@click.prevent="goToCreateAnotherTaxonomy()"
class="button is-secondary">{{ $i18n.get('label_create_another_taxonomy') }}</button>
</div>
<div
v-if="!$route.query.recent"
style="margin-right: auto;"
class="control">
<button
id="button-cancel-taxonomy-creation"
class="button is-outlined"
type="button"
@click="cancelBack">{{ $i18n.get('cancel') }}</button>
</div>
<p
style="margin: 0 12px;"
class="help is-danger">
{{ formErrorMessage }}
</p>
<p
v-if="updatedAt != undefined"
class="updated-at">
{{ ($i18n.get('info_updated_at') + ' ' + updatedAt) }}
</p>
<div class="control">
<a
target="_blank"
class="button link-button"
:href="themeTaxonomiesURL + taxonomy.slug">
<span class="icon is-large">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-see"/>
</span>
<span>{{ $i18n.get('label_taxonomy_page_on_website') }}</span>
</a>
<button
:class="{ 'is-loading': isLoadingTaxonomy, 'is-success': !isLoadingTaxonomy }"
id="button-submit-taxonomy-creation"
@click.prevent="onSubmit"
class="button">{{ $i18n.get('save') }}</button>
</div>
</footer>
</form>
<div v-if="!isLoading && (($route.name == 'TaxonomyCreationForm' && !$userCaps.hasCapability('tnc_rep_edit_taxonomies')) || ($route.name == 'TaxonomyEditionForm' && taxonomy && taxonomy.current_user_can_edit != undefined && !taxonomy.current_user_can_edit))">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>
<span class="icon">
<i class="tainacan-icon tainacan-icon-30px tainacan-icon-taxonomies"/>
</span>
</p>
<p>{{ $i18n.get('info_can_not_edit_taxonomy') }}</p>
</div>
</section>
</div>
<b-loading
:active.sync="isLoadingTaxonomy"
:can-cancel="false"/>
<b-loading
:active.sync="isLoadingTaxonomy"
:can-cancel="false"/>
</b-tabs>
</div> </div>
</div> </div>
</template> </template>
@ -242,10 +274,10 @@
export default { export default {
name: 'TaxonomyEditionForm', name: 'TaxonomyEditionForm',
components: { components: {
TermsList TermsList
}, },
mixins: [ wpAjax, formHooks ], mixins: [ wpAjax, formHooks ],
beforeRouteLeave( to, from, next ) { beforeRouteLeave( to, from, next ) {
let formNotSaved = false; let formNotSaved = false;
if (this.taxonomy) { if (this.taxonomy) {
@ -257,6 +289,8 @@
formNotSaved = true; formNotSaved = true;
if (this.taxonomy.allow_insert != this.form.allowInsert) if (this.taxonomy.allow_insert != this.form.allowInsert)
formNotSaved = true; formNotSaved = true;
if (this.taxonomy.hierarchical != this.form.hierarchical)
formNotSaved = true;
if (this.taxonomy.status != this.form.status) if (this.taxonomy.status != this.form.status)
formNotSaved = true; formNotSaved = true;
if (this.taxonomy.enabled_post_types != this.form.enabledPostTypes) if (this.taxonomy.enabled_post_types != this.form.enabledPostTypes)
@ -278,23 +312,7 @@
trapFocus: true, trapFocus: true,
customClass: 'tainacan-modal', customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close') closeButtonAriaLabel: this.$i18n.get('close')
}); });
} else if (this.isEditingTerm) {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_terms_not_saved'),
onConfirm: () => {
next();
}
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else { } else {
next(); next();
} }
@ -306,13 +324,13 @@
taxonomy: null, taxonomy: null,
isLoadingTaxonomy: false, isLoadingTaxonomy: false,
isUpdatingSlug: false, isUpdatingSlug: false,
isEditingTerm: false,
form: { form: {
name: String, name: String,
status: String, status: String,
description: String, description: String,
slug: String, slug: String,
allowInsert: String, allowInsert: String,
hierarchical: String,
enabledPostTypes: Array enabledPostTypes: Array
}, },
wpPostTypes: tainacan_plugin.wp_post_types, wpPostTypes: tainacan_plugin.wp_post_types,
@ -320,7 +338,8 @@
formErrorMessage: '', formErrorMessage: '',
entityName: 'taxonomy', entityName: 'taxonomy',
updatedAt: undefined, updatedAt: undefined,
shouldReloadTermsList: false shouldReloadTermsList: false,
themeTaxonomiesURL: tainacan_plugin.theme_taxonomy_list_url
} }
}, },
mounted(){ mounted(){
@ -354,6 +373,7 @@
this.form.slug = this.taxonomy.slug; this.form.slug = this.taxonomy.slug;
this.form.status = this.taxonomy.status; this.form.status = this.taxonomy.status;
this.form.allowInsert = this.taxonomy.allow_insert; this.form.allowInsert = this.taxonomy.allow_insert;
this.form.hierarchical = this.taxonomy.hierarchical;
this.form.enabledPostTypes = this.taxonomy.enabled_post_types; this.form.enabledPostTypes = this.taxonomy.enabled_post_types;
this.isLoadingTaxonomy = false; this.isLoadingTaxonomy = false;
@ -390,6 +410,7 @@
slug: this.form.slug ? this.form.slug : '', slug: this.form.slug ? this.form.slug : '',
status: this.form.status, status: this.form.status,
allow_insert: this.form.allowInsert, allow_insert: this.form.allowInsert,
hierarchical: this.form.hierarchical,
enabled_post_types: this.form.enabledPostTypes, enabled_post_types: this.form.enabledPostTypes,
context: 'edit' context: 'edit'
}; };
@ -407,6 +428,7 @@
this.form.description = this.taxonomy.description; this.form.description = this.taxonomy.description;
this.form.status = this.taxonomy.status; this.form.status = this.taxonomy.status;
this.form.allowInsert = this.taxonomy.allow_insert; this.form.allowInsert = this.taxonomy.allow_insert;
this.form.hierarchical = this.taxonomy.hierarchical;
this.form.enabledPostTypes = this.taxonomy.enabled_post_types; this.form.enabledPostTypes = this.taxonomy.enabled_post_types;
this.isLoadingTaxonomy = false; this.isLoadingTaxonomy = false;
@ -463,7 +485,8 @@
description: '', description: '',
status: 'auto-draft', status: 'auto-draft',
slug: '', slug: '',
allow_insert: '', allow_insert: 'yes',
hierarchical: 'yes'
}; };
this.fillExtraFormData(data); this.fillExtraFormData(data);
this.createTaxonomy(data) this.createTaxonomy(data)
@ -477,6 +500,7 @@
this.form.description = this.taxonomy.description; this.form.description = this.taxonomy.description;
this.form.slug = this.taxonomy.slug; this.form.slug = this.taxonomy.slug;
this.form.allowInsert = this.taxonomy.allow_insert; this.form.allowInsert = this.taxonomy.allow_insert;
this.form.hierarchical = this.taxonomy.hierarchical;
// Pre-fill status with publish to incentivate it // Pre-fill status with publish to incentivate it
this.form.status = 'publish'; this.form.status = 'publish';
@ -496,25 +520,19 @@
cancelBack(){ cancelBack(){
this.$router.go(-1); this.$router.go(-1);
}, },
labelNewTerms(){
return ( this.form.allowInsert === 'yes' ) ? this.$i18n.get('label_yes') : this.$i18n.get('label_no');
},
isEditingTermUpdate (value) {
this.isEditingTerm = value;
},
goToCreateAnotherTaxonomy() { goToCreateAnotherTaxonomy() {
this.$router.push(this.$routerHelper.getNewTaxonomyPath()); this.$router.push(this.$routerHelper.getNewTaxonomyPath());
this.taxonomyId = undefined; this.taxonomyId = undefined;
this.taxonomy = null; this.taxonomy = null;
this.isUpdatingSlug = false; this.isUpdatingSlug = false;
this.isEditingTerm = false,
this.form = { this.form = {
name: String, name: String,
status: String, status: String,
description: String, description: String,
slug: String, slug: String,
allowInsert: String, allowInsert: String,
hierarchical: String,
enabledPostTypes: Array enabledPostTypes: Array
}; };
this.editFormErrors = {}; this.editFormErrors = {};
@ -542,13 +560,17 @@
align-items: center; align-items: center;
} }
.tainacan-form>.columns { .tainacan-form>.columns {
margin-bottom: var(--tainacan-container-padding); margin-bottom: 48px;
}
.tainacan-form .column {
padding: 1em var(--tainacan-one-column);
} }
.tainacan-form .column:last-of-type { .tainacan-form .column:last-of-type {
padding-left: 0; padding-left: var(--tainacan-one-column) !important;
}
.two-columns-fields {
column-width: 180px;
.field {
margin-bottom: 0px;
}
} }
.form-submit { .form-submit {
align-items: center; align-items: center;
@ -558,5 +580,61 @@
color: var(--tainacan-info-color); color: var(--tainacan-info-color);
font-style: italic; font-style: italic;
} }
.footer {
padding: 14px var(--tainacan-one-column);
position: fixed;
bottom: 0;
right: 0;
z-index: 9999;
background-color: var(--tainacan-gray1);
width: calc(100% - var(--tainacan-sidebar-width, 3.25em));
height: 60px;
display: flex;
justify-content: flex-end;
align-items: center;
transition: bottom 0.5s ease, width 0.2s linear;
.footer-message {
display: flex;
align-items: center;
}
.update-info-section {
color: var(--tainacan-info-color);
margin-right: auto;
display: flex;
flex-wrap: nowrap;
}
.help {
display: inline-flex;
font-size: 1.0em;
margin-top: 0;
margin-left: 24px;
.tainacan-help-tooltip-trigger {
margin-left: 0.25em;
}
}
.link-button {
background-color: transparent;
border: none;
}
@media screen and (max-width: 769px) {
padding: 13px 0.5em;
width: 100%;
flex-wrap: wrap;
height: auto;
position: fixed;
.update-info-section {
margin-left: auto;margin-bottom: 0.75em;
margin-top: -0.25em;
}
}
}
</style> </style>

View File

@ -5,14 +5,11 @@
tabindex="-1" tabindex="-1"
aria-modal aria-modal
id="termEditForm" id="termEditForm"
class="tainacan-form" class="tainacan-form tainacan-modal-content"
:class="{ 'tainacan-modal-content': isModal }"
@submit.prevent="saveEdition(form)"> @submit.prevent="saveEdition(form)">
<component <header
:is="isModal ? 'header' : 'div'" class="tainacan-page-title tainacan-modal-title">
class="tainacan-page-title" <h2 style="width: 60%">{{ form & form.id && form.id != 'new' ? $i18n.get("title_term_edit") : $i18n.get("title_term_creation") }}</h2>
:class="{ 'tainacan-modal-title': isModal }">
<h2>{{ form & form.id && form.id != 'new' ? $i18n.get("title_term_edit") : $i18n.get("title_term_creation") }}</h2>
<a <a
v-if="form && form.url != undefined && form.url!= ''" v-if="form && form.url != undefined && form.url!= ''"
target="_blank" target="_blank"
@ -20,12 +17,12 @@
<span class="icon"> <span class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-see"/> <i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-see"/>
</span> </span>
<span class="menu-text">{{ $i18n.get('label_view_on_theme') }}</span> <span class="menu-text">{{ $i18n.get('label_term_page_on_website') }}</span>
</a> </a>
<hr> <hr>
</component> </header>
<div :class="isModal ? 'modal-card-body' : ''"> <div class="modal-card-body">
<b-loading <b-loading
:is-full-page="false" :is-full-page="false"
:active.sync="isLoading" /> :active.sync="isLoading" />
@ -109,7 +106,6 @@
</span> </span>
</a> </a>
</div> </div>
<br>
</div> </div>
</b-field> </b-field>
</div> </div>
@ -138,6 +134,7 @@
<!-- Parent -------------- --> <!-- Parent -------------- -->
<b-field <b-field
v-if="isHierarchical"
:addons="false" :addons="false"
:type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''" :type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
:message="formErrors.parent ? formErrors : formErrors.repeated"> :message="formErrors.parent ? formErrors : formErrors.repeated">
@ -165,6 +162,7 @@
@input="fetchParentTerms" @input="fetchParentTerms"
@focus="clearErrors('parent');" @focus="clearErrors('parent');"
:disabled="!hasParent" :disabled="!hasParent"
:append-to-body="true"
check-infinite-scroll check-infinite-scroll
@infinite-scroll="fetchMoreParentTerms"> @infinite-scroll="fetchMoreParentTerms">
<template slot-scope="props"> <template slot-scope="props">
@ -186,7 +184,7 @@
<transition name="fade"> <transition name="fade">
<p <p
class="checkboxes-warning" class="checkboxes-warning"
v-show="isModal != true && showCheckboxesWarning == true"> v-show="isTermInsertionFlow != true && showCheckboxesWarning == true">
{{ $i18n.get('info_warning_changing_parent_term') }} {{ $i18n.get('info_warning_changing_parent_term') }}
</p> </p>
</transition> </transition>
@ -215,7 +213,7 @@
<button <button
class="button is-success" class="button is-success"
type="submit"> type="submit">
{{ isModal ? $i18n.get('label_create_and_select') : $i18n.get('save') }} {{ isTermInsertionFlow ? $i18n.get('label_create_and_select') : $i18n.get('save') }}
</button> </button>
</div> </div>
</div> </div>
@ -225,7 +223,7 @@
<script> <script>
import { formHooks } from "../../js/mixins"; import { formHooks } from "../../js/mixins";
import { mapActions, mapGetters } from 'vuex'; import { mapActions } from 'vuex';
import wpMediaFrames from '../../js/wp-media-frames'; import wpMediaFrames from '../../js/wp-media-frames';
export default { export default {
@ -234,7 +232,8 @@
props: { props: {
originalForm: Object, originalForm: Object,
taxonomyId: '', taxonomyId: '',
isModal: false isHierarchical: Boolean,
isTermInsertionFlow: false
}, },
data() { data() {
return { return {
@ -251,7 +250,8 @@
isLoading: false, isLoading: false,
parentTermSearchQuery: '', parentTermSearchQuery: '',
parentTermSearchOffset: 0, parentTermSearchOffset: 0,
form: {} form: {},
totalTerms: undefined
} }
}, },
created() { created() {
@ -290,13 +290,10 @@
methods: { methods: {
...mapActions('taxonomy', [ ...mapActions('taxonomy', [
'sendChildTerm', 'sendChildTerm',
'updateChildTerm', 'updateTerm',
'fetchParentName', 'fetchParentName',
'fetchPossibleParentTerms' 'fetchPossibleParentTerms'
]), ]),
...mapGetters('taxonomy', [
'getTerms'
]),
saveEdition(term) { saveEdition(term) {
if (term.id === 'new') { if (term.id === 'new') {
@ -314,12 +311,11 @@
term: data term: data
}) })
.then((term) => { .then((term) => {
this.$emit('onEditionFinished', {term: term, hasChangedParent: this.hasChangedParent }); this.$emit('onEditionFinished', {term: term, hasChangedParent: this.hasChangedParent, initialParent: this.initialParentId });
this.form = {}; this.form = {};
this.formErrors = {}; this.formErrors = {};
this.isLoading = false; this.isLoading = false;
if (this.isModal) this.$parent.close();
this.$parent.close();
}) })
.catch((errors) => { .catch((errors) => {
this.isLoading = false; this.isLoading = false;
@ -329,7 +325,6 @@
this.$set(this.formErrors, metadatum, (this.formErrors[metadatum] !== undefined ? this.formErrors[metadatum] : '') + error[metadatum] + '\n'); this.$set(this.formErrors, metadatum, (this.formErrors[metadatum] !== undefined ? this.formErrors[metadatum] : '') + error[metadatum] + '\n');
} }
} }
this.$emit('onErrorFound');
}); });
} else { } else {
@ -341,18 +336,18 @@
parent: this.hasParent ? this.form.parent : 0, parent: this.hasParent ? this.form.parent : 0,
header_image_id: this.form.header_image_id, header_image_id: this.form.header_image_id,
header_image: this.form.header_image, header_image: this.form.header_image,
total_children: this.form.total_children ? this.form.total_children : 0
} }
this.fillExtraFormData(data); this.fillExtraFormData(data);
this.isLoading = true; this.isLoading = true;
this.updateChildTerm({ this.updateTerm({
taxonomyId: this.taxonomyId, taxonomyId: this.taxonomyId,
term: data term: data
}) })
.then((term) => { .then((term) => {
this.formErrors = {}; this.formErrors = {};
this.$emit('onEditionFinished', { term: term, hasChangedParent: this.hasChangedParent }); this.$emit('onEditionFinished', { term: term, hasChangedParent: this.hasChangedParent, initialParent: this.initialParentId });
if (this.isModal) this.$parent.close();
this.$parent.close();
}) })
.catch((errors) => { .catch((errors) => {
for (let error of errors.errors) { for (let error of errors.errors) {
@ -361,14 +356,11 @@
} }
} }
this.isLoading = false; this.isLoading = false;
this.$emit('onErrorFound');
}); });
} }
}, },
cancelEdition() { cancelEdition() {
this.$emit('onEditionCanceled', this.form); this.$parent.close();
if (this.isModal)
this.$parent.close();
}, },
deleteHeaderImage() { deleteHeaderImage() {
this.form = Object.assign({}, this.form = Object.assign({},
@ -426,8 +418,8 @@
} }
// No need to load more // No need to load more
if (this.parentTermSearchOffset > 0 && this.parentTerms.length >= this.totalTerms) if (this.parentTermSearchOffset > 0 && this.totalTerms !== undefined && this.parentTerms.length >= this.totalTerms)
return return;
this.isFetchingParentTerms = true; this.isFetchingParentTerms = true;
@ -465,11 +457,13 @@
this.clearErrors('parent'); this.clearErrors('parent');
}, },
onSelectParentTerm(selectedParentTerm) { onSelectParentTerm(selectedParentTerm) {
this.hasChangedParent = this.initialParentId != selectedParentTerm.id; if ( selectedParentTerm ) {
this.form.parent = selectedParentTerm.id; this.hasChangedParent = this.initialParentId != selectedParentTerm.id;
this.selectedParentTerm = selectedParentTerm; this.form.parent = selectedParentTerm.id;
this.parentTermName = selectedParentTerm.name; this.selectedParentTerm = selectedParentTerm;
this.showCheckboxesWarning = true; this.parentTermName = selectedParentTerm.name;
this.showCheckboxesWarning = true;
}
} }
} }
} }
@ -508,8 +502,14 @@
&.tainacan-modal-content { &.tainacan-modal-content {
overflow: hidden; overflow: hidden;
.field {
padding-left: 0;
margin-left: 0;
}
.tainacan-modal-title { .tainacan-modal-title {
margin-bottom: 0; margin: 0;
padding: 0 12px;
} }
.thumbnail-field { .thumbnail-field {
max-width: 120px; max-width: 120px;
@ -517,9 +517,6 @@
.image-placeholder { .image-placeholder {
left: 2px; left: 2px;
} }
.form-submit {
padding-top: 0px !important;
}
} }
.tainacan-page-title { .tainacan-page-title {
@ -545,7 +542,6 @@
.image-and-description-area { .image-and-description-area {
margin-bottom: 0px; margin-bottom: 0px;
margin-top: 24px;
.column:first-of-type { .column:first-of-type {
margin-right: 24px; margin-right: 24px;

View File

@ -70,21 +70,6 @@
$i18n.get('info_of') + totalAttachments + '.' $i18n.get('info_of') + totalAttachments + '.'
}} }}
</div> </div>
<!-- <div class="items-per-page">
<b-field
horizontal
:label="$i18n.get('label_attachments_per_page')">
<b-select
:value="attachmentsPerPage"
@input="onChangeAttachmentsPerPage"
:disabled="attachments.length <= 0">
<option value="12">12</option>
<option value="24">24</option>
<option value="48">48</option>
<option value="96">96</option>
</b-select>
</b-field>
</div> -->
<div class="pagination"> <div class="pagination">
<b-pagination <b-pagination
@change="onPageChange" @change="onPageChange"

View File

@ -1,268 +0,0 @@
<template>
<div
style="width: 100%;">
<div
class="term-item"
:class="{
'opened-term': term.opened
}">
<span
class="term-name"
:class="{'is-danger': formWithErrors == term.id }"
v-html="term.hierarchy_path ? (`<span class='term-name-hierarchy-path'>${term.hierarchy_path}</span>${term.name}`) : term.name" />
<span
v-if="term.id != undefined"
class="label-details">
<span
class="not-saved"
v-if="term.id == 'new'">
{{ $i18n.get('info_not_saved') }}
</span>
</span>
<span
v-if="currentUserCanEditTaxonomy"
class="controls"
:class="{'is-disabled': isEditingTerm}">
<a
@click.prevent="editTerm()">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-edit"/>
</span>
</a>
<a @click.prevent="tryToRemoveTerm()">
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-delete"/>
</span>
</a>
</span>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'BasicTermItem',
props: {
term: Object,
index: Number,
taxonomyId: Number,
order: String,
currentUserCanEditTaxonomy: Boolean
},
data(){
return {
isLoadingTerms: false,
isEditingTerm: false
}
},
created() {
this.$eventBusTermsList.$on('editTerm', this.eventOnEditTerm);
this.$eventBusTermsList.$on('termEditionSaved', this.eventOnTermEditionSaved);
this.$eventBusTermsList.$on('termEditionCanceled', this.eventOnTermEditionCanceled);
},
beforeDestroy() {
this.$eventBusTermsList.$off('editTerm', this.eventOnEditTerm);
this.$eventBusTermsList.$off('termEditionSaved', this.eventOnTermEditionSaved);
this.$eventBusTermsList.$off('termEditionCanceled', this.eventOnTermEditionCanceled);
},
methods: {
...mapActions('taxonomy', [
'updateTerm',
'deleteTerm'
]),
editTerm() {
this.$emit('onUpdateTermOpenedState', !this.term.opened);
this.$eventBusTermsList.onEditTerm(this.term);
},
tryToRemoveTerm() {
// Checks if user is deleting a term with unsaved info.
if (this.term.id == 'new') {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_terms_not_saved'),
onConfirm: () => { this.removeTerm(); },
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
this.removeTerm();
}
},
removeTerm() {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_selected_term_delete'),
onConfirm: () => {
// If all checks passed, term can be deleted
this.$eventBusTermsList.onDeleteBasicTermItem(this.term);
}
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
},
eventOnEditTerm() {
this.isEditingTerm = true;
},
eventOnTermEditionSaved() {
this.isEditingTerm = false;
this.$emit('onUpdateTermOpenedState', false);
},
eventOnTermEditionCanceled() {
this.isEditingTerm = false;
this.$emit('onUpdateTermOpenedState', false);
}
}
}
</script>
<style lang="scss" scoped>
// Term Item
.term-item {
padding: 0 0 0 1.75em;
min-height: 2.5em;
display: flex;
position: relative;
align-items: center;
justify-content: space-between;
border-left: 1px solid transparent;
visibility: visible;
opacity: 1;
transition: display 0.3s, visibility 0.3s, opacity 0.3s;
width: 100%;
&:first-child:hover {
background-color: var(--tainacan-gray1) !important;
.controls {
visibility: visible;
opacity: 1.0;
}
&::before {
border-color: transparent transparent transparent var(--tainacan-gray2) !important;
}
}
.term-name {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
margin-left: 0.4em;
margin-right: 0.4em;
display: inline-block;
max-width: 73%;
color: var(--tainacan-gray5);
&.is-danger {
color: var(--tainacan-danger) !important;
}
}
/deep/ .term-name-hierarchy-path {
color: var(--tainacan-gray-4);
}
.label-details {
font-weight: normal;
color: var(--tainacan-gray3);
margin-right: auto;
}
.not-saved {
font-style: italic;
font-weight: bold;
color: var(--tainacan-danger);
}
.controls {
height: 3.125em;
visibility: hidden;
opacity: 0.0;
display: flex;
justify-content: space-between;
background-color: var(--tainacan-gray2);
padding: 0.65em 0.875em;
a {
display: flex;
align-items: center;
margin: 0 0.375em;
.icon {
bottom: 1px;
position: relative;
i, i:before { font-size: 1.25em; }
}
}
}
.controls.is-disabled a {
color: var(--tainacan-info-color) !important;
cursor: not-allowed !important;
user-select: none;
}
&.opened-term:first-child {
cursor: default;
background-color: var(--tainacan-blue1);
&:before {
content: '';
display: block;
position: absolute;
left: 100%;
right: -20px;
width: 0;
height: 0;
border-style: solid;
border-color: transparent transparent transparent var(--tainacan-blue1);
border-left-width: 24px;
border-top-width: 1.55em;
border-bottom-width: 1.55em;
top: 0;
}
&:hover:before {
border-color: transparent transparent transparent var(--tainacan-gray1);
}
}
&.collapsed-term {
display: none;
visibility: hidden;
opacity: 0;
transition: display 0.3s, visibility 0.3s, opacity 0.3s;
}
}
.view-more-terms {
font-size: 0.875em;
margin: 0 0 0 1.75em !important;
padding: 0.5em 0 0.5em 1.75em;
display: flex;
border-top: 1px solid var(--tainacan-gray1);
}
</style>

View File

@ -1426,7 +1426,7 @@
v-for="(column, columnIndex) in displayedMetadata" v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex" :key="columnIndex"
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')" v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" /> v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : (`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" />
<p <p
v-tooltip="{ v-tooltip="{
delay: { delay: {
@ -1442,7 +1442,7 @@
v-for="(column, columnIndex) in displayedMetadata" v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex" :key="columnIndex"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')" v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.title != undefined ? item.title : ''" /> v-html="item.title != undefined ? item.title : (`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" />
<div class="tainacan-map-card-thumbnail"> <div class="tainacan-map-card-thumbnail">
<blur-hash-image <blur-hash-image
v-if="item.thumbnail != undefined" v-if="item.thumbnail != undefined"
@ -2542,7 +2542,6 @@ export default {
.select-all { .select-all {
color: var(--tainacan-info-color); color: var(--tainacan-info-color);
font-size: 0.875em;
margin-right: auto; margin-right: auto;
margin-bottom: 0; margin-bottom: 0;

View File

@ -239,9 +239,9 @@ export default {
} }
}, },
mounted() { mounted() {
/* If we're in a collection list, the metadata won't exist as they are read inside sections */ /* If we're in a collection list, the metadata won't exist as they are read inside sections */
if (!this.isRepositoryLevel) { if ( !this.isRepositoryLevel ) {
this.collectionId = this.$route.params.collectionId; this.collectionId = this.$route.params.collectionId;
this.isLoadingMetadata = true; this.isLoadingMetadata = true;
@ -253,14 +253,17 @@ export default {
isContextEdit: true, isContextEdit: true,
includeDisabled: true, includeDisabled: true,
includeOptionsAsHtml: false includeOptionsAsHtml: false
}).then((resp) => {
resp.request
.then(() => {
this.loadMetadataMappers();
this.isLoadingMetadata = false;
})
.catch(() => {
this.isLoadingMetadata = false;
});
}) })
.then(() => { .catch(() => this.isLoadingMetadata = false);
this.loadMetadataMappers();
this.isLoadingMetadata = false;
})
.catch(() => {
this.isLoadingMetadata = false;
});
} else { } else {
this.loadMetadataMappers(); this.loadMetadataMappers();
} }
@ -281,7 +284,7 @@ export default {
this.fetchMetadatumMappers() this.fetchMetadatumMappers()
.then(() => { .then(() => {
this.isLoadingMetadatumMappers = false; this.isLoadingMetadatumMappers = false;
if (this.metadatumMappers.length >= 1) if (this.metadatumMappers.length >= 1)
this.onSelectMetadataMapper(this.metadatumMappers[0]) this.onSelectMetadataMapper(this.metadatumMappers[0])
}) })
@ -294,7 +297,7 @@ export default {
this.isMapperMetadataLoading = true; this.isMapperMetadataLoading = true;
this.mapper = metadatumMapper; //TODO try to use v-model again this.mapper = metadatumMapper; //TODO try to use v-model again
this.mapperMetadata = []; this.mapperMetadata = [];
if (metadatumMapper != '') { if (metadatumMapper != '') {
for (var k in metadatumMapper.metadata) { for (var k in metadatumMapper.metadata) {
var item = metadatumMapper.metadata[k]; var item = metadatumMapper.metadata[k];
@ -376,8 +379,6 @@ export default {
metadataMapperMetadata: metadataMapperMetadata, metadataMapperMetadata: metadataMapperMetadata,
mapper: this.mapper.slug mapper: this.mapper.slug
}).then(() => { }).then(() => {
this.isLoadingMetadata = true;
this.refreshMetadata();
this.isMapperMetadataLoading = false; this.isMapperMetadataLoading = false;
}) })
.catch(() => { .catch(() => {

View File

@ -1,461 +0,0 @@
<template>
<div
style="width: 100%;">
<div
class="term-item"
:style="{
'border-left-color': term.parent > 0 ? 'var(--tainacan-gray1)' : 'transparent'
}"
:class="{
'opened-term': term.opened
}">
<span
v-if="term.parent != 0 && index == 0"
class="icon children-icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-nextlevel"/>
</span>
<span
v-tooltip="{
content: $i18n.get('label_show_children_terms'),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
placement: 'bottom'
}"
class="children-dropdown icon">
<i
:class="{
'tainacan-icon-arrowright': !showChildren,
'tainacan-icon-arrowdown': showChildren,
'is-disabled': isEditingTerm }"
class="tainacan-icon tainacan-icon-36px"
v-if="term.total_children > 0"
@click.prevent="toggleShowChildren()"/>
</span>
<span
class="term-name"
:class="{'is-danger': formWithErrors == term.id, 'is-italic': !term.name }">
{{ term.name ? term.name : $i18n.get('label_term_without_name') }}
</span>
<span
v-if="term.id == 'new'"
class="label-details">
<span class="not-saved" >
{{ $i18n.get('info_not_saved') }}
</span>
</span>
<span
class="children-counter"
v-if="term.total_children > 0">
<span>{{ term.total_children + ' ' + $i18n.get('label_children_terms') }}</span>
</span>
<span
v-if="currentUserCanEditTaxonomy"
class="controls"
:class="{'is-disabled': isEditingTerm}">
<a @click="addNewChildTerm(term, index)">
<span
v-tooltip="{
content: $i18n.get('label_new_child'),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-add"/>
</span>
</a>
<a
@click.prevent="editTerm()">
<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>
</a>
<a @click.prevent="tryToRemoveTerm()">
<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>
</a>
</span>
</div>
<transition-group
class="children-area"
name="filter-item">
<div
class="term-item"
:style="{
'border-left-color': term.parent > 0 && childTerm.parent > 0 ? 'var(--tainacan-gray1)' : 'transparent'
}"
:class="{
'opened-term': childTerm.opened,
}"
v-for="(childTerm, childIndex) in term.children"
:key="childTerm.id"
v-if="showChildren">
<recursive-term-item
:term="childTerm"
:index="childIndex"
:taxonomy-id="taxonomyId"
:order="order"
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
@onUpdateTermOpenedState="(state) => childTerm.opened = state"/>
</div>
</transition-group>
<a
class="view-more-terms"
:class="{'is-disabled': isEditingTerm}"
@click="offset = offset + maxTerms; loadChildTerms(term.id)"
v-if="showChildren && term.children != undefined && (totalTerms > term.children.length)">
{{ $i18n.get('label_view_more') + ' (' + Number(totalTerms - term.children.length) + ' ' + $i18n.get('terms') + ')' }}
</a>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'RecursiveTermItem',
props: {
term: Object,
index: Number,
taxonomyId: Number,
order: String,
currentUserCanEditTaxonomy: Boolean
},
data(){
return {
isLoadingTerms: false,
isEditingTerm: false,
searchQuery: '',
showChildren: false,
maxTerms: 100,
offset: 0,
totalTerms: 0
}
},
created() {
this.$root.$on('onChildTermDeleted', this.eventOnChildTermDeleted);
this.$eventBusTermsList.$on('editTerm', this.eventOnEditTerm);
this.$eventBusTermsList.$on('termEditionSaved', this.eventOnTermEditionSaved);
this.$eventBusTermsList.$on('termEditionCanceled', this.eventOnTermEditionCanceled);
},
beforeDestroy() {
this.$root.$off('onChildTermDeleted', this.eventOnChildTermDeleted);
this.$eventBusTermsList.$off('editTerm', this.eventOnEditTerm);
this.$eventBusTermsList.$off('termEditionSaved', this.eventOnTermEditionSaved);
this.$eventBusTermsList.$off('termEditionCanceled', this.eventOnTermEditionCanceled);
},
methods: {
...mapActions('taxonomy', [
'updateChildTerm',
'deleteChildTerm',
'fetchChildTerms',
'clearTerms',
'updateChildTermLocal'
]),
teste() {
this.totalTerms = this.totalTerms - 1;
},
addNewChildTerm() {
this.showChildren = true;
this.$eventBusTermsList.onAddNewChildTerm(this.term.id);
},
toggleShowChildren() {
if (!this.isLoadingTerms && (this.term.children == undefined || this.term.children.length <= 0)) {
this.loadChildTerms(this.term.id);
} else {
this.showChildren = !this.showChildren;
}
},
loadChildTerms(parentId) {
this.isLoadingTerms = true;
let search = (this.searchQuery != undefined && this.searchQuery != '') ? { searchterm: this.searchQuery } : '';
this.fetchChildTerms({
parentId: parentId,
taxonomyId: this.taxonomyId,
fetchOnly: '',
search: search,
all: '',
order: this.order,
offset: this.offset,
number: this.maxTerms
})
.then((resp) => {
this.isLoadingTerms = false;
this.showChildren = true;
this.totalTerms = resp.total;
})
.catch((error) => {
this.isLoadingTerms = false;
this.$console.log(error);
});
},
editTerm() {
this.$emit('onUpdateTermOpenedState', !this.term.opened);
this.$eventBusTermsList.onEditTerm(this.term);
},
tryToRemoveTerm() {
// Checks if user is deleting a term with unsaved info.
if (this.term.id == 'new') {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_terms_not_saved'),
onConfirm: () => { this.removeTerm(); },
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
this.removeTerm();
}
},
removeTerm() {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_selected_term_delete'),
onConfirm: () => {
// If all checks passed, term can be deleted
this.deleteChildTerm({
taxonomyId: this.taxonomyId,
termId: this.term.id,
parent: this.term.parent })
.then(() => {
this.$root.$emit('onChildTermDeleted', this.term.parent);
})
.catch((error) => {
this.$console.log(error);
});
// Updates parent IDs for orphans
if (this.term.children != undefined && this.term.children.length > 0) {
for (let orphanTerm of this.term.children) {
this.updateChildTermLocal({
term: orphanTerm,
parent: this.term.parent,
oldParent: this.term.id
});
}
}
}
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
},
eventOnChildTermDeleted(parentTermId) {
if (this.term.id == parentTermId && this.totalTerms > 0) {
this.totalTerms--;
this.loadChildTerms(parentTermId);
}
},
eventOnEditTerm() {
this.isEditingTerm = true;
},
eventOnTermEditionSaved($event) {
if (this.term.id == $event.term.id) {
this.$set(this.term, 'description', $event.term.description);
this.$set(this.term, 'header_image', $event.term.header_image);
this.$set(this.term, 'header_image_id', $event.term.header_image_id);
this.$set(this.term, 'name', $event.term.name);
this.$set(this.term, 'parent', $event.term.parent);
this.$set(this.term, 'id', $event.term.id);
} else if (this.term.children != undefined) {
for (let i = 0; i < this.term.children.length; i++) {
if (this.term.children[i].id == $event.term.id) {
this.$set(this.term.children[i], 'description', $event.term.description);
this.$set(this.term.children[i], 'header_image', $event.term.header_image);
this.$set(this.term.children[i], 'header_image_id', $event.term.header_image_id);
this.$set(this.term.children[i], 'name', $event.term.name);
this.$set(this.term.children[i], 'parent', $event.term.parent);
this.$set(this.term.children[i], 'id', $event.term.id);
}
}
}
this.isEditingTerm = false;
this.$emit('onUpdateTermOpenedState', false);
},
eventOnTermEditionCanceled() {
this.isEditingTerm = false;
this.$emit('onUpdateTermOpenedState', false);
}
}
}
</script>
<style lang="scss" scoped>
// Term Item
.term-item {
padding: 0 0 0 1.75em;
min-height: 2.5em;
display: flex;
position: relative;
align-items: center;
justify-content: space-between;
border-left: 1px solid transparent;
visibility: visible;
opacity: 1;
width: 100%;
& .term-item:first-child:hover {
background-color: var(--tainacan-gray1) !important;
.controls {
visibility: visible;
opacity: 1.0;
}
&::before {
border-color: transparent transparent transparent var(--tainacan-gray2) !important;
}
}
.children-icon {
color: var(--tainacan-blue2);
position: absolute;
left: -1.3125em;
top: 1px;
font-size: 1.5em;
}
.children-dropdown {
color: var(--tainacan-blue4);
position: absolute;
left: 5px;
cursor: pointer;
}
.term-name {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
margin-left: 0.4em;
margin-right: 0.4em;
display: inline-block;
max-width: 73%;
&.is-danger {
color: var(--tainacan-danger) !important;
}
}
.label-details {
font-weight: normal;
color: var(--tainacan-gray3);
margin-left: 1em;
margin-right: auto;
}
.children-counter {
margin-left: 1em;
margin-right: auto;
color: var(--tainacan-info-color);
padding-right: 1em;
white-space: nowrap;
overflow: hidden;
}
.not-saved {
font-style: italic;
font-weight: bold;
color: var(--tainacan-danger);
}
.controls {
height: 3.125em;
visibility: hidden;
opacity: 0.0;
display: flex;
justify-content: space-between;
background-color: var(--tainacan-gray2);
padding: 0.65em 0.875em;
a {
display: flex;
align-items: center;
margin: 0 0.375em;
.icon {
bottom: 1px;
position: relative;
i, i:before { font-size: 1.25em; }
}
}
}
.controls.is-disabled a, .children-dropdown i.is-disabled {
color: var(--tainacan-info-color) !important;
cursor: not-allowed !important;
user-select: none;
}
&.opened-term>div:first-child>div {
cursor: default;
background-color: var(--tainacan-gray1);
&:before {
content: '';
display: block;
position: absolute;
left: 100%;
right: -20px;
width: 0;
height: 0;
border-style: solid;
border-color: transparent transparent transparent var(--tainacan-gray1);
border-left-width: 24px;
border-top-width: 1.55em;
border-bottom-width: 1.55em;
top: 0;
}
&:hover:before {
border-color: transparent transparent transparent var(--tainacan-gray1);
}
}
&.collapsed-term {
display: none;
visibility: hidden;
opacity: 0;
}
}
.view-more-terms {
font-size: 0.875em;
margin: 0 0 0 1.75em !important;
padding: 0.5em 0 0.5em 1.75em;
display: flex;
border-top: 1px solid var(--tainacan-gray1);
}
</style>

View File

@ -68,6 +68,10 @@
<th> <th>
<div class="th-wrap">{{ $i18n.get('label_collections_using') }}</div> <div class="th-wrap">{{ $i18n.get('label_collections_using') }}</div>
</th> </th>
<!-- Total Items -->
<th v-if="!isOnTrash">
<div class="th-wrap total-terms-header">{{ $i18n.get('label_total_terms') }}</div>
</th>
<!-- Actions --> <!-- Actions -->
<th <th
v-if="taxonomies.findIndex((taxonomy) => taxonomy.current_user_can_edit || taxonomy.current_user_can_delete) >= 0" v-if="taxonomies.findIndex((taxonomy) => taxonomy.current_user_can_edit || taxonomy.current_user_can_delete) >= 0"
@ -162,11 +166,33 @@
}, },
content: (taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections, taxonomy.metadata_by_collection) : $i18n.get('label_no_collections_using_taxonomy'), content: (taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections, taxonomy.metadata_by_collection) : $i18n.get('label_no_collections_using_taxonomy'),
autoHide: false, autoHide: false,
html: true,
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'], popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
placement: 'auto-start' placement: 'auto-start'
}" }"
v-html="(taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections, taxonomy.metadata_by_collection) : $i18n.get('label_no_collections_using_taxonomy')" /> v-html="(taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections, taxonomy.metadata_by_collection) : $i18n.get('label_no_collections_using_taxonomy')" />
</td> </td>
<!-- Total terms -->
<td
@click.self="onClickTaxonomy($event, taxonomy.id, index)"
class="column-small-width column-align-right"
:label="$i18n.get('label_total_terms')"
v-if="taxonomy.total_terms != undefined"
:aria-label="$i18n.get('label_total_terms') + ': ' + taxonomy.total_terms['total']">
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: getTotalTermsDetailed(taxonomy.total_terms),
autoHide: false,
html: true,
popperClass: ['tainacan-tooltip', 'tooltip', 'tainacan-repository-tooltip'],
placement: 'auto-start'
}"
v-html="taxonomy.total_terms['total']" />
</td>
<!-- Actions --> <!-- Actions -->
<td <td
v-if="taxonomy.current_user_can_edit || taxonomy.current_user_can_delete" v-if="taxonomy.current_user_can_edit || taxonomy.current_user_can_delete"
@ -276,6 +302,9 @@
for (let i = 0; i < this.selected.length; i++) for (let i = 0; i < this.selected.length; i++)
this.selected.splice(i, 1, !this.allOnPageSelected); this.selected.splice(i, 1, !this.allOnPageSelected);
}, },
getTotalTermsDetailed(total_terms) {
return this.$i18n.get('label_total_terms') + ': ' + total_terms['total'] + '<br> ' + this.$i18n.get('label_root_terms') + ': ' + total_terms['root'] + '<br> ' + this.$i18n.get('label_used_by_items') + ': ' + total_terms['not_empty'];
},
deleteOneTaxonomy(taxonomyId) { deleteOneTaxonomy(taxonomyId) {
this.$buefy.modal.open({ this.$buefy.modal.open({
parent: this, parent: this,
@ -401,6 +430,10 @@
} }
} }
.total-terms-header {
text-align: right;
}
</style> </style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,9 @@
:ref="'tainacan-form-item--' + groupIndex + '-' + childIndex" :ref="'tainacan-form-item--' + groupIndex + '-' + childIndex"
:item-metadatum="childItemMetadatum" :item-metadatum="childItemMetadatum"
:hide-collapses="hideCollapses" :hide-collapses="hideCollapses"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="hideHelpButtons"
:help-info-bellow-label="helpInfoBellowLabel"
:is-collapsed="childItemMetadatum.collapse" :is-collapsed="childItemMetadatum.collapse"
:is-mobile-screen="isMobileScreen" :is-mobile-screen="isMobileScreen"
@changeCollapse="onChangeCollapse($event, groupIndex, childIndex)" @changeCollapse="onChangeCollapse($event, groupIndex, childIndex)"
@ -120,6 +123,9 @@
value: [String, Number, Array], value: [String, Number, Array],
disabled: false, disabled: false,
hideCollapses: false, hideCollapses: false,
hideMetadataTypes: Boolean,
hideHelpButtons: Boolean,
helpInfoBellowLabel: Boolean,
metadataNameFilterString: '', metadataNameFilterString: '',
isMobileScreen: false, isMobileScreen: false,
isMetadataNavigation: false, isMetadataNavigation: false,

View File

@ -29,13 +29,13 @@
* *
</span> </span>
<span <span
v-if="!$parent.hideMetadataTypes" v-if="!hideMetadataTypes"
class="metadata-type"> class="metadata-type">
({{ itemMetadatum.metadatum.metadata_type_object.name }}) ({{ itemMetadatum.metadatum.metadata_type_object.name }})
</span> </span>
<help-button <help-button
v-if="!$parent.hideHelpButtons && v-if="!hideHelpButtons &&
!$parent.helpInfoBellowLabel && !helpInfoBellowLabel &&
itemMetadatum.metadatum && itemMetadatum.metadatum &&
itemMetadatum.metadatum.description_bellow_name !== 'yes' && itemMetadatum.metadatum.description_bellow_name !== 'yes' &&
itemMetadatum.metadatum.description" itemMetadatum.metadatum.description"
@ -51,7 +51,7 @@
v-if="itemMetadatum.metadatum && v-if="itemMetadatum.metadatum &&
itemMetadatum.metadatum.description && itemMetadatum.metadatum.description &&
( (
(!$parent.hideHelpButtons && $parent.helpInfoBellowLabel) || (!hideHelpButtons && helpInfoBellowLabel) ||
(itemMetadatum.metadatum.description_bellow_name === 'yes') (itemMetadatum.metadatum.description_bellow_name === 'yes')
)"> )">
{{ itemMetadatum.metadatum.description }} {{ itemMetadatum.metadatum.description }}
@ -64,6 +64,9 @@
@blur="performValueChange" @blur="performValueChange"
:metadata-name-filter-string="metadataNameFilterString" :metadata-name-filter-string="metadataNameFilterString"
:hide-collapses="hideCollapses" :hide-collapses="hideCollapses"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="hideHelpButtons"
:help-info-bellow-label="helpInfoBellowLabel"
:is-mobile-screen="isMobileScreen" :is-mobile-screen="isMobileScreen"
@mobileSpecialFocus="onMobileSpecialFocus" @mobileSpecialFocus="onMobileSpecialFocus"
:is-focused="isFocused" :is-focused="isFocused"
@ -83,6 +86,9 @@
@blur="performValueChange" @blur="performValueChange"
:metadata-name-filter-string="metadataNameFilterString" :metadata-name-filter-string="metadataNameFilterString"
:hide-collapses="hideCollapses" :hide-collapses="hideCollapses"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="hideHelpButtons"
:help-info-bellow-label="helpInfoBellowLabel"
:is-mobile-screen="isMobileScreen" :is-mobile-screen="isMobileScreen"
@mobileSpecialFocus="onMobileSpecialFocus" @mobileSpecialFocus="onMobileSpecialFocus"
:is-focused="isFocused" :is-focused="isFocused"
@ -121,7 +127,7 @@
v-if="itemMetadatum.metadatum && v-if="itemMetadatum.metadatum &&
itemMetadatum.metadatum.description && itemMetadatum.metadatum.description &&
( (
(!$parent.hideHelpButtons && $parent.helpInfoBellowLabel) || (!hideHelpButtons && helpInfoBellowLabel) ||
(itemMetadatum.metadatum.description_bellow_name === 'yes') (itemMetadatum.metadatum.description_bellow_name === 'yes')
)"> )">
{{ itemMetadatum.metadatum.description }} {{ itemMetadatum.metadatum.description }}
@ -134,6 +140,9 @@
@blur="performValueChange" @blur="performValueChange"
:is-last-metadatum="isLastMetadatum" :is-last-metadatum="isLastMetadatum"
:hide-collapses="hideCollapses" :hide-collapses="hideCollapses"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="hideHelpButtons"
:help-info-bellow-label="helpInfoBellowLabel"
:is-mobile-screen="isMobileScreen" :is-mobile-screen="isMobileScreen"
:metadata-name-filter-string="metadataNameFilterString" :metadata-name-filter-string="metadataNameFilterString"
@mobileSpecialFocus="onMobileSpecialFocus" @mobileSpecialFocus="onMobileSpecialFocus"
@ -153,6 +162,9 @@
itemMetadatum: Object, itemMetadatum: Object,
isCollapsed: true, isCollapsed: true,
hideCollapses: false, hideCollapses: false,
hideMetadataTypes: Boolean,
hideHelpButtons: Boolean,
helpInfoBellowLabel: Boolean,
isLastMetadatum: false, isLastMetadatum: false,
metadataNameFilterString: '', metadataNameFilterString: '',
isMobileScreen: false, isMobileScreen: false,

View File

@ -44,7 +44,7 @@
<span class="icon is-small"> <span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/> <i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span> </span>
&nbsp;{{ $i18n.get('label_new_term') }} &nbsp;{{ $i18n.get('label_create_new_term') }}
</a> </a>
</div> </div>
@ -59,9 +59,10 @@
custom-class="tainacan-modal" custom-class="tainacan-modal"
:close-button-aria-label="$i18n.get('close')"> :close-button-aria-label="$i18n.get('close')">
<term-edition-form <term-edition-form
:is-hierarchical="isHierarchical"
:taxonomy-id="taxonomyId" :taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }" :original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
:is-modal="true" :is-term-insertion-flow="true"
@onEditionFinished="($event) => addRecentlyCreatedTerm($event.term)" @onEditionFinished="($event) => addRecentlyCreatedTerm($event.term)"
@onEditionCanceled="() => $console.log('Editing canceled')" @onEditionCanceled="() => $console.log('Editing canceled')"
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" /> @onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />
@ -70,6 +71,7 @@
<!-- Term creation panel, used on item submission block for a simpler term creation --> <!-- Term creation panel, used on item submission block for a simpler term creation -->
<transition name="filter-item"> <transition name="filter-item">
<term-creation-panel <term-creation-panel
:is-hierarchical="isHierarchical"
v-if="isTermCreationPanelOpen" v-if="isTermCreationPanelOpen"
:taxonomy-id="taxonomyId" :taxonomy-id="taxonomyId"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }" :original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
@ -139,6 +141,14 @@
!isNaN(this.itemMetadatum.metadatum.cardinality) && !isNaN(this.itemMetadatum.metadatum.cardinality) &&
this.itemMetadatum.metadatum.cardinality > 1 this.itemMetadatum.metadatum.cardinality > 1
) ? this.itemMetadatum.metadatum.cardinality : undefined; ) ? this.itemMetadatum.metadatum.cardinality : undefined;
},
isHierarchical() {
return (
this.itemMetadatum.metadatum &&
this.itemMetadatum.metadatum.metadata_type_object &&
this.itemMetadatum.metadatum.metadata_type_object.options &&
this.itemMetadatum.metadatum.metadata_type_object.options.hierarchical
) ? this.itemMetadatum.metadatum.metadata_type_object.options.hierarchical !== 'no' : true;
} }
}, },
watch: { watch: {

View File

@ -41,14 +41,14 @@
v-if="allowNew" v-if="allowNew"
slot="footer"> slot="footer">
<a @click="$emit('showAddNewTerm', { name: searchName })"> <a @click="$emit('showAddNewTerm', { name: searchName })">
{{ $i18n.get('label_new_term') + ' "' + searchName + '"' }} {{ $i18n.get('label_create_new_term') + ' "' + searchName + '"' }}
</a> </a>
</template> </template>
</b-taginput> </b-taginput>
</template> </template>
<script> <script>
import { mapActions, mapGetters } from 'vuex'; import { mapActions } from 'vuex';
export default { export default {
props: { props: {
@ -87,9 +87,6 @@
...mapActions('taxonomy', [ ...mapActions('taxonomy', [
'fetchTerms' 'fetchTerms'
]), ]),
...mapGetters('taxonomy', [
'getTerms'
]),
loadTerms: _.debounce( function(value) { loadTerms: _.debounce( function(value) {
// String update // String update

View File

@ -435,9 +435,11 @@ class Taxonomy extends Metadata_Type {
$array = parent::_toArray(); $array = parent::_toArray();
if ( isset($array['options']['taxonomy_id']) ) { if ( isset($array['options']['taxonomy_id']) ) {
$array['options']['taxonomy'] = \Tainacan\Repositories\Taxonomies::get_instance()->get_db_identifier_by_id( $array['options']['taxonomy_id'] ); $term_taxonomy = $this->get_taxonomy();
}
$array['options']['taxonomy'] = \Tainacan\Repositories\Taxonomies::get_instance()->get_db_identifier_by_id( $array['options']['taxonomy_id'] );
$array['options']['hierarchical'] = $term_taxonomy->get_hierarchical();
}
return $array; return $array;
} }

View File

@ -59,17 +59,18 @@ import { mapActions } from 'vuex';
export default { export default {
name: 'CollectionsModal', name: 'CollectionsModal',
data(){ data() {
return { return {
collections: [], collections: [],
isLoading: false isLoading: false,
maxCollectionsPerPage: tainacan_plugin.api_max_items_per_page ? Number(tainacan_plugin.api_max_items_per_page) : 96
} }
}, },
mounted() { mounted() {
this.isLoading = true; this.isLoading = true;
this.fetchCollections({ this.fetchCollections({
page: 1, page: 1,
collectionsPerPage: 96, collectionsPerPage: this.maxCollectionsPerPage,
contextEdit: true contextEdit: true
}) })
.then((res) => { .then((res) => {

View File

@ -77,6 +77,19 @@
<span class="is-hidden-mobile">{{ $i18n.get('label_view_collection_on_website') }}</span> <span class="is-hidden-mobile">{{ $i18n.get('label_view_collection_on_website') }}</span>
</a> </a>
</li> </li>
<li>
<a
:href="repositoryTaxonomiesURL"
target="_blank"
v-if="isRepositoryLevel && !$adminOptions.hideRepositorySubheaderViewTaxonomiesButton"
class="button"
id="view-repository-button--taxonomies">
<span class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-see"/>
</span>
<span class="is-hidden-mobile">{{ $i18n.get('label_view_taxonomies_on_website') }}</span>
</a>
</li>
<li> <li>
<a <a
:href="repositoryURL" :href="repositoryURL"
@ -109,6 +122,7 @@ export default {
return { return {
repositoryName: tainacan_plugin.repository_name, repositoryName: tainacan_plugin.repository_name,
repositoryURL: tainacan_plugin.theme_collection_list_url, repositoryURL: tainacan_plugin.theme_collection_list_url,
repositoryTaxonomiesURL: tainacan_plugin.theme_taxonomy_list_url,
collectionId: '' collectionId: ''
} }
}, },
@ -255,7 +269,8 @@ export default {
background-color: var(--tainacan-turquoise5) !important; background-color: var(--tainacan-turquoise5) !important;
} }
} }
#view-repository-button { #view-repository-button,
#view-repository-button--taxonomies {
font-size: 0.9375em !important; font-size: 0.9375em !important;
border: none; border: none;
border-radius: 0px !important; border-radius: 0px !important;

View File

@ -95,7 +95,7 @@
<template v-if="!isLoadingSearch && allowNew && !searchResults.length"> <template v-if="!isLoadingSearch && allowNew && !searchResults.length">
<li class="tainacan-li-checkbox-list result-info"> <li class="tainacan-li-checkbox-list result-info">
<a @click="$emit('showAddNewTerm', { name: optionName })"> <a @click="$emit('showAddNewTerm', { name: optionName })">
{{ $i18n.get('label_new_term') + ' "' + optionName + '"' }} {{ $i18n.get('label_create_new_term') + ' "' + optionName + '"' }}
</a> </a>
</li> </li>
</template> </template>

View File

@ -0,0 +1,130 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal
autofocus
role="alertdialog"
class="tainacan-form tainacan-dialog dialog"
ref="termDeletionDialog">
<div
class="modal-card"
style="width: auto">
<div class="modal-custom-icon">
<span class="icon is-large">
<i
style="color: var(--tainacan-red2);"
class="tainacan-icon tainacan-icon-alert"/>
</span>
</div>
<section
tabindex="1"
class="modal-card-body">
<header
class="modal-card-head">
<h1
id="alert-dialog-title"
class="modal-card-title">
{{ $i18n.get('label_warning') }}
</h1>
</header>
<span v-html="message" />
<div
v-if="showDescendantsDeleteButton"
class="type-of-deletion-options">
<b-radio
native-value="selected"
v-model="typeOfDelete">
{{ amountOfTerms > 1 ? $i18n.get('label_remove_selected_terms') : $i18n.get('label_remove_selected_term') }}
</b-radio>
<b-radio
native-value="descendants"
v-model="typeOfDelete">
{{ amountOfTerms > 1 ? $i18n.get('label_remove_terms_and_descendants') : $i18n.get('label_remove_term_and_descendants') }}
</b-radio>
</div>
</section>
<footer class="modal-card-foot form-submit">
<button
v-if="!hideCancel"
class="button is-outlined"
type="button"
@click="$parent.close()">
{{ $i18n.get('cancel') }}
</button>
<button
type="submit"
class="button is-success"
@click="onConfirm(typeOfDelete); $parent.close();">
{{ $i18n.get('continue') }}
</button>
</footer>
</div>
</div>
</template>
<script>
export default {
name: 'TermDeletionDialog',
props: {
title: String,
message: String,
showDescendantsDeleteButton: {
type: Boolean,
default: false
},
onConfirm: {
type: Function,
default: () => {}
},
hideCancel: {
type: Boolean,
default: false,
},
amountOfTerms: {
type: Number,
default: 1
},
},
data() {
return {
typeOfDelete: 'selected'
}
},
mounted() {
if (this.$refs.termDeletionDialog)
this.$refs.termDeletionDialog.focus();
}
}
</script>
<style scoped>
i.tainacan-icon,
i.tainacan-icon::before {
font-size: 56px;
}
button.is-success {
margin-left: auto;
}
.b-checkbox.checkbox {
margin-top: 12px;
width: auto !important;
}
.type-of-deletion-options {
margin-top: 0.5rem;
font-size: 1.25em;
max-width: 97%;
}
@media screen and (max-width: 768px) {
.modal-custom-icon {
display: none !important;
}
}
</style>

View File

@ -0,0 +1,299 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal
autofocus
role="alertdialog"
class="tainacan-form tainacan-dialog dialog"
ref="termMultipleInsertionDialog">
<div
class="modal-card"
style="width: auto">
<div class="modal-custom-icon">
<span class="icon is-large">
<i
style="color: var(--tainacan-blue5);"
class="tainacan-icon tainacan-icon-taxonomies"/>
</span>
</div>
<section
tabindex="1"
class="modal-card-body">
<header
class="modal-card-head">
<h1
id="alert-dialog-title"
class="modal-card-title">
{{ $i18n.get('label_multiple_terms_insertion') }}
</h1>
</header>
<b-field :addons="false">
<label
class="label"
style="font-size: 1em;">
{{ $i18n.get('instruction_multiple_terms_insertion') }}
</label>
<b-taginput
v-model="termNames"
attached
:confirm-keys="termNamesSeparator"
:on-paste-separators="termNamesSeparator"
:remove-on-keys="[]"
:aria-close-label="$i18n.get('remove_value')"
class="tainacan-multiple-term-insertion--taginput"
:class="{'has-selected': termNames != undefined && termNames != []}"
:placeholder="$i18n.get('term') + '1,' + $i18n.get('term') + '2,' + $i18n.get('term') + '3 ...'" />
<div class="separator-term-names">
<label class="label is-inline">{{ $i18n.get('label_separator') }}:</label>
<b-checkbox
v-for="separator of ['Enter', ',', ';', '|']"
:key="separator"
name="term-multiple-insertion-separator"
v-model="termNamesSeparator"
:native-value="separator"
:disabled="separator == 'Enter'">
<kbd>{{ separator }}</kbd>
</b-checkbox>
</div>
</b-field>
<!-- Parent -------------- -->
<div
v-if="isHierarchical"
class="parent-term-options">
<b-radio
:native-value="false"
v-model="hasParent">
{{ $i18n.get('label_no_parent_root_term') }}
</b-radio>
<b-radio
:native-value="true"
v-model="hasParent">
{{ $i18n.get('instruction_select_a_parent_term') }}
</b-radio>
<b-autocomplete
v-if="hasParent"
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"
check-infinite-scroll
:append-to-body="true"
@infinite-scroll="fetchMoreParentTerms">
<template slot-scope="props">
<div class="media">
<div
v-if="props.option.header_image_id"
class="media-left">
<img
width="28"
:src="props.option.thumbnail && props.option.thumbnail['thumbnail'] && props.option.thumbnail['thumbnail'][0] ? props.option.thumbnail['thumbnail'][0] : 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>
</div>
</section>
<footer class="modal-card-foot form-submit">
<button
v-if="!hideCancel"
class="button is-outlined"
type="button"
@click="$parent.close()">
{{ $i18n.get('cancel') }}
</button>
<button
type="submit"
class="button is-success"
:disabled="hasParent ? !selectedParentTerm : false"
@click="onConfirm({ parent: hasParent ? selectedParentTerm : 0, termNames: termNames }); $parent.close();">
{{ $i18n.get('continue') }}
</button>
</footer>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'TermMultipleInsertionDialog',
props: {
title: String,
onConfirm: {
type: Function,
default: () => {}
},
taxonomyId: '',
excludeTree: '',
isHierarchical: Boolean,
initialTermParent: String,
initialTermParentName: String
},
data() {
return {
hasParent: false,
termNames: [],
termNamesSeparator: [",", "Enter"],
parentTerms: [],
isFetchingParentTerms: false,
parentTermSearchQuery: '',
parentTermSearchOffset: 0,
selectedParentTerm: undefined,
parentTermName: '',
totalTerms: undefined
}
},
created() {
if ( this.initialTermParent && this.initialTermParentName ) {
this.parentTermName = this.initialTermParentName;
this.selectedParentTerm = this.initialTermParent;
this.hasParent = true;
}
},
mounted() {
if (this.$refs.termMultipleInsertionDialog)
this.$refs.termMultipleInsertionDialog.focus();
},
methods: {
...mapActions('taxonomy', [
'fetchPossibleParentTerms'
]),
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.totalTerms !== undefined && this.parentTerms.length >= this.totalTerms)
return
this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({
taxonomyId: this.taxonomyId,
termId: this.excludeTree,
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),
onSelectParentTerm(selectedParentTerm) {
if ( selectedParentTerm ) {
this.selectedParentTerm = selectedParentTerm.id;
this.parentTermName = selectedParentTerm.name;
} else {
this.selectedParentTerm = undefined;
this.parentTermName = '';
}
}
}
}
</script>
<style scoped>
.dialog .modal-card {
max-width: 980px;
}
i.tainacan-icon,
i.tainacan-icon::before {
font-size: 40px;
}
button.is-success {
margin-left: auto;
}
.b-checkbox.checkbox {
margin-top: 8px;
width: auto !important;
}
.parent-term-options {
margin-top: 0.5rem;
max-width: 97%;
}
.parent-term-options .b-radio {
font-size: 1.125em;
}
.separator-term-names {
display: flex;
flex-wrap: wrap;
padding: 4px 10px;
background: #f9f9f9;
border: 1px solid var(--tainacan-gray1, #f2f2f2);
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
font-size: 1.25em;
}
.separator-term-names .b-checkbox {
width: auto;
margin-right: 0.75em;
}
.separator-term-names > label {
opacity: 0.875;
font-size: 0.75em;
margin-right: 1em;
display: block;
margin-bottom: 0;
}
.separator-term-names > label.is-inline {
margin-top: 2px;
}
.tainacan-multiple-term-insertion--taginput /deep/ .tag,
.tainacan-multiple-term-insertion--taginput /deep/ .tags {
white-space: normal !important;
min-height: calc(2em - 1px) !important;
height: auto !important;
}
.tainacan-multiple-term-insertion--taginput /deep/ .tag.is-delete {
min-width: calc(2em - 1px) !important;
}
@media screen and (max-width: 768px) {
.modal-custom-icon {
display: none !important;
}
}
</style>

View File

@ -0,0 +1,221 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal
autofocus
role="alertdialog"
class="tainacan-form tainacan-dialog dialog"
ref="termParentSelectionDialog">
<div
class="modal-card"
style="width: auto">
<div class="modal-custom-icon">
<span class="icon is-large">
<i
style="color: var(--tainacan-blue5);"
class="tainacan-icon tainacan-icon-taxonomies"/>
</span>
</div>
<section
tabindex="1"
class="modal-card-body">
<header
class="modal-card-head">
<h1
id="alert-dialog-title"
class="modal-card-title">
{{ $i18n.get('label_update_parent') }}
</h1>
</header>
<!-- Parent -------------- -->
<div class="parent-term-options">
<b-radio
:native-value="false"
v-model="hasParent">
{{ $i18n.get('label_no_parent_root_term') }}
</b-radio>
<b-radio
:native-value="true"
v-model="hasParent">
{{ $i18n.get('instruction_select_a_parent_term') }}
</b-radio>
<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"
:disabled="!hasParent"
check-infinite-scroll
:append-to-body="true"
@infinite-scroll="fetchMoreParentTerms">
<template slot-scope="props">
<div class="media">
<div
v-if="props.option.header_image_id"
class="media-left">
<img
width="28"
:src="props.option.thumbnail && props.option.thumbnail['thumbnail'] && props.option.thumbnail['thumbnail'][0] ? props.option.thumbnail['thumbnail'][0] : 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>
</div>
</section>
<footer class="modal-card-foot form-submit">
<button
v-if="!hideCancel"
class="button is-outlined"
type="button"
@click="$parent.close()">
{{ $i18n.get('cancel') }}
</button>
<button
type="submit"
class="button is-success"
:disabled="hasParent ? !selectedParentTerm : false"
@click="onConfirm(hasParent ? selectedParentTerm : 0); $parent.close();">
{{ $i18n.get('continue') }}
</button>
</footer>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'TermParentSelectionDialog',
props: {
title: String,
onConfirm: {
type: Function,
default: () => {}
},
amountOfTerms: {
type: Number,
default: 1
},
taxonomyId: '',
excludeTree: ''
},
data() {
return {
hasParent: false,
parentTerms: [],
isFetchingParentTerms: false,
parentTermSearchQuery: '',
parentTermSearchOffset: 0,
selectedParentTerm: undefined,
parentTermName: '',
totalTerms: undefined
}
},
mounted() {
if (this.$refs.termParentSelectionDialog)
this.$refs.termParentSelectionDialog.focus();
},
methods: {
...mapActions('taxonomy', [
'fetchPossibleParentTerms'
]),
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.totalTerms !== undefined && this.parentTerms.length >= this.totalTerms)
return
this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({
taxonomyId: this.taxonomyId,
termId: this.excludeTree,
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),
onSelectParentTerm(selectedParentTerm) {
if ( selectedParentTerm ) {
this.selectedParentTerm = selectedParentTerm.id;
this.parentTermName = selectedParentTerm.name;
} else {
this.selectedParentTerm = undefined;
this.parentTermName = '';
}
}
}
}
</script>
<style scoped>
i.tainacan-icon,
i.tainacan-icon::before {
font-size: 40px;
}
button.is-success {
margin-left: auto;
}
.b-checkbox.checkbox {
margin-top: 12px;
width: auto !important;
}
.parent-term-options {
margin-top: 0.5rem;
max-width: 97%;
}
.parent-term-options .b-radio {
font-size: 1.125em;
}
@media screen and (max-width: 768px) {
.modal-custom-icon {
display: none !important;
}
}
</style>

View File

@ -116,7 +116,7 @@ export default {
}, },
data() { data() {
return { return {
maxItemsPerPage: tainacan_plugin.api_max_items_per_page maxItemsPerPage: tainacan_plugin.api_max_items_per_page ? Number(tainacan_plugin.api_max_items_per_page) : 96
} }
}, },
computed: { computed: {
@ -133,7 +133,7 @@ export default {
return Math.ceil(Number(this.totalItems)/Number(this.itemsPerPage)); return Math.ceil(Number(this.totalItems)/Number(this.itemsPerPage));
}, },
itemsPerPageOptions() { itemsPerPageOptions() {
const defaultItemsPerPageOptions = [12, 24, 48, 96]; const defaultItemsPerPageOptions = [12, 24, 48, this.maxItemsPerPage];
if (!isNaN(this.itemsPerPage) && !defaultItemsPerPageOptions.includes(this.itemsPerPage)) if (!isNaN(this.itemsPerPage) && !defaultItemsPerPageOptions.includes(this.itemsPerPage))
defaultItemsPerPageOptions.push(this.itemsPerPage); defaultItemsPerPageOptions.push(this.itemsPerPage);

View File

@ -58,9 +58,6 @@ import FormGeoCoordinate from '../components/metadata-types/geocoordinate/FormGe
// Term edition form must be imported here so that it is not necessary on item-submission bundle // Term edition form must be imported here so that it is not necessary on item-submission bundle
import TermEditionForm from '../components/edition/term-edition-form.vue'; import TermEditionForm from '../components/edition/term-edition-form.vue';
// Term Recursive item component needs to be imported here, otherwise would cause ciruclar dependency
import RecursiveTermItem from '../components/lists/recursive-term-item.vue';
import FormFilterNumeric from '../components/filter-types/numeric/FormNumeric.vue'; import FormFilterNumeric from '../components/filter-types/numeric/FormNumeric.vue';
import FormFilterNumericInterval from '../components/filter-types/numeric-interval/FormNumericInterval.vue'; import FormFilterNumericInterval from '../components/filter-types/numeric-interval/FormNumericInterval.vue';
import FormFilterNumericListInterval from '../components/filter-types/numeric-list-interval/FormNumericListInterval.vue'; import FormFilterNumericListInterval from '../components/filter-types/numeric-list-interval/FormNumericListInterval.vue';
@ -72,10 +69,9 @@ import TainacanFormItem from '../components/metadata-types/tainacan-form-item.vu
import AdminPage from '../admin.vue' import AdminPage from '../admin.vue'
import HelpButton from '../components/other/help-button.vue'; import HelpButton from '../components/other/help-button.vue';
import TainacanTitle from '../components/navigation/tainacan-title.vue'; import TainacanTitle from '../components/navigation/tainacan-title.vue';
import store from './store/store' import store from './store/store';
import router from './router' import router from './router';
import eventBusSearch from './event-bus-search'; import eventBusSearch from './event-bus-search';
import eventBusTermsList from './event-bus-terms-list.js';
import eventBusMetadataList from './event-bus-metadata-list.js'; import eventBusMetadataList from './event-bus-metadata-list.js';
import { import {
I18NPlugin, I18NPlugin,
@ -224,13 +220,11 @@ export default (element) => {
Vue.component('tainacan-form-item', TainacanFormItem); Vue.component('tainacan-form-item', TainacanFormItem);
/* Others */ /* Others */
Vue.component('recursive-term-item', RecursiveTermItem);
Vue.component('help-button', HelpButton); Vue.component('help-button', HelpButton);
Vue.component('draggable', draggable); Vue.component('draggable', draggable);
Vue.component('tainacan-title', TainacanTitle); Vue.component('tainacan-title', TainacanTitle);
// Event bus are needed to facilate comunication between child-parent-child components // Event bus are needed to facilate comunication between child-parent-child components
Vue.use(eventBusTermsList, {});
Vue.use(eventBusMetadataList, {}); Vue.use(eventBusMetadataList, {});
Vue.use(eventBusSearch, { store: store, router: router}); Vue.use(eventBusSearch, { store: store, router: router});

View File

@ -1,28 +0,0 @@
export default {
install(Vue, options = {}) {
Vue.prototype.$eventBusTermsList = new Vue({
data: {
},
methods: {
onEditTerm(term) {
this.$emit('editTerm', term);
},
onTermEditionSaved({term, hasChangedParent}) {
this.$emit('termEditionSaved', { term: term, hasChangedParent: hasChangedParent });
},
onTermEditionCanceled(term) {
this.$emit('termEditionCanceled', term);
},
onAddNewChildTerm(parentId) {
this.$emit('addNewChildTerm', parentId);
},
onDeleteBasicTermItem(term) {
this.$emit('deleteBasicTermItem', term);
}
}
});
}
}

View File

@ -82,8 +82,12 @@ export const updateCollectionMetadataOrder = (state, { metadataOrder, metadataSe
const existingSectionIndex = state.metadataSections.findIndex((aMetadataSection) => aMetadataSection.id == metadataSectionId); const existingSectionIndex = state.metadataSections.findIndex((aMetadataSection) => aMetadataSection.id == metadataSectionId);
if (existingSectionIndex >= 0) { if (existingSectionIndex >= 0) {
const updatedMetadatumIndexInsideSection = state.metadataSections[existingSectionIndex]['metadata_object_list'].findIndex((aMetadatum) => { return !!aMetadatum['id'] && (aMetadatum.id == metadataOrder[i]['id']) }); const updatedMetadatumIndexInsideSection = state.metadataSections[existingSectionIndex]['metadata_object_list'].findIndex((aMetadatum) => { return !!aMetadatum['id'] && (aMetadatum.id == metadataOrder[i]['id']) });
if (updatedMetadatumIndexInsideSection >= 0) if (updatedMetadatumIndexInsideSection >= 0) {
state.metadataSections[existingSectionIndex]['metadata_object_list'][updatedMetadatumIndexInsideSection].enabled = metadataOrder[i].enabled;
let metadataObjectList = state.metadataSections[existingSectionIndex]['metadata_object_list'];
metadataObjectList[updatedMetadatumIndexInsideSection].enabled = metadataOrder[i].enabled;
Vue.set(state.metadataSections[existingSectionIndex], 'metadata_object_list', metadataObjectList);
}
} }
} }
} }

View File

@ -123,77 +123,21 @@ export const fetchTaxonomyName = ({ commit }, taxonomyId) => {
}; };
// TAXONOMY TERMS // TAXONOMY TERMS
export const sendTerm = ({commit}, { taxonomyId, name, description, parent, headerImageId, headerImage }) => { export const fetchTerms = ({}, {taxonomyId, fetchOnly, search, all, order, offset, number, exclude }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('/taxonomy/' + taxonomyId + '/terms/', {
name: name,
description: description,
parent: parent,
header_image_id: headerImageId,
header_image: headerImage
})
.then( res => {
let term = res.data;
commit('setSingleTerm', term);
resolve( term );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
});
});
};
export const deleteTerm = ({ commit }, { taxonomyId, termId }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.delete(`/taxonomy/${taxonomyId}/terms/${termId}?permanently=1`)
.then(res => {
let term = res.data;
commit('deleteTerm', termId);
resolve( term );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
});
});
};
export const updateTerm = ({ commit }, { taxonomyId, id, name, description, parent, headerImageId, headerImage }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/${id}`, {
name: name,
description: description,
parent: parent,
header_image_id: headerImageId,
header_image: headerImage,
})
.then( res => {
let term = res.data;
commit('setSingleTerm', term);
resolve( term );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
});
});
};
export const fetchTerms = ({ commit }, {taxonomyId, fetchOnly, search, all, order, offset, number, exclude }) => {
let query = ''; let query = '';
if (order == undefined) if (order == undefined)
order = 'asc'; order = 'asc';
if(fetchOnly && search && !all ){ if (fetchOnly && search && !all )
query = `?order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`; query = `?order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`;
} else if(fetchOnly && search && all ){ else if (fetchOnly && search && all )
query = `?hideempty=0&order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`; query = `?hideempty=0&order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`;
} else if(search && !all && !fetchOnly){ else if (search && !all && !fetchOnly)
query = `?hideempty=0&order=${order}&${qs.stringify(search)}`; query = `?hideempty=0&order=${order}&${qs.stringify(search)}`;
} else { else
query =`?hideempty=0&order=${order}`; query =`?hideempty=0&order=${order}`;
}
if (number != undefined) if (number != undefined)
query += '&number=' + number; query += '&number=' + number;
@ -207,9 +151,7 @@ export const fetchTerms = ({ commit }, {taxonomyId, fetchOnly, search, all, orde
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.tainacan.get(`/taxonomy/${taxonomyId}/terms${query}`) axios.tainacan.get(`/taxonomy/${taxonomyId}/terms${query}`)
.then(res => { .then(res => {
let terms = res.data; resolve({ terms: res.data, total: res.headers['x-wp-total'] });
commit('setTerms', terms);
resolve({ terms: terms, total: res.headers['x-wp-total'] });
}) })
.catch(error => { .catch(error => {
reject( error ); reject( error );
@ -217,48 +159,11 @@ export const fetchTerms = ({ commit }, {taxonomyId, fetchOnly, search, all, orde
}); });
}; };
// Hierarchy usage of terms list -----------------
export const fetchChildTerms = ({ commit }, { parentId, taxonomyId, fetchOnly, search, all, order, offset, number }) => {
let query = '';
if (order == undefined) {
order = 'asc';
}
if(fetchOnly && search && !all ){
query = `?order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`;
} else if(fetchOnly && search && all ){
query = `?hideempty=0&order=${order}&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`;
} else if(search && !all && !fetchOnly){
query = `?hideempty=0&order=${order}&${qs.stringify(search)}`;
} else {
query =`?hideempty=0&order=${order}`;
}
query += '&parent=' + parentId;
if (offset != undefined && number != undefined)
query += '&offset=' + offset + '&number=' + number;
return new Promise((resolve, reject) => {
axios.tainacan.get(`/taxonomy/${taxonomyId}/terms${query}`)
.then(res => {
let terms = res.data;
commit('setChildTerms', { terms: terms, parent: parentId });
resolve({ terms: terms, total: res.headers['x-wp-total'] });
})
.catch(error => {
reject(error);
});
});
};
export const sendChildTerm = ({ commit }, { taxonomyId, term }) => { export const sendChildTerm = ({ commit }, { taxonomyId, term }) => {
return new Promise(( resolve, reject ) => { return new Promise(( resolve, reject ) => {
axios.tainacan.post(`/taxonomy/${taxonomyId}/terms/`, term) axios.tainacan.post(`/taxonomy/${taxonomyId}/terms/`, term)
.then( res => { .then( res => {
let newTerm = res.data; const newTerm = res.data;
commit('addChildTerm', {term: newTerm, parent: term.parent });
resolve( newTerm ); resolve( newTerm );
}) })
.catch(error => { .catch(error => {
@ -267,13 +172,12 @@ export const sendChildTerm = ({ commit }, { taxonomyId, term }) => {
}); });
}; };
export const updateChildTerm = ({ commit }, { taxonomyId, term }) => { export const updateTerm = ({}, { taxonomyId, term }) => {
return new Promise(( resolve, reject ) => { return new Promise(( resolve, reject ) => {
axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/${term.id}`, term) axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/${term.id}`, term)
.then( res => { .then( res => {
let updatedTerm = res.data; const updatedTerm = res.data;
commit('updateChildTerm', { term: updatedTerm, parent: updatedTerm.parent, oldParent: term.parent }); resolve( updatedTerm );
resolve( term );
}) })
.catch(error => { .catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors }); reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
@ -281,17 +185,16 @@ export const updateChildTerm = ({ commit }, { taxonomyId, term }) => {
}); });
}; };
// Used to update parent changes after deletion only locally export const deleteTerm = ({}, { taxonomyId, termId, deleteChildTerms = false }) => {
export const updateChildTermLocal = ({ commit }, { term, parent, oldParent }) => { let query = 'permanently=1&hideempty=0';
commit('updateChildTerm', { term: term, parent: parent, oldParent: oldParent });
}; if ( deleteChildTerms )
query += `&delete_child_terms=${deleteChildTerms}`;
export const deleteChildTerm = ({ commit }, { taxonomyId, termId, parent }) => {
return new Promise(( resolve, reject ) => { return new Promise(( resolve, reject ) => {
axios.tainacan.delete(`/taxonomy/${taxonomyId}/terms/${termId}?permanently=1`) axios.tainacan.delete(`/taxonomy/${taxonomyId}/terms/${termId}?${query}`)
.then(res => { .then(res => {
let term = res.data; const term = res.data;
commit('deleteChildTerm', { termId: termId, parent: parent });
resolve( term ); resolve( term );
}) })
.catch(error => { .catch(error => {
@ -300,15 +203,57 @@ export const deleteChildTerm = ({ commit }, { taxonomyId, termId, parent }) => {
}); });
}; };
export const deleteTerms = ({}, { taxonomyId, terms, parent, deleteChildTerms = false }) => {
let query = `permanently=1&hideempty=0&number=0`;
export const clearTerms = ({ commit }) => { if ( parent !== undefined )
commit('clearTerms'); query += `&parent=${parent}`;
if ( terms.length )
query += `&include=${terms}`;
if ( deleteChildTerms )
query += `&delete_child_terms=${deleteChildTerms}`;
return new Promise(( resolve, reject ) => {
axios.tainacan.delete(`/taxonomy/${taxonomyId}/terms/?${query}`)
.then(res => {
const terms = res.data;
resolve( terms );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
});
});
};
export const changeTermsParent = ({}, { taxonomyId, newParentTerm, terms, parent }) => {
let query = `hideempty=0&number=0`;
if ( parent !== undefined )
query += `&parent=${parent}`;
if ( terms.length )
query += `&include=${terms}`;
return new Promise(( resolve, reject ) => {
axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/newparent/${newParentTerm}?${query}`)
.then(res => {
const terms = res.data;
resolve( terms );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
});
});
}; };
// Used only on Term Edit form, for autocomplete search for parents // Used only on Term Edit form, for autocomplete search for parents
export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, search, offset } ) => { export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, search, offset } ) => {
let endpoint = '/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&exclude_tree=' + termId + "&hideempty=0&offset=0&number=20&order=asc"; const excludeTree = termId ? qs.stringify({ exclude_tree: termId }) : '';
let endpoint = '/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&hideempty=0&offset=0&number=20&order=asc&' + excludeTree;
if (offset) if (offset)
endpoint += '&offset=' + offset; endpoint += '&offset=' + offset;
@ -331,6 +276,7 @@ export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, searc
}); });
}); });
}; };
export const fetchParentName = ({ commit }, { taxonomyId, parentId } ) => { export const fetchParentName = ({ commit }, { taxonomyId, parentId } ) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms/' + parentId + '?fetch_only=name') axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms/' + parentId + '?fetch_only=name')
@ -343,3 +289,22 @@ export const fetchParentName = ({ commit }, { taxonomyId, parentId } ) => {
}); });
}); });
}; };
export const multipleTermsInsertion = ({}, { taxonomyId, parent, termNames } ) => {
const terms = termNames.map(aTermName => {
return {
parent: parent,
name: aTermName
}
});
return new Promise((resolve, reject) => {
axios.tainacan.post('/taxonomy/' + taxonomyId + '/terms/bulkinsert', terms )
.then(res => {
resolve( res.data );
})
.catch(error => {
reject(error['response']['data']);
});
});
};

View File

@ -10,10 +10,6 @@ export const getTaxonomyName = state => {
return state.taxonomyName; return state.taxonomyName;
}; };
export const getTerms = state => {
return state.terms;
};
export const getRepositoryTotalTaxonomies = state => { export const getRepositoryTotalTaxonomies = state => {
return state.repositoryTotalTaxonomies; return state.repositoryTotalTaxonomies;
}; };

View File

@ -1,6 +1,3 @@
import Vue from 'vue';
import t from 't';
export const setRepositoryTotalTaxonomies = (state, repositoryTotalTaxonomies) => { export const setRepositoryTotalTaxonomies = (state, repositoryTotalTaxonomies) => {
state.repositoryTotalTaxonomies = repositoryTotalTaxonomies; state.repositoryTotalTaxonomies = repositoryTotalTaxonomies;
}; };
@ -24,152 +21,4 @@ export const deleteTaxonomy = ( state, taxonomy ) => {
if (index >= 0) { if (index >= 0) {
state.taxonomies.splice(index, 1); state.taxonomies.splice(index, 1);
} }
};
// TAXONOMY TERMS
export const setSingleTerm = (state, term) => {
let index = state.terms.findIndex(updatedTerm => updatedTerm.id === term.id);
if ( index >= 0){
Vue.set( state.terms, index, term );
} else {
state.terms.push( term );
}
};
export const setTerms = (state, terms) => {
for (let term of terms) {
let existingTermIndex = state.terms.findIndex(aTerm => aTerm.id == term.id);
if (existingTermIndex >= 0)
Vue.set(state.terms, existingTermIndex, term);
else
state.terms.push(term);
}
};
export const clearTerms = (state) => {
state.terms = [];
};
// Hierarchy usage of terms list -----------------
export const setChildTerms = (state, { terms, parent }) => {
if (parent > 0 ) {
for (let i = 0; i < state.terms.length; i++) {
let parentTerm = t.find(state.terms[i], [], (node, par) => { return node.id == parent; });
if (parentTerm != undefined) {
if (parentTerm['children'] == undefined)
Vue.set(parentTerm, 'children', []);
for (let term of terms){
let existingTermIndex = parentTerm['children'].findIndex(aTerm => aTerm.id == term.id);
if (existingTermIndex < 0)
parentTerm['children'].push(term);
else
Vue.set(parentTerm['children'], existingTermIndex, term);
}
}
}
} else {
if (state.terms != undefined) {
for (let term of terms) {
let existingTermIndex = state.terms.findIndex(aTerm => aTerm.id == term.id);
if (existingTermIndex < 0)
state.terms.push(term);
else
Vue.set(state.terms, existingTermIndex, term);
}
} else {
state.terms = terms;
}
}
};
export const addChildTerm = (state, { term, parent }) => {
if (parent > 0 ) {
for (let aTerm of state.terms) {
let parentTerm = t.find(aTerm, [], (node, par) => { return node.id == parent; });
if (parentTerm != undefined) {
if (parentTerm['children'] == undefined) {
Vue.set(parentTerm, 'children', []);
}
parentTerm['children'].unshift(term);
parentTerm.total_children = parentTerm.children.length;
}
}
} else {
if (state.terms != undefined) {
let existingTermIndex = state.terms.findIndex(aTerm => aTerm.id == term.id);
if (existingTermIndex >= 0)
Vue.set(state.terms, existingTermIndex, term);
else
state.terms.unshift(term);
} else {
state.terms = []
state.terms.unshift(term);
}
}
};
export const updateChildTerm = (state, { term, parent, oldParent }) => {
if (oldParent == undefined) {
if (parent > 0 ) {
for (let aTerm of state.terms) {
let childTerm = t.find(aTerm, [], (node, par) => { return node.id == term.id; });
if (childTerm != undefined) {
childTerm = term;
}
}
} else {
if (state.terms != undefined) {
for (let i = 0; i < state.terms.length; i++) {
if (state.terms[i].id == term.id)
Vue.set(state.terms, i, term);
}
} else {
state.terms = []
state.terms.push(term);
}
}
} else {
// Removes from old parent
deleteChildTerm(term.id, oldParent)
// Adds it to new one
addChildTerm(term, parent);
}
};
export const deleteChildTerm = ( state, {termId, parent} ) => {
if (parent > 0 ) {
for (let i = 0; i < state.terms.length; i++) {
let parentTerm = t.find(state.terms[i], [], (node, par) => { return node.id == parent; });
if (parentTerm != undefined) {
let index = parentTerm.children.findIndex(deletedTerm => deletedTerm.id == termId);
if (index >= 0) {
parentTerm.children.splice(index, 1);
parentTerm.total_children = parentTerm.children.length;
}
}
}
} else {
if (state.terms != undefined) {
for (let i = 0; i < state.terms.length; i++) {
if (state.terms[i].id == termId)
state.terms.splice(i, 1);
}
}
}
};
export const deleteTerm = ( state, termId ) => {
let index = state.terms.findIndex(deletedTerm => deletedTerm.id === termId);
if (index >= 0) {
state.terms.splice(index, 1);
}
}; };

View File

@ -271,7 +271,7 @@
<option value="12">12</option> <option value="12">12</option>
<option value="24">24</option> <option value="24">24</option>
<option value="48">48</option> <option value="48">48</option>
<option value="96">96</option> <option :value="maxActivitiesPerPage">{{ maxActivitiesPerPage }}</option>
</b-select> </b-select>
</b-field> </b-field>
</div> </div>
@ -312,7 +312,7 @@
<option value="12">12</option> <option value="12">12</option>
<option value="24">24</option> <option value="24">24</option>
<option value="48">48</option> <option value="48">48</option>
<option value="96">96</option> <option :value="maxActivitiesPerPage">{{ maxActivitiesPerPage }}</option>
</b-select> </b-select>
</b-field> </b-field>
</div> </div>
@ -367,7 +367,8 @@
userIdForFiltering: null, userIdForFiltering: null,
usersForFilteringSearchQuery: '', usersForFilteringSearchQuery: '',
usersForFilteringSearchPage: 1, usersForFilteringSearchPage: 1,
totalUsers: 0 totalUsers: 0,
maxActivitiesPerPage: tainacan_plugin.api_max_items_per_page ? Number(tainacan_plugin.api_max_items_per_page) : 96
} }
}, },
computed: { computed: {

View File

@ -333,7 +333,7 @@
<option value="12">12</option> <option value="12">12</option>
<option value="24">24</option> <option value="24">24</option>
<option value="48">48</option> <option value="48">48</option>
<option value="96">96</option> <option :value="maxCollectionsPerPage">{{ maxCollectionsPerPage }}</option>
</b-select> </b-select>
</b-field> </b-field>
</div> </div>
@ -377,13 +377,14 @@ export default {
isLoadingCollectionTaxonomies: false, isLoadingCollectionTaxonomies: false,
status: '', status: '',
order: 'desc', order: 'desc',
ordeBy: 'date', orderBy: 'date',
searchQuery: '', searchQuery: '',
sortingOptions: [ sortingOptions: [
{ label: this.$i18n.get('label_title'), value: 'title' }, { label: this.$i18n.get('label_title'), value: 'title' },
{ label: this.$i18n.get('label_creation_date'), value: 'date' }, { label: this.$i18n.get('label_creation_date'), value: 'date' },
{ label: this.$i18n.get('label_modification_date'), value: 'modified' } { label: this.$i18n.get('label_modification_date'), value: 'modified' }
] ],
maxCollectionsPerPage: tainacan_plugin.api_max_items_per_page ? Number(tainacan_plugin.api_max_items_per_page) : 96
} }
}, },
computed: { computed: {

View File

@ -125,7 +125,7 @@
</a> </a>
</li> </li>
<li <li
v-for="(statusOption, index) of $statusHelper.getStatuses()" v-for="(statusOption, index) of $statusHelper.getStatuses().filter((status) => status.slug != 'draft')"
:key="index" :key="index"
v-if="statusOption.slug != 'private' || (statusOption.slug == 'private' && $userCaps.hasCapability('tnc_rep_read_private_taxonomies'))" v-if="statusOption.slug != 'private' || (statusOption.slug == 'private' && $userCaps.hasCapability('tnc_rep_read_private_taxonomies'))"
@click="onChangeTab(statusOption.slug)" @click="onChangeTab(statusOption.slug)"
@ -212,7 +212,7 @@
<option value="12">12</option> <option value="12">12</option>
<option value="24">24</option> <option value="24">24</option>
<option value="48">48</option> <option value="48">48</option>
<option value="96">96</option> <option :value="maxTaxonomiesPerPage">{{ maxTaxonomiesPerPage }}</option>
</b-select> </b-select>
</b-field> </b-field>
</div> </div>
@ -254,12 +254,13 @@
taxonomiesPerPage: 12, taxonomiesPerPage: 12,
status: '', status: '',
order: 'asc', order: 'asc',
ordeBy: 'date', orderBy: 'date',
searchQuery: '', searchQuery: '',
sortingOptions: [ sortingOptions: [
{ label: this.$i18n.get('label_title'), value: 'title' }, { label: this.$i18n.get('label_title'), value: 'title' },
{ label: this.$i18n.get('label_creation_date'), value: 'date' }, { label: this.$i18n.get('label_creation_date'), value: 'date' },
] ],
maxTaxonomiesPerPage: tainacan_plugin.api_max_items_per_page ? Number(tainacan_plugin.api_max_items_per_page) : 96
} }
}, },
computed: { computed: {

View File

@ -96,6 +96,7 @@
overflow-x: visible !important; overflow-x: visible !important;
white-space: normal !important; white-space: normal !important;
word-wrap: break-word; word-wrap: break-word;
word-break: break-word;
} }
} }
} }
@ -433,3 +434,8 @@
} }
} }
} }
/* This makes sure dropdown autocomplete inside a modal that is appended to body appears in front of the modal. */
body.tainacan-admin-page>.control.autocomplete {
z-index: 9999999;
}

View File

@ -135,6 +135,7 @@
max-width: 240px !important; max-width: 240px !important;
p { p {
font-size: 0.875em !important; font-size: 0.875em !important;
line-height: 1.125em;
color: var(--tainacan-input-color) !important; color: var(--tainacan-input-color) !important;
margin: 0px !important; margin: 0px !important;
} }

View File

@ -289,8 +289,8 @@
.slideshow-icon { .slideshow-icon {
color: var(--tainacan-info-color); color: var(--tainacan-info-color);
position: absolute; position: absolute;
right: 7px; right: 18px;
top: 7px; top: 12px;
transform: scale(0.0); transform: scale(0.0);
transition: transform 0.2s ease; transition: transform 0.2s ease;
} }

View File

@ -319,6 +319,7 @@ class Admin {
'admin_url' => admin_url(), 'admin_url' => admin_url(),
'theme_items_list_url' => esc_url_raw( get_site_url() ) . '/' . \Tainacan\Theme_Helper::get_instance()->get_items_list_slug(), 'theme_items_list_url' => esc_url_raw( get_site_url() ) . '/' . \Tainacan\Theme_Helper::get_instance()->get_items_list_slug(),
'theme_collection_list_url' => get_post_type_archive_link( 'tainacan-collection' ), 'theme_collection_list_url' => get_post_type_archive_link( 'tainacan-collection' ),
'theme_taxonomy_list_url' => get_post_type_archive_link( 'tainacan-taxonomy' ),
'custom_header_support' => get_theme_support('custom-header'), 'custom_header_support' => get_theme_support('custom-header'),
'registered_view_modes' => \Tainacan\Theme_Helper::get_instance()->get_registered_view_modes(), 'registered_view_modes' => \Tainacan\Theme_Helper::get_instance()->get_registered_view_modes(),
'exposer_mapper_param' => \Tainacan\Mappers_Handler::MAPPER_PARAM, 'exposer_mapper_param' => \Tainacan\Mappers_Handler::MAPPER_PARAM,

View File

@ -191,12 +191,16 @@ export default {
tainacanAxios: undefined, tainacanAxios: undefined,
paged: undefined, paged: undefined,
totalCollections: 0, totalCollections: 0,
apiRoot: '',
errorMessage: 'No collections found.', errorMessage: 'No collections found.',
swiper: {} swiper: {}
} }
}, },
created() { created() {
this.tainacanAxios = axios.create({ baseURL: this.tainacanApiRoot });
this.apiRoot = (tainacan_blocks && tainacan_blocks.root && !this.tainacanApiRoot) ? tainacan_blocks.root : this.tainacanApiRoot;
this.tainacanAxios = axios.create({ baseURL: this.apiRoot });
if (tainacan_blocks && tainacan_blocks.nonce) if (tainacan_blocks && tainacan_blocks.nonce)
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;

View File

@ -526,7 +526,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
setContent(); setContent();
}} }}
min={ 1 } min={ 1 }
max={ 96 } max={ tainacan_blocks.api_max_items_per_page ? Number(tainacan_blocks.api_max_items_per_page) : 96 }
/> />
</div> </div>
</PanelBody> </PanelBody>

View File

@ -201,11 +201,15 @@ export default {
paged: undefined, paged: undefined,
totalItems: 0, totalItems: 0,
swiper: {}, swiper: {},
apiRoot: '',
errorMessage: 'No items found.' errorMessage: 'No items found.'
} }
}, },
created() { created() {
this.tainacanAxios = axios.create({ baseURL: this.tainacanApiRoot });
this.apiRoot = (tainacan_blocks && tainacan_blocks.root && !this.tainacanApiRoot) ? tainacan_blocks.root : this.tainacanApiRoot;
this.tainacanAxios = axios.create({ baseURL: this.apiRoot });
if (tainacan_blocks && tainacan_blocks.nonce) if (tainacan_blocks && tainacan_blocks.nonce)
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;

View File

@ -14,100 +14,104 @@
}, },
"attributes": { "attributes": {
"content": { "content": {
"type": "Array", "type": "array",
"source": "children", "source": "children",
"selector": "div" "selector": "div"
}, },
"terms": { "terms": {
"type": "Array", "type": "array",
"default": [] "default": []
}, },
"isModalOpen": { "isModalOpen": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"selectedTerms": { "selectedTerms": {
"type": "Array", "type": "array",
"default": [] "default": []
}, },
"itemsRequestSource": { "itemsRequestSource": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"maxTermsNumber": { "maxTermsnumber": {
"type": "Number", "type": "number",
"value": 12 "value": 12
}, },
"maxTermsPerScreen": { "maxTermsPerScreen": {
"type": "Number", "type": "number",
"value": 6 "value": 6
}, },
"spaceBetweenTerms": { "spaceBetweenTerms": {
"type": "Number", "type": "number",
"value": 32 "value": 32
}, },
"spaceAroundCarousel": { "spaceAroundCarousel": {
"type": "Number", "type": "number",
"value": 50 "value": 50
}, },
"isLoading": { "isLoading": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"isLoadingTerm": { "isLoadingTerm": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"arrowsPosition": { "arrowsPosition": {
"type": "String", "type": "string",
"value": "around" "value": "around"
}, },
"largeArrows": { "largeArrows": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"arrowsStyle": { "arrowsStyle": {
"type": "String", "type": "string",
"value": "type-1" "value": "type-1"
}, },
"autoPlay": { "autoPlay": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"autoPlaySpeed": { "autoPlaySpeed": {
"type": "Number", "type": "number",
"value": 3 "value": 3
}, },
"loopSlides": { "loopSlides": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"hideName": { "hideName": {
"type": "Boolean", "type": "boolean",
"value": true "value": true
}, },
"showTermThumbnail": { "showTermThumbnail": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"term": { "term": {
"type": "Object", "type": "object",
"value": {} "value": {}
}, },
"imageSize": {
"type": "string",
"default": "tainacan-medium"
},
"blockId": { "blockId": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"termBackgroundColor": { "termBackgroundColor": {
"type": "String", "type": "string",
"default": "#454647" "default": "#454647"
}, },
"termTextColor": { "termTextColor": {
"type": "String", "type": "string",
"default": "#ffffff" "default": "#ffffff"
}, },
"taxonomyId": { "taxonomyId": {
"type": "String", "type": "string",
"default": "" "default": ""
} }
}, },

View File

@ -1,6 +1,153 @@
const { useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor ); const { useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
export default [ export default [
/* Deprecated on 0.20.1 to add imageSize attribute */
{
"attributes": {
"content": {
"type": "Array",
"source": "children",
"selector": "div"
},
"terms": {
"type": "Array",
"default": []
},
"isModalOpen": {
"type": "Boolean",
"default": false
},
"selectedTerms": {
"type": "Array",
"default": []
},
"itemsRequestSource": {
"type": "String",
"default": ""
},
"maxTermsNumber": {
"type": "Number",
"value": 12
},
"maxTermsPerScreen": {
"type": "Number",
"value": 6
},
"spaceBetweenTerms": {
"type": "Number",
"value": 32
},
"spaceAroundCarousel": {
"type": "Number",
"value": 50
},
"isLoading": {
"type": "Boolean",
"value": false
},
"isLoadingTerm": {
"type": "Boolean",
"value": false
},
"arrowsPosition": {
"type": "String",
"value": "around"
},
"largeArrows": {
"type": "Boolean",
"value": false
},
"arrowsStyle": {
"type": "String",
"value": "type-1"
},
"autoPlay": {
"type": "Boolean",
"value": false
},
"autoPlaySpeed": {
"type": "Number",
"value": 3
},
"loopSlides": {
"type": "Boolean",
"value": false
},
"hideName": {
"type": "Boolean",
"value": true
},
"showTermThumbnail": {
"type": "Boolean",
"value": false
},
"term": {
"type": "Object",
"value": {}
},
"blockId": {
"type": "String",
"default": ""
},
"termBackgroundColor": {
"type": "String",
"default": "#454647"
},
"termTextColor": {
"type": "String",
"default": "#ffffff"
},
"taxonomyId": {
"type": "String",
"default": ""
}
},
save({ attributes, className }) {
const {
content,
blockId,
selectedTerms,
arrowsPosition,
largeArrows,
arrowsStyle,
maxTermsPerScreen,
maxTermsNumber,
spaceBetweenTerms,
spaceAroundCarousel,
autoPlay,
autoPlaySpeed,
loopSlides,
hideName,
showTermThumbnail,
taxonomyId
} = attributes;
// Gets attributes such as style, that are automatically added by the editor hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps.save();
return <div
{ ...blockProps }
data-module="carousel-terms-list"
selected-terms={ JSON.stringify(selectedTerms.map((term) => { return term.id; })) }
arrows-position={ arrowsPosition }
auto-play={ '' + autoPlay }
auto-play-speed={ autoPlaySpeed }
loop-slides={ '' + loopSlides }
hide-name={ '' + hideName }
large-arrows={ '' + largeArrows }
arrows-style={ arrowsStyle }
max-terms-number={ maxTermsNumber }
max-terms-per-screen={ maxTermsPerScreen }
space-between-terms={ spaceBetweenTerms }
space-around-carousel={ spaceAroundCarousel }
taxonomy-id={ taxonomyId }
tainacan-api-root={ tainacan_blocks.root }
tainacan-base-url={ tainacan_blocks.base_url }
show-term-thumbnail={ '' + showTermThumbnail }
id={ 'wp-block-tainacan-carousel-terms-list_' + blockId }>
{ content }
</div>
}
},
/* Deprecated on Tainacan 0.18.6 due to arrowsStyle option */ /* Deprecated on Tainacan 0.18.6 due to arrowsStyle option */
{ {
"attributes": { "attributes": {

View File

@ -2,8 +2,12 @@ const { __ } = wp.i18n;
const { RangeControl, Spinner, Button, BaseControl, ToggleControl, SelectControl, Placeholder, IconButton, PanelBody } = wp.components; const { RangeControl, Spinner, Button, BaseControl, ToggleControl, SelectControl, Placeholder, IconButton, PanelBody } = wp.components;
const { InspectorControls, BlockControls, useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor ); const { InspectorControls, BlockControls, useBlockProps, store } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
const { useSelect } = wp.data;
import map from 'lodash/map'; // Do not user import { map,pick } from 'lodash'; -> These causes conflicts with underscore due to lodash global variable
import pick from 'lodash/pick';
import TermsModal from '../terms-list/terms-modal.js'; import TermsModal from '../terms-list/terms-modal.js';
import tainacan from '../../js/axios.js'; import tainacan from '../../js/axios.js';
import axios from 'axios'; import axios from 'axios';
@ -34,7 +38,8 @@ export default function({ attributes, setAttributes, className, isSelected, clie
loopSlides, loopSlides,
hideName, hideName,
showTermThumbnail, showTermThumbnail,
taxonomyId taxonomyId,
imageSize
} = attributes; } = attributes;
// Gets blocks props from hook // Gets blocks props from hook
@ -48,9 +53,30 @@ export default function({ attributes, setAttributes, className, isSelected, clie
maxTermsPerScreen = 6; maxTermsPerScreen = 6;
setAttributes({ maxTermsPerScreen: maxTermsPerScreen }); setAttributes({ maxTermsPerScreen: maxTermsPerScreen });
} }
if (imageSize === undefined) {
imageSize = 'tainacan-medium';
setAttributes({ imageSize: imageSize });
}
const thumbHelper = ThumbnailHelperFunctions(); const thumbHelper = ThumbnailHelperFunctions();
// Get available image sizes
const { imageSizes } = useSelect(
( select ) => {
const { getSettings } = select( store );
const settings = pick( getSettings(), [
'imageSizes'
] );
return settings
},
[ clientId ]
);
const imageSizeOptions = map(
imageSizes,
( { name, slug } ) => ( { value: slug, label: name } )
);
function prepareItem(term, termItems) { function prepareItem(term, termItems) {
return ( return (
<li <li
@ -87,8 +113,18 @@ export default function({ attributes, setAttributes, className, isSelected, clie
</div> </div>
: :
<img <img
src={ term.header_image ? term.header_image : `${tainacan_blocks.base_url}/assets/images/placeholder_square.png`} src={
alt={ term.name ? term.name : __( 'Thumbnail', 'tainacan' )}/> term.thumbnail && term.thumbnail[imageSize] && term.thumbnail[imageSize][0]
?
term.thumbnail[imageSize][0]
:
(term.thumbnail && term.thumbnail['thumbnail'][0] && term.thumbnail['thumbnail'][0]
?
term.thumbnail['thumbnail'][0]
:
`${tainacan_blocks.base_url}/assets/images/placeholder_square.png`)
}
alt={ term.thumbnail_alt ? term.thumbnail_alt : (term.name ? term.name : __( 'Thumbnail', 'tainacan' ) ) }/>
} }
{ !hideName ? <span>{ term.name ? term.name : '' }</span> : null } { !hideName ? <span>{ term.name ? term.name : '' }</span> : null }
</a> </a>
@ -233,6 +269,16 @@ export default function({ attributes, setAttributes, className, isSelected, clie
min={ 1 } min={ 1 }
max={ 9 } max={ 9 }
/> />
<SelectControl
label={__('Image size', 'tainacan')}
value={ imageSize }
options={ imageSizeOptions }
onChange={ ( anImageSize ) => {
imageSize = anImageSize;
setAttributes({ imageSize: imageSize });
setContent();
}}
/>
<RangeControl <RangeControl
label={ __('Space between each term', 'tainacan') } label={ __('Space between each term', 'tainacan') }
value={ !isNaN(spaceBetweenTerms) ? spaceBetweenTerms : 32 } value={ !isNaN(spaceBetweenTerms) ? spaceBetweenTerms : 32 }

View File

@ -16,6 +16,7 @@ export default function({ attributes, className }) {
autoPlaySpeed, autoPlaySpeed,
loopSlides, loopSlides,
hideName, hideName,
imageSize,
showTermThumbnail, showTermThumbnail,
taxonomyId taxonomyId
} = attributes; } = attributes;
@ -33,6 +34,7 @@ export default function({ attributes, className }) {
hide-name={ '' + hideName } hide-name={ '' + hideName }
large-arrows={ '' + largeArrows } large-arrows={ '' + largeArrows }
arrows-style={ arrowsStyle } arrows-style={ arrowsStyle }
image-size={ imageSize }
max-terms-number={ maxTermsNumber } max-terms-number={ maxTermsNumber }
max-terms-per-screen={ maxTermsPerScreen } max-terms-per-screen={ maxTermsPerScreen }
space-between-terms={ spaceBetweenTerms } space-between-terms={ spaceBetweenTerms }

View File

@ -36,6 +36,7 @@ export default (element) => {
maxTermsPerScreen: 6, maxTermsPerScreen: 6,
spaceBetweenTerms: 32, spaceBetweenTerms: 32,
spaceAroundCarousel: 50, spaceAroundCarousel: 50,
imageSize: 'tainacan-medium',
loopSlides: false, loopSlides: false,
hideName: true, hideName: true,
showTermThumbnail: false, showTermThumbnail: false,
@ -57,6 +58,7 @@ export default (element) => {
loopSlides: this.loopSlides, loopSlides: this.loopSlides,
largeArrows: this.largeArrows, largeArrows: this.largeArrows,
arrowsStyle: this.arrowsStyle, arrowsStyle: this.arrowsStyle,
imageSize: this.imageSize,
maxTermsPerScreen: this.maxTermsPerScreen, maxTermsPerScreen: this.maxTermsPerScreen,
spaceBetweenTerms: this.spaceBetweenTerms, spaceBetweenTerms: this.spaceBetweenTerms,
spaceAroundCarousel: this.spaceAroundCarousel, spaceAroundCarousel: this.spaceAroundCarousel,
@ -83,6 +85,7 @@ export default (element) => {
this.largeArrows = this.$el.attributes['large-arrows'] != undefined ? this.$el.attributes['large-arrows'].value == 'true' : false; this.largeArrows = this.$el.attributes['large-arrows'] != undefined ? this.$el.attributes['large-arrows'].value == 'true' : false;
this.arrowsStyle = this.$el.attributes['arrows-style'] != undefined ? this.$el.attributes['arrows-style'].value : undefined; this.arrowsStyle = this.$el.attributes['arrows-style'] != undefined ? this.$el.attributes['arrows-style'].value : undefined;
this.loopSlides = this.$el.attributes['loop-slides'] != undefined ? this.$el.attributes['loop-slides'].value == 'true' : false; this.loopSlides = this.$el.attributes['loop-slides'] != undefined ? this.$el.attributes['loop-slides'].value == 'true' : false;
this.imageSize = this.$el.attributes['image-size'] != undefined ? this.$el.attributes['image-size'].value : 'tainacan-medium';
this.hideName = this.$el.attributes['hide-name'] != undefined ? this.$el.attributes['hide-name'].value == 'true' : false; this.hideName = this.$el.attributes['hide-name'] != undefined ? this.$el.attributes['hide-name'].value == 'true' : false;
this.taxonomyId = this.$el.attributes['taxonomy-id'] != undefined ? this.$el.attributes['taxonomy-id'].value : undefined; this.taxonomyId = this.$el.attributes['taxonomy-id'] != undefined ? this.$el.attributes['taxonomy-id'].value : undefined;
this.showTermThumbnail = this.$el.attributes['show-term-thumbnail'] != undefined ? this.$el.attributes['show-term-thumbnail'].value == 'true' : false; this.showTermThumbnail = this.$el.attributes['show-term-thumbnail'] != undefined ? this.$el.attributes['show-term-thumbnail'].value == 'true' : false;

View File

@ -39,8 +39,29 @@
:id="isNaN(term.id) ? term.id : 'term-id-' + term.id" :id="isNaN(term.id) ? term.id : 'term-id-' + term.id"
:href="term.url"> :href="term.url">
<img <img
:src="term.header_image ? term.header_image : `${tainacanBaseUrl}/assets/images/placeholder_square.png`" :src="
:alt="term.name ? term.name : $root.__('Thumbnail', 'tainacan')" > term.thumbnail && term.thumbnail[imageSize] && term.thumbnail[imageSize][0]
?
term.thumbnail[imageSize][0]
:
(term.thumbnail && term.thumbnail['thumbnail'] && term.thumbnail['thumbnail'][0]
?
term.thumbnail['thumbnail'][0]
:
`${tainacanBaseUrl}/assets/images/placeholder_square.png`)
"
:data-src="
term.thumbnail && term.thumbnail[imageSize] && term.thumbnail[imageSize][0]
?
term.thumbnail[imageSize][0]
:
(term.thumbnail && term.thumbnail['thumbnail'] && term.thumbnail['thumbnail'][0]
?
term.thumbnail['thumbnail'][0]
:
`${tainacanBaseUrl}/assets/images/placeholder_square.png`)
"
:alt="term.thumbnail_alt ? term.thumbnail_alt : (term.name ? term.name : $root.__('Thumbnail', 'tainacan'))" >
<span v-if="!hideName">{{ term.name ? term.name : '' }}</span> <span v-if="!hideName">{{ term.name ? term.name : '' }}</span>
</a> </a>
<a <a
@ -152,6 +173,7 @@ export default {
hideName: Boolean, hideName: Boolean,
largeArrows: Boolean, largeArrows: Boolean,
arrowsStyle: String, arrowsStyle: String,
imageSize: String,
showTermThumbnail: Boolean, showTermThumbnail: Boolean,
tainacanApiRoot: String, tainacanApiRoot: String,
tainacanBaseUrl: String, tainacanBaseUrl: String,
@ -172,11 +194,15 @@ export default {
paged: undefined, paged: undefined,
totalTerms: 0, totalTerms: 0,
swiper: {}, swiper: {},
apiRoot: '',
errorMessage: 'No terms found.' errorMessage: 'No terms found.'
} }
}, },
created() { created() {
this.tainacanAxios = axios.create({ baseURL: this.tainacanApiRoot });
this.apiRoot = (tainacan_blocks && tainacan_blocks.root && !this.tainacanApiRoot) ? tainacan_blocks.root : this.tainacanApiRoot;
this.tainacanAxios = axios.create({ baseURL: this.apiRoot });
if (tainacan_blocks && tainacan_blocks.nonce) if (tainacan_blocks && tainacan_blocks.nonce)
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;

View File

@ -678,7 +678,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
setContent(); setContent();
}} }}
min={ 1 } min={ 1 }
max={ 96 } max={ tainacan_blocks.api_max_items_per_page ? Number(tainacan_blocks.api_max_items_per_page) : 96 }
/> />
<hr></hr> <hr></hr>
</div> </div>

View File

@ -324,13 +324,16 @@ export default {
tainacanAxios: undefined, tainacanAxios: undefined,
paged: undefined, paged: undefined,
totalItems: 0, totalItems: 0,
apiRoot: '',
errorMessage: 'No items found.' errorMessage: 'No items found.'
} }
}, },
created() { created() {
this.tainacanAxios = axios.create({ baseURL: this.tainacanApiRoot }); this.apiRoot = (tainacan_blocks && tainacan_blocks.root && !this.tainacanApiRoot) ? tainacan_blocks.root : this.tainacanApiRoot;
if (tainacan_blocks && tainacan_blocks.nonce)
this.tainacanAxios = axios.create({ baseURL: this.apiRoot });
if ( tainacan_blocks && tainacan_blocks.nonce )
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
this.localOrder = this.order; this.localOrder = this.order;

View File

@ -93,8 +93,8 @@ export default class TermModal extends React.Component {
id: term.id, id: term.id,
url: term.url, url: term.url,
header_image: [{ header_image: [{
src: term.header_image, src: term.thumbnail && term.thumbnail['tainacan-small'] && term.thumbnail['tainacan-small'][0] ? term.thumbnail['tainacan-small'][0] : term.header_image,
alt: term.name alt: term.thumbnail_alt ? term.thumbnail_alt : term.name
}] }]
})); }));
@ -134,8 +134,8 @@ export default class TermModal extends React.Component {
id: term.id, id: term.id,
url: term.url, url: term.url,
header_image: [{ header_image: [{
src: term.header_image, src: term.thumbnail && term.thumbnail['tainacan-small'] && term.thumbnail['tainacan-small'][0] ? term.thumbnail['tainacan-small'][0] : term.header_image,
alt: term.name alt: term.thumbnail_alt ? term.thumbnail_alt : term.name
}] }]
}); });
} }

View File

@ -48,13 +48,26 @@
content: item.metadata != undefined ? renderMetadata(item, column) : '', content: item.metadata != undefined ? renderMetadata(item, column) : '',
html: true, html: true,
autoHide: false, autoHide: false,
placement: 'auto-start', placement: 'top-start',
popperClass: ['tainacan-tooltip', 'tooltip'] popperClass: ['tainacan-tooltip', 'tooltip']
}" }"
v-for="(column, metadatumIndex) in displayedMetadata" v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex" :key="metadatumIndex"
v-if="column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')" v-if="column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.metadata != undefined && collectionId ? renderMetadata(item, column) : (item.title ? item.title :`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" /> v-html="item.metadata != undefined && collectionId && renderMetadata(item, column) ? renderMetadata(item, column) : (item.title ? item.title :`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" />
<div class="tainacan-map-card-thumbnail">
<blur-hash-image
v-if="item.thumbnail != undefined"
class="tainacan-map-card-item-thumbnail"
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-small', 40)"
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-small', 40)"
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-small')"
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-small', item.document_mimetype)"
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-small', item.document_mimetype)"
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
:transition-duration="500"
/>
</div>
<span <span
v-if="isSlideshowViewModeEnabled" v-if="isSlideshowViewModeEnabled"
v-tooltip="{ v-tooltip="{

View File

@ -131,7 +131,7 @@ export default (element) => {
// View Modes Logic // View Modes Logic
const registeredViewModes = const registeredViewModes =
( tainacan_plugin && tainacan_plugin.registered_view_modes && tainacan_plugin.registered_view_modes.lenght ) ? ( tainacan_plugin && tainacan_plugin.registered_view_modes && tainacan_plugin.registered_view_modes.length ) ?
tainacan_plugin.registered_view_modes : tainacan_plugin.registered_view_modes :
[ 'table', 'cards', 'records', 'masonry', 'slideshow', 'list', 'map' ]; [ 'table', 'cards', 'records', 'masonry', 'slideshow', 'list', 'map' ];

View File

@ -14,129 +14,133 @@
}, },
"attributes": { "attributes": {
"content": { "content": {
"type": "Array", "type": "array",
"source": "children", "source": "children",
"selector": "div" "selector": "div"
}, },
"collectionId": { "collectionId": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"collectionSlug": { "collectionSlug": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"facets": { "facets": {
"type": "Array", "type": "array",
"default": [] "default": []
}, },
"facetsObject": { "facetsObject": {
"type": "Array", "type": "array",
"default": [] "default": []
}, },
"showImage": { "showImage": {
"type": "Boolean", "type": "boolean",
"default": true "default": true
}, },
"nameInsideImage": { "nameInsideImage": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"showItemsCount": { "showItemsCount": {
"type": "Boolean", "type": "boolean",
"default": true "default": true
}, },
"showLoadMore": { "showLoadMore": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"showSearchBar": { "showSearchBar": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"layout": { "layout": {
"type": "String", "type": "string",
"default": "grid" "default": "grid"
}, },
"cloudRate": { "cloudRate": {
"type": "Number", "type": "number",
"default": 1 "default": 1
}, },
"isModalOpen": { "isModalOpen": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"gridMargin": { "gridMargin": {
"type": "Number", "type": "number",
"default": 24 "default": 24
}, },
"metadatumId": { "metadatumId": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"metadatumType": { "metadatumType": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"facetsRequestSource": { "facetsRequestSource": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"maxFacetsNumber": { "maxFacetsNumber": {
"type": "Number", "type": "number",
"value": 12 "value": 12
}, },
"isLoading": { "isLoading": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"isLoadingCollection": { "isLoadingCollection": {
"type": "Boolean", "type": "boolean",
"value": false "value": false
}, },
"collection": { "collection": {
"type": "Object", "type": "object",
"value": {} "value": {}
}, },
"searchString": { "searchstring": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"blockId": { "blockId": {
"type": "String", "type": "string",
"default": "" "default": ""
}, },
"parentTerm": { "parentTerm": {
"type": "Number", "type": "number",
"default": null "default": null
}, },
"isParentTermModalOpen": { "isParentTermModalOpen": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"maxColumnsCount": { "maxColumnsCount": {
"type": "Number", "type": "number",
"default": 5 "default": 5
}, },
"appendChildTerms": { "appendChildTerms": {
"type": "Boolean", "type": "boolean",
"default": false "default": false
}, },
"childFacetsObject": { "childFacetsObject": {
"type": "Object", "type": "object",
"default": {} "default": {}
}, },
"linkTermFacetsToTermPage": { "linkTermFacetsToTermPage": {
"type": "Boolean", "type": "boolean",
"default": true "default": true
}, },
"isLoadingChildTerms": { "isLoadingChildTerms": {
"type": "Number", "type": "number",
"default": null "default": null
}, },
"itemsCountStyle": { "itemsCountStyle": {
"type": "String", "type": "string",
"default": "default" "default": "default"
},
"imageSize": {
"type": "string",
"default": "tainacan-medium"
} }
}, },
"supports": { "supports": {

View File

@ -1,4 +1,190 @@
const { useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
export default [ export default [
/* Deprecated on Tainacan 0.20.1 to add imageSize */
{
"attributes": {
"content": {
"type": "Array",
"source": "children",
"selector": "div"
},
"collectionId": {
"type": "String",
"default": ""
},
"collectionSlug": {
"type": "String",
"default": ""
},
"facets": {
"type": "Array",
"default": []
},
"facetsObject": {
"type": "Array",
"default": []
},
"showImage": {
"type": "Boolean",
"default": true
},
"nameInsideImage": {
"type": "Boolean",
"default": false
},
"showItemsCount": {
"type": "Boolean",
"default": true
},
"showLoadMore": {
"type": "Boolean",
"default": false
},
"showSearchBar": {
"type": "Boolean",
"value": false
},
"layout": {
"type": "String",
"default": "grid"
},
"cloudRate": {
"type": "Number",
"default": 1
},
"isModalOpen": {
"type": "Boolean",
"default": false
},
"gridMargin": {
"type": "Number",
"default": 24
},
"metadatumId": {
"type": "String",
"default": ""
},
"metadatumType": {
"type": "String",
"default": ""
},
"facetsRequestSource": {
"type": "String",
"default": ""
},
"maxFacetsNumber": {
"type": "Number",
"value": 12
},
"isLoading": {
"type": "Boolean",
"value": false
},
"isLoadingCollection": {
"type": "Boolean",
"value": false
},
"collection": {
"type": "Object",
"value": {}
},
"searchString": {
"type": "String",
"default": ""
},
"blockId": {
"type": "String",
"default": ""
},
"parentTerm": {
"type": "Number",
"default": null
},
"isParentTermModalOpen": {
"type": "Boolean",
"default": false
},
"maxColumnsCount": {
"type": "Number",
"default": 5
},
"appendChildTerms": {
"type": "Boolean",
"default": false
},
"childFacetsObject": {
"type": "Object",
"default": {}
},
"linkTermFacetsToTermPage": {
"type": "Boolean",
"default": true
},
"isLoadingChildTerms": {
"type": "Number",
"default": null
},
"itemsCountStyle": {
"type": "String",
"default": "default"
}
},
save({ attributes, className }) {
const {
content,
blockId,
collectionId,
collectionSlug,
parentTerm,
showImage,
nameInsideImage,
showItemsCount,
showLoadMore,
layout,
cloudRate,
gridMargin,
metadatumId,
metadatumType,
maxFacetsNumber,
maxColumnsCount,
showSearchBar,
linkTermFacetsToTermPage,
appendChildTerms,
itemsCountStyle
} = attributes;
// Gets attributes such as style, that are automatically added by the editor hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps.save();
return <div
{ ...blockProps }
data-module="facets-list"
metadatum-id={ metadatumId }
metadatum-type={ metadatumType }
collection-id={ collectionId }
collection-slug={ collectionSlug }
parent-term-id={ parentTerm ? parentTerm.id : undefined }
show-image={ '' + showImage }
name-inside-image={ nameInsideImage === true ? 'true' : 'false' }
show-items-count={ '' + showItemsCount }
show-search-bar={ '' + showSearchBar }
show-load-more={ '' + showLoadMore }
append-child-terms={ (appendChildTerms === true ? 'true' : 'false') }
link-term-facets-to-term-page={ linkTermFacetsToTermPage === false ? 'false' : 'true' }
layout={ layout }
items-count-style={ itemsCountStyle }
cloud-rate={ cloudRate }
grid-margin={ gridMargin }
max-facets-number={ maxFacetsNumber }
max-columns-count={ maxColumnsCount }
tainacan-api-root={ tainacan_blocks.root }
tainacan-base-url={ tainacan_blocks.base_url }
tainacan-site-url={ tainacan_blocks.site_url }
id={ 'wp-block-tainacan-facets-list_' + blockId }>
{ content }
</div>
}
},
/* Deprecated on Tainacan 0.18.6 due to itemsCountStyle */ /* Deprecated on Tainacan 0.18.6 due to itemsCountStyle */
{ {
"attributes": { "attributes": {

View File

@ -2,13 +2,18 @@ const { __ } = wp.i18n;
const { BaseControl, RangeControl, Spinner, SelectControl, Button, ToggleControl, Placeholder, PanelBody } = wp.components; const { BaseControl, RangeControl, Spinner, SelectControl, Button, ToggleControl, Placeholder, PanelBody } = wp.components;
const { InspectorControls, BlockControls, useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor ); const { InspectorControls, BlockControls, useBlockProps, store } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
const { useSelect } = wp.data;
import map from 'lodash/map'; // Do not user import { map,pick } from 'lodash'; -> These causes conflicts with underscore due to lodash global variable
import pick from 'lodash/pick';
import MetadataModal from './metadata-modal.js'; import MetadataModal from './metadata-modal.js';
import ParentTermModal from './parent-term-modal.js'; import ParentTermModal from './parent-term-modal.js';
import tainacan from '../../js/axios.js'; import tainacan from '../../js/axios.js';
import axios from 'axios'; import axios from 'axios';
import qs from 'qs'; import qs from 'qs';
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js'; import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
export default function({ attributes, setAttributes, className, isSelected, clientId }) { export default function({ attributes, setAttributes, className, isSelected, clientId }) {
@ -40,7 +45,8 @@ export default function({ attributes, setAttributes, className, isSelected, clie
childFacetsObject, childFacetsObject,
linkTermFacetsToTermPage, linkTermFacetsToTermPage,
isLoadingChildTerms, isLoadingChildTerms,
itemsCountStyle itemsCountStyle,
imageSize
} = attributes; } = attributes;
// Gets blocks props from hook // Gets blocks props from hook
@ -87,7 +93,30 @@ export default function({ attributes, setAttributes, className, isSelected, clie
if (metadatumType == __('Relationship', 'tainacan')) { if (metadatumType == __('Relationship', 'tainacan')) {
metadatumType = 'Tainacan\\Metadata_Types\\Relationship'; metadatumType = 'Tainacan\\Metadata_Types\\Relationship';
setAttributes({ metadatumType: metadatumType }); setAttributes({ metadatumType: metadatumType });
} if (imageSize === undefined) {
imageSize = 'tainacan-medium';
setAttributes({ imageSize: imageSize });
} }
const thumbHelper = ThumbnailHelperFunctions();
// Get available image sizes
const { imageSizes } = useSelect(
( select ) => {
const { getSettings } = select( store );
const settings = pick( getSettings(), [
'imageSizes'
] );
return settings
},
[ clientId ]
);
const imageSizeOptions = map(
imageSizes,
( { name, slug } ) => ( { value: slug, label: name } )
);
function prepareFacet(facet) { function prepareFacet(facet) {
const facetId = facet.id != undefined ? facet.id : facet.value; const facetId = facet.id != undefined ? facet.id : facet.value;
@ -96,38 +125,23 @@ export default function({ attributes, setAttributes, className, isSelected, clie
key={ facetId } key={ facetId }
className={ 'facet-list-item' + (!showImage ? ' facet-without-image' : '') + (nameInsideImage ? ' facet-with-name-inside-image' : '') + ((appendChildTerms && facet.total_children > 0) ? ' facet-term-with-children': '')}> className={ 'facet-list-item' + (!showImage ? ' facet-without-image' : '') + (nameInsideImage ? ' facet-with-name-inside-image' : '') + ((appendChildTerms && facet.total_children > 0) ? ' facet-term-with-children': '')}>
<a <a
id={ isNaN(facetId) ? facetId : 'facet-id-' + facetId } id={ isNaN(facetId) ? facetId : 'facet-id-' + facetId }
href={ !appendChildTerms ? ((linkTermFacetsToTermPage && isMetadatumTypeTaxonomy(metadatumType)) ? facet.term_url : facet.url) : (facet.total_children > 0 ? null : (linkTermFacetsToTermPage ? facet.term_url : facet.url)) } href={ !appendChildTerms ? ((linkTermFacetsToTermPage && isMetadatumTypeTaxonomy(metadatumType)) ? facet.term_url : facet.url) : (facet.total_children > 0 ? null : (linkTermFacetsToTermPage ? facet.term_url : facet.url)) }
onClick={ () => { (appendChildTerms && facet.total_children > 0) ? displayChildTerms(facetId) : null } } onClick={ () => { (appendChildTerms && facet.total_children > 0) ? displayChildTerms(facetId) : null } }
style={{ fontSize: layout == 'cloud' && facet.total_items ? + (1 + (cloudRate/4) * Math.log(facet.total_items)) + 'em' : ''}}> style={{ fontSize: layout == 'cloud' && facet.total_items ? + (1 + (cloudRate/4) * Math.log(facet.total_items)) + 'em' : ''}}>
{ isMetadatumTypeTaxonomy(metadatumType) ? <img
<img src={
src={ facet.entity.thumbnail && facet.entity.thumbnail[imageSize][0] && facet.entity.thumbnail[imageSize][0]
facet.entity && facet.entity['header_image'] ?
? facet.entity.thumbnail[imageSize][0]
facet.entity['header_image'] :
: (facet.entity.thumbnail && facet.entity.thumbnail['thumbnail'][0] && facet.entity.thumbnail['thumbnail'][0]
`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` ?
} facet.entity.thumbnail['thumbnail'][0]
alt={ facet.label ? facet.label : __( 'Thumbnail', 'tainacan' ) }/> :
: null `${tainacan_blocks.base_url}/assets/images/placeholder_square.png`)
} }
{ isMetadatumTypeRelationship(metadatumType) ? alt={ facet.label ? facet.label : __( 'Thumbnail', 'tainacan' ) }/>
<img
src={
facet.entity.thumbnail && facet.entity.thumbnail['tainacan-medium'][0] && facet.entity.thumbnail['tainacan-medium'][0]
?
facet.entity.thumbnail['tainacan-medium'][0]
:
(facet.entity.thumbnail && facet.entity.thumbnail['thumbnail'][0] && facet.entity.thumbnail['thumbnail'][0]
?
facet.entity.thumbnail['thumbnail'][0]
:
`${tainacan_blocks.base_url}/assets/images/placeholder_square.png`)
}
alt={ facet.label ? facet.label : __( 'Thumbnail', 'tainacan' ) }/>
: null
}
<div className={ 'facet-label-and-count' + (itemsCountStyle === 'below' ? ' is-style-facet-label-and-count--below' : '') }> <div className={ 'facet-label-and-count' + (itemsCountStyle === 'below' ? ' is-style-facet-label-and-count--below' : '') }>
<span>{ facet.label ? facet.label : '' }</span> <span>{ facet.label ? facet.label : '' }</span>
{ {
@ -507,7 +521,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
setContent(); setContent();
}} }}
min={ 1 } min={ 1 }
max={ 96 } max={ tainacan_blocks.api_max_items_per_page ? Number(tainacan_blocks.api_max_items_per_page) : 96 }
/> />
<ToggleControl <ToggleControl
label={__('Items count', 'tainacan')} label={__('Items count', 'tainacan')}
@ -592,6 +606,17 @@ export default function({ attributes, setAttributes, className, isSelected, clie
> >
<div> <div>
{ (isMetadatumTypeTaxonomy(metadatumType) || isMetadatumTypeRelationship(metadatumType)) ? { (isMetadatumTypeTaxonomy(metadatumType) || isMetadatumTypeRelationship(metadatumType)) ?
<>
<SelectControl
label={__('Image size', 'tainacan')}
value={ imageSize }
options={ imageSizeOptions }
onChange={ ( anImageSize ) => {
imageSize = anImageSize;
setAttributes({ imageSize: imageSize });
setContent();
}}
/>
<ToggleControl <ToggleControl
label={__('Name inside image', 'tainacan')} label={__('Name inside image', 'tainacan')}
help={ nameInsideImage ? __("Toggle to show facet's name inside the image", 'tainacan') : __("Do not show facet's name image", 'tainacan')} help={ nameInsideImage ? __("Toggle to show facet's name inside the image", 'tainacan') : __("Do not show facet's name image", 'tainacan')}
@ -602,7 +627,8 @@ export default function({ attributes, setAttributes, className, isSelected, clie
updateContent(); updateContent();
} }
} }
/> : null />
</> : null
} }
<div style={{ marginTop: '16px'}}> <div style={{ marginTop: '16px'}}>
<RangeControl <RangeControl
@ -642,6 +668,17 @@ export default function({ attributes, setAttributes, className, isSelected, clie
> >
<div> <div>
{ (isMetadatumTypeTaxonomy(metadatumType) || isMetadatumTypeRelationship(metadatumType)) ? { (isMetadatumTypeTaxonomy(metadatumType) || isMetadatumTypeRelationship(metadatumType)) ?
<>
<SelectControl
label={__('Image size', 'tainacan')}
value={ imageSize }
options={ imageSizeOptions }
onChange={ ( anImageSize ) => {
imageSize = anImageSize;
setAttributes({ imageSize: imageSize });
setContent();
}}
/>
<ToggleControl <ToggleControl
label={__('Image', 'tainacan')} label={__('Image', 'tainacan')}
help={ showImage ? __("Toggle to show facet's image", 'tainacan') : __("Do not show facet's image", 'tainacan')} help={ showImage ? __("Toggle to show facet's image", 'tainacan') : __("Do not show facet's image", 'tainacan')}
@ -653,6 +690,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
} }
} }
/> />
</>
: null } : null }
<div style={{ marginTop: '16px'}}> <div style={{ marginTop: '16px'}}>
<RangeControl <RangeControl
@ -706,7 +744,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
existingMetadatumId={ metadatumId } existingMetadatumId={ metadatumId }
existingMetadatumType={ metadatumType } existingMetadatumType={ metadatumType }
onSelectCollection={ (selectedCollection) => { onSelectCollection={ (selectedCollection) => {
collectionId = selectedCollection.id; collectionId = selectedCollection.id + "";
collectionSlug = selectedCollection.slug; collectionSlug = selectedCollection.slug;
setAttributes({ setAttributes({
@ -715,7 +753,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
}); });
}} }}
onSelectMetadatum={ (selectedFacet) =>{ onSelectMetadatum={ (selectedFacet) =>{
metadatumId = selectedFacet.metadatumId; metadatumId = selectedFacet.metadatumId + "";
metadatumType = selectedFacet.metadatumType; metadatumType = selectedFacet.metadatumType;
setAttributes({ setAttributes({
metadatumId: metadatumId, metadatumId: metadatumId,

View File

@ -8,21 +8,10 @@
@click="() => { isCollapseInsteadOfLink(facet) ? displayChildTerms(facetId) : null }" @click="() => { isCollapseInsteadOfLink(facet) ? displayChildTerms(facetId) : null }"
:style="{ fontSize: layout == 'cloud' && facet.total_items ? + (1 + (cloudRate/4) * Math.log(facet.total_items)) + 'em' : ''}"> :style="{ fontSize: layout == 'cloud' && facet.total_items ? + (1 + (cloudRate/4) * Math.log(facet.total_items)) + 'em' : ''}">
<img <img
v-if="isMetadatumTypeTaxonomy"
:src=" :src="
facet.entity && facet.entity['header_image'] facet.entity.thumbnail && facet.entity.thumbnail[imageSize][0] && facet.entity.thumbnail[imageSize][0]
?
facet.entity['header_image']
:
`${tainacanBaseUrl}/assets/images/placeholder_square.png`
"
:alt="facet.label ? facet.label : $root.__('Thumbnail', 'tainacan')">
<img
v-if="isMetadatumTypeRelationship"
:src="
facet.entity.thumbnail && facet.entity.thumbnail['tainacan-medium'][0] && facet.entity.thumbnail['tainacan-medium'][0]
? ?
facet.entity.thumbnail['tainacan-medium'][0] facet.entity.thumbnail[imageSize][0]
: :
(facet.entity.thumbnail && facet.entity.thumbnail['thumbnail'][0] && facet.entity.thumbnail['thumbnail'][0] (facet.entity.thumbnail && facet.entity.thumbnail['thumbnail'][0] && facet.entity.thumbnail['thumbnail'][0]
? ?
@ -30,7 +19,7 @@
: :
`${tainacanBaseUrl}/assets/images/placeholder_square.png`) `${tainacanBaseUrl}/assets/images/placeholder_square.png`)
" "
:alt="facet.label ? facet.label : $root.__('Thumbnail', 'tainacan')"> :alt="facet.thumbnail_alt ? facet.thumbnail_alt : (facet.label ? facet.label : $root.__('Thumbnail', 'tainacan'))">
<div :class=" 'facet-label-and-count' + (itemsCountStyle === 'below' ? ' is-style-facet-label-and-count--below' : '')"> <div :class=" 'facet-label-and-count' + (itemsCountStyle === 'below' ? ' is-style-facet-label-and-count--below' : '')">
<span>{{ facet.label ? facet.label : '' }}</span> <span>{{ facet.label ? facet.label : '' }}</span>
<span <span
@ -143,7 +132,8 @@ export default {
childFacetsObject: Object, childFacetsObject: Object,
isMetadatumTypeTaxonomy: Boolean, isMetadatumTypeTaxonomy: Boolean,
isMetadatumTypeRelationship: Boolean, isMetadatumTypeRelationship: Boolean,
itemsCountStyle: String itemsCountStyle: String,
imageSize: String
}, },
computed:{ computed:{
facetId() { facetId() {

View File

@ -21,7 +21,8 @@ export default function({ attributes, className }) {
showSearchBar, showSearchBar,
linkTermFacetsToTermPage, linkTermFacetsToTermPage,
appendChildTerms, appendChildTerms,
itemsCountStyle itemsCountStyle,
imageSize
} = attributes; } = attributes;
// Gets attributes such as style, that are automatically added by the editor hook // Gets attributes such as style, that are automatically added by the editor hook
@ -39,6 +40,7 @@ export default function({ attributes, className }) {
show-items-count={ '' + showItemsCount } show-items-count={ '' + showItemsCount }
show-search-bar={ '' + showSearchBar } show-search-bar={ '' + showSearchBar }
show-load-more={ '' + showLoadMore } show-load-more={ '' + showLoadMore }
image-size={ imageSize }
append-child-terms={ (appendChildTerms === true ? 'true' : 'false') } append-child-terms={ (appendChildTerms === true ? 'true' : 'false') }
link-term-facets-to-term-page={ linkTermFacetsToTermPage === false ? 'false' : 'true' } link-term-facets-to-term-page={ linkTermFacetsToTermPage === false ? 'false' : 'true' }
layout={ layout } layout={ layout }

View File

@ -38,6 +38,7 @@ export default (element) => {
nameInsideImage: false, nameInsideImage: false,
linkTermFacetsToTermPage: true, linkTermFacetsToTermPage: true,
appendChildTerms: false, appendChildTerms: false,
imageSize: 'tainacan-medium',
layout: 'grid', layout: 'grid',
itemsCountStyle: 'default', itemsCountStyle: 'default',
cloudRate: 1, cloudRate: 1,
@ -67,6 +68,7 @@ export default (element) => {
itemsCountStyle: this.itemsCountStyle, itemsCountStyle: this.itemsCountStyle,
cloudRate: this.cloudRate, cloudRate: this.cloudRate,
gridMargin: this.gridMargin, gridMargin: this.gridMargin,
imageSize: this.imageSize,
linkTermFacetsToTermPage: this.linkTermFacetsToTermPage, linkTermFacetsToTermPage: this.linkTermFacetsToTermPage,
appendChildTerms: this.appendChildTerms, appendChildTerms: this.appendChildTerms,
maxFacetsNumber: this.maxFacetsNumber, maxFacetsNumber: this.maxFacetsNumber,
@ -95,6 +97,7 @@ export default (element) => {
this.itemsCountStyle = this.$el.attributes['items-count-style'] != undefined ? this.$el.attributes['items-count-style'].value : undefined; this.itemsCountStyle = this.$el.attributes['items-count-style'] != undefined ? this.$el.attributes['items-count-style'].value : undefined;
this.cloudRate = this.$el.attributes['cloud-rate'] != undefined ? Number(this.$el.attributes['cloud-rate'].value) : undefined; this.cloudRate = this.$el.attributes['cloud-rate'] != undefined ? Number(this.$el.attributes['cloud-rate'].value) : undefined;
this.gridMargin = this.$el.attributes['grid-margin'] != undefined ? Number(this.$el.attributes['grid-margin'].value) : undefined; this.gridMargin = this.$el.attributes['grid-margin'] != undefined ? Number(this.$el.attributes['grid-margin'].value) : undefined;
this.imageSize = this.$el.attributes['image-size'] != undefined ? this.$el.attributes['image-size'].value : 'tainacan-medium';
this.linkTermFacetsToTermPage = this.$el.attributes['link-term-facets-to-term-page'] != undefined ? this.$el.attributes['link-term-facets-to-term-page'].value == 'true' : true; this.linkTermFacetsToTermPage = this.$el.attributes['link-term-facets-to-term-page'] != undefined ? this.$el.attributes['link-term-facets-to-term-page'].value == 'true' : true;
this.maxFacetsNumber = this.$el.attributes['max-facets-number'] != undefined ? this.$el.attributes['max-facets-number'].value : undefined; this.maxFacetsNumber = this.$el.attributes['max-facets-number'] != undefined ? this.$el.attributes['max-facets-number'].value : undefined;
this.maxColumnsCount = this.$el.attributes['max-columns-count'] != undefined ? this.$el.attributes['max-columns-count'].value : 5; this.maxColumnsCount = this.$el.attributes['max-columns-count'] != undefined ? this.$el.attributes['max-columns-count'].value : 5;

View File

@ -90,6 +90,7 @@
:child-facets-object="childFacetsObject" :child-facets-object="childFacetsObject"
:append-child-terms="appendChildTerms" :append-child-terms="appendChildTerms"
:facet="facet" :facet="facet"
:image-size="imageSize"
:cloud-rate="cloudRate" :cloud-rate="cloudRate"
:items-count-style="itemsCountStyle" :items-count-style="itemsCountStyle"
:tainacan-base-url="tainacanBaseUrl" :tainacan-base-url="tainacanBaseUrl"
@ -121,6 +122,7 @@
:child-facets-object="childFacetsObject" :child-facets-object="childFacetsObject"
:append-child-terms="appendChildTerms" :append-child-terms="appendChildTerms"
:facet="facet" :facet="facet"
:image-size="imageSize"
:cloud-rate="cloudRate" :cloud-rate="cloudRate"
:items-count-style="itemsCountStyle" :items-count-style="itemsCountStyle"
:tainacan-base-url="tainacanBaseUrl" :tainacan-base-url="tainacanBaseUrl"
@ -194,7 +196,8 @@ export default {
tainacanBaseUrl: String, tainacanBaseUrl: String,
tainacanSiteUrl: String, tainacanSiteUrl: String,
className: String, className: String,
customStyle: String customStyle: String,
imageSize: String
}, },
data() { data() {
return { return {
@ -211,6 +214,7 @@ export default {
tainacanAxios: undefined, tainacanAxios: undefined,
offset: undefined, offset: undefined,
totalFacets: 0, totalFacets: 0,
apiRoot: '',
lastTerm: undefined, lastTerm: undefined,
localParentTermId: '' localParentTermId: ''
} }
@ -224,7 +228,9 @@ export default {
} }
}, },
created() { created() {
this.tainacanAxios = axios.create({ baseURL: this.tainacanApiRoot }); this.apiRoot = (tainacan_blocks && tainacan_blocks.root && !this.tainacanApiRoot) ? tainacan_blocks.root : this.tainacanApiRoot;
this.tainacanAxios = axios.create({ baseURL: this.apiRoot });
if (tainacan_blocks && tainacan_blocks.nonce) if (tainacan_blocks && tainacan_blocks.nonce)
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;

View File

@ -5,7 +5,7 @@
"apiVersion": 2, "apiVersion": 2,
"category": "tainacan-blocks", "category": "tainacan-blocks",
"keywords": [ "item", "location", "geographic", "coordinates", "metadatum", "field", "value" ], "keywords": [ "item", "location", "geographic", "coordinates", "metadatum", "field", "value" ],
"description": "A single item geographic metadatum, containing location information.", "description": "A single item geocoordinate metadatum, containing location information.",
"textdomain": "tainacan", "textdomain": "tainacan",
"parent": [], "parent": [],
"example": { "example": {

View File

@ -286,7 +286,7 @@
li.swiper-slide { li.swiper-slide {
text-align: center; text-align: center;
vertical-align: top; vertical-align: top;
word-break: break-all; word-break: break-word;
font-size: 0.875em; font-size: 0.875em;
max-width: calc(var(--tainacan-media-thumbs-carousel-item-size, 136px) + 17px); max-width: calc(var(--tainacan-media-thumbs-carousel-item-size, 136px) + 17px);
@ -328,15 +328,18 @@
font-size: 1em; font-size: 1em;
color: var(--tainacan-media-metadata-color, #454647); color: var(--tainacan-media-metadata-color, #454647);
opacity: 0.75; opacity: 0.75;
word-break: break-word;
} }
.swiper-slide-metadata__caption { .swiper-slide-metadata__caption {
font-size: 0.9375em; font-size: 0.9375em;
color: var(--tainacan-media-metadata-color, #454647); color: var(--tainacan-media-metadata-color, #454647);
word-break: break-word;
} }
.swiper-slide-metadata__caption { .swiper-slide-metadata__caption {
font-size: 0.875em; font-size: 0.875em;
color: var(---tainacan-media-metadata-color, #454647); color: var(---tainacan-media-metadata-color, #454647);
opacity: 0.85; opacity: 0.85;
word-break: break-word;
} }
.swiper-slide-metadata { .swiper-slide-metadata {
text-align: center; text-align: center;

View File

@ -36,6 +36,7 @@
<!-- Parent -------------- --> <!-- Parent -------------- -->
<b-field <b-field
v-if="isHierarchical"
:addons="false" :addons="false"
:type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''" :type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
:message="formErrors.parent ? formErrors : formErrors.repeated"> :message="formErrors.parent ? formErrors : formErrors.repeated">
@ -71,7 +72,7 @@
class="media-left"> class="media-left">
<img <img
width="28" width="28"
:src="props.option.header_image"> :src="props.option.thumbnail && props.option.thumbnail['tainacan-small'] && props.option.thumbnail['tainacan-small'][0] ? props.option.thumbnail['tainacan-small'][0] : props.option.header_image">
</div> </div>
<div class="media-content"> <div class="media-content">
{{ props.option.name }} {{ props.option.name }}
@ -83,19 +84,23 @@
</b-field> </b-field>
<!-- Submit buttons -------------- --> <!-- Submit buttons -------------- -->
<div class="field is-grouped form-submit"> <div
<div class="control"> class="wp-block-buttons form-submit"
style="gap: 1rem;">
<div
class="wp-block-button is-style-outline"
style="margin-right: auto;">
<button <button
type="button" type="button"
class="button is-outlined" class="wp-block-button__link wp-element-button"
@click.prevent="cancelEdition()" @click.prevent="cancelEdition()"
slot="trigger"> slot="trigger">
{{ $i18n.get('cancel') }} {{ $i18n.get('cancel') }}
</button> </button>
</div> </div>
<div class="control"> <div class="wp-block-button">
<button <button
class="button is-success" class="wp-block-button__link wp-element-button"
type="submit"> type="submit">
{{ $i18n.get('label_create_and_select') }} {{ $i18n.get('label_create_and_select') }}
</button> </button>
@ -107,14 +112,15 @@
<script> <script>
import { formHooks } from "../../../../../admin/js/mixins"; import { formHooks } from "../../../../../admin/js/mixins";
import { mapActions, mapGetters } from 'vuex'; import { mapActions } from 'vuex';
export default { export default {
name: 'TermEditionForm', name: 'TermEditionForm',
mixins: [ formHooks ], mixins: [ formHooks ],
props: { props: {
originalForm: Object, originalForm: Object,
taxonomyId: '' taxonomyId: '',
isHierarchical: Boolean
}, },
data() { data() {
return { return {
@ -157,13 +163,10 @@
methods: { methods: {
...mapActions('taxonomy', [ ...mapActions('taxonomy', [
'sendChildTerm', 'sendChildTerm',
'updateChildTerm', 'updateTerm',
'fetchParentName', 'fetchParentName',
'fetchPossibleParentTerms' 'fetchPossibleParentTerms'
]), ]),
...mapGetters('taxonomy', [
'getTerms'
]),
saveEdition(term) { saveEdition(term) {
if (term.id === 'new') { if (term.id === 'new') {
@ -260,7 +263,7 @@
border-left: 1px solid var(--tainacan-input-border-color, #dbdbdb); border-left: 1px solid var(--tainacan-input-border-color, #dbdbdb);
border-bottom: 1px solid var(--tainacan-input-border-color, #dbdbdb); border-bottom: 1px solid var(--tainacan-input-border-color, #dbdbdb);
column-count: 2; column-count: 2;
@media screen and (max-width: 1024px) { @media screen and (max-width: 1024px) {
column-count: 1; column-count: 1;
} }
@ -269,9 +272,10 @@
break-inside: avoid; break-inside: avoid;
} }
.form-submit { .form-submit {
padding-top: 0; padding-top: 1rem;
padding-bottom: 0; padding-bottom: 0;
column-span: all; column-span: all;
display: flex;
} }
} }
} }

View File

@ -499,6 +499,9 @@
v-if="enabledMetadata[index] == 'true'" v-if="enabledMetadata[index] == 'true'"
:item-metadatum="itemMetadatum" :item-metadatum="itemMetadatum"
:hide-collapses="hideCollapses" :hide-collapses="hideCollapses"
:hide-metadata-types="hideMetadataTypes"
:hide-help-buttons="hideHelpButtons"
:help-info-bellow-label="helpInfoBellowLabel"
:is-collapsed="metadataCollapses[index]" :is-collapsed="metadataCollapses[index]"
@changeCollapse="onChangeCollapse($event, index)"/> @changeCollapse="onChangeCollapse($event, index)"/>
@ -609,6 +612,7 @@
style="margin-right: auto;"> style="margin-right: auto;">
<button <button
@click="onDiscard()" @click="onDiscard()"
id="tainacan-item-submission-block-button--cancel"
type="button" type="button"
class="wp-block-button__link wp-element-button"> class="wp-block-button__link wp-element-button">
{{ $i18n.get('cancel') }} {{ $i18n.get('cancel') }}
@ -619,6 +623,7 @@
class="wp-block-button"> class="wp-block-button">
<button <button
@click="onPreviousStep()" @click="onPreviousStep()"
id="tainacan-item-submission-block-button--previous"
type="button" type="button"
class="wp-block-button__link wp-element-button"> class="wp-block-button__link wp-element-button">
{{ $i18n.get('previous') }} {{ $i18n.get('previous') }}
@ -629,6 +634,7 @@
class="wp-block-button"> class="wp-block-button">
<button <button
@click="onNextStep()" @click="onNextStep()"
id="tainacan-item-submission-block-button--next"
type="button" type="button"
class="wp-block-button__link wp-element-button"> class="wp-block-button__link wp-element-button">
{{ $i18n.get('next') }} {{ $i18n.get('next') }}
@ -639,6 +645,7 @@
class="wp-block-button"> class="wp-block-button">
<button <button
:disabled="showTermsAgreementCheckbox && !userHasAgreedToTerms" :disabled="showTermsAgreementCheckbox && !userHasAgreedToTerms"
id="tainacan-item-submission-block-button--submit"
@click="onSubmit()" @click="onSubmit()"
type="button" type="button"
class="wp-block-button__link wp-element-button"> class="wp-block-button__link wp-element-button">
@ -880,7 +887,7 @@ export default {
}, },
}, },
created() { created() {
// Puts loading on form // Puts loading on form
this.isLoading = true; this.isLoading = true;
@ -953,7 +960,6 @@ export default {
}); });
}, },
mounted() { mounted() {
// Checks if only one type of document is allowed. In this case we preset document type // Checks if only one type of document is allowed. In this case we preset document type
if (!this.hideFileModalButton && this.hideTextModalButton && this.hideLinkModalButton) if (!this.hideFileModalButton && this.hideTextModalButton && this.hideLinkModalButton)
this.form.document_type = 'attachment'; this.form.document_type = 'attachment';

View File

@ -135,8 +135,8 @@ export default class TermsModal extends React.Component {
id: term.id, id: term.id,
url: term.url, url: term.url,
header_image: [{ header_image: [{
src: term.header_image, src: term.thumbnail && term.thumbnail['tainacan-medium'] && term.thumbnail['tainacan-medium'][0] ? term.thumbnail['tainacan-medium'][0] : term.header_image,
alt: term.name alt: term.thumbnail_alt ? term.thumbnail_alt : term.name
}] }]
})); }));
@ -176,8 +176,8 @@ export default class TermsModal extends React.Component {
id: term.id, id: term.id,
url: term.url, url: term.url,
header_image: [{ header_image: [{
src: term.header_image, src: term.thumbnail && term.thumbnail['tainacan-medium'] && term.thumbnail['tainacan-medium'][0] ? term.thumbnail['tainacan-medium'][0] : term.header_image,
alt: term.name alt: term.thumbnail_alt ? term.thumbnail_alt : term.name
}] }]
}); });
} }

View File

@ -153,7 +153,7 @@ function tainacan_blocks_register_block($block_slug, $options = []) {
wp_register_style( wp_register_style(
$block_slug, $block_slug,
$TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-' . $block_slug . '.css', $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-' . $block_slug . '.css',
array('tainacan-blocks-common-editor-styles'), array(),
$TAINACAN_VERSION $TAINACAN_VERSION
); );
$register_params['style'] = $block_slug; $register_params['style'] = $block_slug;
@ -215,6 +215,7 @@ function tainacan_blocks_get_common_editor_styles() {
*/ */
function tainacan_blocks_get_plugin_js_settings(){ function tainacan_blocks_get_plugin_js_settings(){
global $TAINACAN_BASE_URL; global $TAINACAN_BASE_URL;
global $TAINACAN_API_MAX_ITEMS_PER_PAGE;
global $wp_version; global $wp_version;
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance(); $Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
@ -229,6 +230,7 @@ function tainacan_blocks_get_plugin_js_settings(){
'root' => esc_url_raw( rest_url() ) . 'tainacan/v2', 'root' => esc_url_raw( rest_url() ) . 'tainacan/v2',
'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : false, 'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : false,
'base_url' => $TAINACAN_BASE_URL, 'base_url' => $TAINACAN_BASE_URL,
'api_max_items_per_page' => $TAINACAN_API_MAX_ITEMS_PER_PAGE,
'admin_url' => admin_url(), 'admin_url' => admin_url(),
'site_url' => site_url(), 'site_url' => site_url(),
'theme_items_list_url' => esc_url_raw( get_site_url() ) . '/' . \Tainacan\Theme_Helper::get_instance()->get_items_list_slug(), 'theme_items_list_url' => esc_url_raw( get_site_url() ) . '/' . \Tainacan\Theme_Helper::get_instance()->get_items_list_slug(),
@ -310,7 +312,7 @@ function tainacan_blocks_get_variations_script() {
wp_enqueue_script( wp_enqueue_script(
'tainacan-blocks-query-variations', 'tainacan-blocks-query-variations',
$TAINACAN_BASE_URL . '/assets/js/tainacan_blocks_query_variations.js', $TAINACAN_BASE_URL . '/assets/js/tainacan_blocks_query_variations.js',
array('wp-blocks', 'wp-components'), array('wp-blocks', 'wp-components', 'wp-i18n'),
$TAINACAN_VERSION $TAINACAN_VERSION
); );

View File

@ -1,7 +1,9 @@
const { registerBlockVariation } = wp.blocks;
const { __ } = wp.i18n;
import itemsIcon from '../blocks/items-list/icon'; import itemsIcon from '../blocks/items-list/icon';
import collectionsIcon from '../blocks/collections-list/icon'; import collectionsIcon from '../blocks/collections-list/icon';
import taxonomiesIcon from '../blocks/terms-list/icon';
const { registerBlockVariation } = wp.blocks;
const { __ } = wp.i18n;
/** /**
* Adds Tainacan Collections as a query loop variation * Adds Tainacan Collections as a query loop variation
@ -91,3 +93,46 @@ Object.keys(POST_TYPES).forEach((postType) => {
] ]
} ); } );
}); });
/**
* Adds Tainacan Taxonomies as a query loop variation
*/
registerBlockVariation( 'core/query', {
name: 'tainacan-taxonomies',
title: __( 'Tainacan taxonomies', 'tainacan'),
icon: taxonomiesIcon,
category: 'tainacan-blocks-variations',
description: __('Displays a list of Tainacan taxonomies', 'tainacan'),
isActive: ( { namespace, query } ) => {
return (
namespace === 'tainacan-taxonomy'
&& query.postType === 'tainacan-taxonomy'
);
},
attributes: {
namespace: 'tainacan-taxonomy',
query: {
postType: 'tainacan-taxonomy',
perPage: 12,
offset: 0
},
align: 'wide',
displayLayout: {
type: 'flex',
columns: 4
}
},
allowedControls: [ 'inherit', 'order', 'search' ],
innerBlocks: [
[
'core/post-template',
{},
[
// [ 'core/post-featured-image' ],
[ 'core/post-title' ]
],
]
]
} );

View File

@ -241,7 +241,8 @@ return apply_filters( 'tainacan-i18n', [
'label_collection_filters' => __( 'Collection Filters', 'tainacan' ), 'label_collection_filters' => __( 'Collection Filters', 'tainacan' ),
'label_parent_term' => __( 'Parent Term', 'tainacan' ), 'label_parent_term' => __( 'Parent Term', 'tainacan' ),
'label_children_terms' => __( 'children terms', 'tainacan' ), 'label_children_terms' => __( 'children terms', 'tainacan' ),
'label_new_term' => __( 'Create New Term', 'tainacan' ), 'label_new_term' => __( 'New Term', 'tainacan' ),
'label_create_new_term' => __( 'Create New Term', 'tainacan' ),
'label_create_and_select' => __( 'Create and Select', 'tainacan' ), 'label_create_and_select' => __( 'Create and Select', 'tainacan' ),
'label_new_child' => __( 'New Child', 'tainacan' ), 'label_new_child' => __( 'New Child', 'tainacan' ),
'label_taxonomy_terms' => __( 'Taxonomy Terms', 'tainacan' ), 'label_taxonomy_terms' => __( 'Taxonomy Terms', 'tainacan' ),
@ -311,6 +312,8 @@ return apply_filters( 'tainacan-i18n', [
'label_select_all_items_page' => __( 'Select all items on page', 'tainacan' ), 'label_select_all_items_page' => __( 'Select all items on page', 'tainacan' ),
'label_select_all_taxonomies_page' => __( 'Select all taxonomies on page', 'tainacan' ), 'label_select_all_taxonomies_page' => __( 'Select all taxonomies on page', 'tainacan' ),
'label_select_all_processes_page' => __( 'Select all processes on page', 'tainacan' ), 'label_select_all_processes_page' => __( 'Select all processes on page', 'tainacan' ),
'label_select_all_terms' => __( 'Select all taxonomy terms', 'tainacan' ),
'label_all_terms_selected' => __( 'All terms selected', 'tainacan' ),
'label_add_or_update_attachments' => __( 'Add or update attachments', 'tainacan' ), 'label_add_or_update_attachments' => __( 'Add or update attachments', 'tainacan' ),
'label_blank_collection' => __( 'Blank collection', 'tainacan' ), 'label_blank_collection' => __( 'Blank collection', 'tainacan' ),
/* translators: the metadata scheme https://dublincore.org/ */ /* translators: the metadata scheme https://dublincore.org/ */
@ -361,6 +364,7 @@ return apply_filters( 'tainacan-i18n', [
'label_remove_value' => __( 'Remove value', 'tainacan' ), 'label_remove_value' => __( 'Remove value', 'tainacan' ),
'label_create_new_page' => __( 'Create new page', 'tainacan' ), 'label_create_new_page' => __( 'Create new page', 'tainacan' ),
'label_total_items' => __( 'Total items', 'tainacan' ), 'label_total_items' => __( 'Total items', 'tainacan' ),
'label_total_terms' => __( 'Total terms', 'tainacan' ),
'label_view_all' => __( 'View all', 'tainacan' ), 'label_view_all' => __( 'View all', 'tainacan' ),
'label_until' => __( 'until', 'tainacan' ), 'label_until' => __( 'until', 'tainacan' ),
'label_visibility' => __( 'Visibility', 'tainacan' ), 'label_visibility' => __( 'Visibility', 'tainacan' ),
@ -395,11 +399,12 @@ return apply_filters( 'tainacan-i18n', [
'label_delete_process' => __( 'Delete process', 'tainacan' ), 'label_delete_process' => __( 'Delete process', 'tainacan' ),
'label_process_failed' => __( 'Process failed', 'tainacan' ), 'label_process_failed' => __( 'Process failed', 'tainacan' ),
'label_max_options_to_show' => __( 'Max options to show', 'tainacan' ), 'label_max_options_to_show' => __( 'Max options to show', 'tainacan' ),
'label_unnamed_process' => __( 'Unnamed process', 'tainacan' ), 'label_unnamed_process' => __( 'Unnamed process', 'tainacan' ),
'loading_processes' => __( 'Loading processes', 'tainacan' ), 'loading_processes' => __( 'Loading processes', 'tainacan' ),
'label_semantic_uri' => __( 'Semantic Uri', 'tainacan' ), 'label_semantic_uri' => __( 'Semantic Uri', 'tainacan' ),
'label_view_collection_on_website' => __( 'View collection on website', 'tainacan' ), 'label_view_collection_on_website' => __( 'View collection on website', 'tainacan' ),
'label_view_collections_on_website' => __( 'View collections on website', 'tainacan' ), 'label_view_collections_on_website' => __( 'View collections on website', 'tainacan' ),
'label_view_taxonomies_on_website' => __( 'View taxonomies on website', 'tainacan' ),
'label_view_more' => __( 'View more', 'tainacan' ), 'label_view_more' => __( 'View more', 'tainacan' ),
'label_log_file' => __( 'Log file', 'tainacan' ), 'label_log_file' => __( 'Log file', 'tainacan' ),
'label_error_log_file' => __( 'Error Log file', 'tainacan' ), 'label_error_log_file' => __( 'Error Log file', 'tainacan' ),
@ -459,6 +464,8 @@ return apply_filters( 'tainacan-i18n', [
'label_urls_for_item_page' => __( 'URLs for Item Page', 'tainacan' ), 'label_urls_for_item_page' => __( 'URLs for Item Page', 'tainacan' ),
'label_item_page_on_website' => __( 'Item page on website', 'tainacan' ), 'label_item_page_on_website' => __( 'Item page on website', 'tainacan' ),
'label_items_list_on_website' => __( 'Items list on website', 'tainacan' ), 'label_items_list_on_website' => __( 'Items list on website', 'tainacan' ),
'label_taxonomy_page_on_website' => __( 'Taxonomy page on website', 'tainacan' ),
'label_term_page_on_website' => __( 'Term page on website', 'tainacan' ),
'label_copy_link_url' => __( 'Copy link URL', 'tainacan' ), 'label_copy_link_url' => __( 'Copy link URL', 'tainacan' ),
'label_open_externally' => __( 'Open externally', 'tainacan' ), 'label_open_externally' => __( 'Open externally', 'tainacan' ),
'label_no_output_info' => __( 'No output info', 'tainacan' ), 'label_no_output_info' => __( 'No output info', 'tainacan' ),
@ -666,8 +673,30 @@ return apply_filters( 'tainacan-i18n', [
'label_show_item_location_on_map' => __( 'Show item location on map', 'tainacan' ), 'label_show_item_location_on_map' => __( 'Show item location on map', 'tainacan' ),
/* translators: This appears before a select where you choose possible geocoorinate metadata */ /* translators: This appears before a select where you choose possible geocoorinate metadata */
'label_showing_locations_for' => __( 'Showing locations for:', 'tainacan' ), 'label_showing_locations_for' => __( 'Showing locations for:', 'tainacan' ),
'label_one_selected_location' => __( 'One selected location', 'tainacan' ), 'label_one_selected_location' => __( 'One location selected', 'tainacan' ),
'label_%s_selected_locations' => __( '%s selected locations', 'tainacan' ), 'label_%s_selected_locations' => __( '%s locations selected', 'tainacan' ),
'label_update_parent' => __( 'Change parent term', 'tainacan' ),
'label_select_child_terms_long' => __( 'Select all child terms', 'tainacan' ),
/* translators: This relates to taxonomy terms selections. It is a shorter version of "select all child terms" */
'label_select_child_terms_short' => __( 'All children', 'tainacan' ),
'label_select_root_terms_long' => __( 'Select all root terms', 'tainacan' ),
/* translators: This relates to taxonomy terms selections. It is a shorter version of "select all root terms" */
'label_select_root_terms_short' => __( 'All root terms', 'tainacan' ),
'label_all_root_terms_selected' => __( 'All root terms selected', 'tainacan' ),
'label_terms_child_of_%s_selected' => __( 'Terms child of %s selected', 'tainacan' ),
'label_remove_selected_term' => __( 'Remove only the selected term', 'tainacan' ),
'label_remove_term_and_descendants' => __( 'Remove term and its descendants', 'tainacan' ),
'label_remove_selected_terms' => __( 'Remove only selected terms', 'tainacan' ),
'label_remove_terms_and_descendants' => __( 'Remove terms and their descendants', 'tainacan' ),
'label_%s_selected_terms' => __( '%s terms selected', 'tainacan' ),
'label_one_selected_term' => __( 'One term selected', 'tainacan' ),
'label_no_parent_root_term' => __( 'No parent (set as root term)', 'tainacan' ),
/* translators: This relates to terms that are in use by some item via a taxonomy. */
'label_used_by_items' => __( 'In use by some item', 'tainacan' ),
'label_multiple_terms_insertion' => __( 'Multiple terms insertion', 'tainacan' ),
'label_multiple_terms' => __( 'Multiple terms', 'tainacan' ),
'label_multiple' => __( 'Multiple', 'tainacan' ),
'label_separator' => __( 'Separator', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders // Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ), 'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -748,6 +777,7 @@ return apply_filters( 'tainacan-i18n', [
'instruction_type_geocoordinate' => __( 'Type a geo coordinate in the form of lat,lng', 'tainacan' ), 'instruction_type_geocoordinate' => __( 'Type a geo coordinate in the form of lat,lng', 'tainacan' ),
'instruction_click_to_add_a_point' => __( 'Drag to reposition or click to insert a marker', 'tainacan' ), 'instruction_click_to_add_a_point' => __( 'Drag to reposition or click to insert a marker', 'tainacan' ),
'instruction_select_geocoordinate_metadatum' => __( 'Select a geocoordinate metadatum', 'tainacan' ), 'instruction_select_geocoordinate_metadatum' => __( 'Select a geocoordinate metadatum', 'tainacan' ),
'instruction_multiple_terms_insertion' => __( 'Type or paste here a list of names using a separator to create multiple terms at once.', 'tainacan' ),
// Info. Other feedback to user. // Info. Other feedback to user.
'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ), 'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ),
@ -825,7 +855,6 @@ return apply_filters( 'tainacan-i18n', [
'info_warning_selected_collections_delete' => __( 'Do you really want to permanently delete the selected collections?', 'tainacan' ), 'info_warning_selected_collections_delete' => __( 'Do you really want to permanently delete the selected collections?', 'tainacan' ),
'info_warning_selected_collections_trash' => __( 'Do you really want to trash the selected collections?', 'tainacan' ), 'info_warning_selected_collections_trash' => __( 'Do you really want to trash the selected collections?', 'tainacan' ),
'info_warning_selected_items_delete' => __( 'Do you really want to permanently delete the selected items?', 'tainacan' ), 'info_warning_selected_items_delete' => __( 'Do you really want to permanently delete the selected items?', 'tainacan' ),
'info_warning_selected_term_delete' => __( 'Do you really want to permanently delete the selected term?', 'tainacan' ),
'info_warning_selected_items_trash' => __( 'Do you really want to trash the selected items?', 'tainacan' ), 'info_warning_selected_items_trash' => __( 'Do you really want to trash the selected items?', 'tainacan' ),
'info_warning_selected_taxonomies_delete' => __( 'Do you really want to delete the selected taxonomies?', 'tainacan' ), 'info_warning_selected_taxonomies_delete' => __( 'Do you really want to delete the selected taxonomies?', 'tainacan' ),
'info_warning_collection_related' => __( 'The metadata Collection related is required', 'tainacan' ), 'info_warning_collection_related' => __( 'The metadata Collection related is required', 'tainacan' ),
@ -859,7 +888,6 @@ return apply_filters( 'tainacan-i18n', [
'info_no_description_provided' => __( 'No description provided.', 'tainacan' ), 'info_no_description_provided' => __( 'No description provided.', 'tainacan' ),
'info_warning_taxonomy_not_saved' => __( 'Are you sure? The taxonomy is not saved, changes will be lost.', 'tainacan' ), 'info_warning_taxonomy_not_saved' => __( 'Are you sure? The taxonomy is not saved, changes will be lost.', 'tainacan' ),
'info_warning_terms_not_saved' => __( 'Are you sure? There are terms not saved, changes will be lost.', 'tainacan' ), 'info_warning_terms_not_saved' => __( 'Are you sure? There are terms not saved, changes will be lost.', 'tainacan' ),
'info_warning_orphan_terms' => __( 'Are you sure? This term is parent of other terms. These will be converted to root terms.', 'tainacan' ),
'info_no_activities' => __( 'No activities found.', 'tainacan' ), 'info_no_activities' => __( 'No activities found.', 'tainacan' ),
'info_logs_before' => __( 'Before', 'tainacan' ), 'info_logs_before' => __( 'Before', 'tainacan' ),
'info_logs_after' => __( 'After', 'tainacan' ), 'info_logs_after' => __( 'After', 'tainacan' ),
@ -961,6 +989,8 @@ return apply_filters( 'tainacan-i18n', [
'info_no_value_compound_metadata' => __( 'No value has been added to this compound metadata.', 'tainacan' ), 'info_no_value_compound_metadata' => __( 'No value has been added to this compound metadata.', 'tainacan' ),
/* translators: Refers to the hierarchy of compound metadata. Like in 'Metadata X (child of Metadata Y) */ /* translators: Refers to the hierarchy of compound metadata. Like in 'Metadata X (child of Metadata Y) */
'info_child_of' => __( 'child of', 'tainacan' ), 'info_child_of' => __( 'child of', 'tainacan' ),
/* translators: Refers to the hierarchy of taxonomy terms. Like in 'Macro (child of Photography) */
'info_children_of_%s' => __( 'Children of %s', 'tainacan' ),
'info_slides_help_introduction' => __( 'Use the following commands to navigate through the items', 'tainacan' ), 'info_slides_help_introduction' => __( 'Use the following commands to navigate through the items', 'tainacan' ),
'info_slides_previous_item' => __( 'to go to the previous item', 'tainacan' ), 'info_slides_previous_item' => __( 'to go to the previous item', 'tainacan' ),
'info_slides_next_item' => __( 'to go to the next item', 'tainacan' ), 'info_slides_next_item' => __( 'to go to the next item', 'tainacan' ),
@ -1006,6 +1036,14 @@ return apply_filters( 'tainacan-i18n', [
'info_non_located_item' => __( 'This item does not have any location based on this metadata.', 'tainacan' ), 'info_non_located_item' => __( 'This item does not have any location based on this metadata.', 'tainacan' ),
'info_metadata_section_hidden_conditional' => __( 'Section disabled due to a conditional metadatum value.', 'tainacan' ), 'info_metadata_section_hidden_conditional' => __( 'Section disabled due to a conditional metadatum value.', 'tainacan' ),
'info_create_select_metadatum_for_conditional_section' => __( 'For configuring conditional sections, first create one select type metadatum to use its values as rules for displaing this section. The metadatum should be inside another metadatum section.', 'tainacan' ), 'info_create_select_metadatum_for_conditional_section' => __( 'For configuring conditional sections, first create one select type metadatum to use its values as rules for displaing this section. The metadatum should be inside another metadatum section.', 'tainacan' ),
'info_taxonomy_terms_list' => __( 'The list of terms that are managed by this taxonomy. They will be used as values for the taxonomy metadata.', 'tainacan' ),
'info_no_child_term_of_%s_found' => __( 'No child term of %s was found.', 'tainacan' ),
'info_warning_term_with_child' => __( 'This term has child terms. Per default, if you remove a parent term, its child terms will be moved one level up in the hierarchy.', 'tainacan' ),
'info_warning_selected_term_delete' => __( 'Do you really want to permanently delete the selected term?', 'tainacan' ),
'info_warning_some_terms_with_child' => __( 'When removing multiple terms at once, it is possible that some of the terms contain child terms. Per default, if you remove a parent term, its child terms will be moved one level up in the hierarchy.', 'tainacan' ),
'info_%s_terms_created' => __( '%s terms created with success.', 'tainacan' ),
'info_terms_creation_failed_due_to_value_%s' => __( 'Terms creation failed due to value: %s.', 'tainacan' ),
'info_terms_creation_failed_due_to_values_%s' => __( 'Terms creation failed due to values: %s.', 'tainacan' ),
/* Activity actions */ /* Activity actions */
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'), 'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),