Merge branch 'release/0.8'

This commit is contained in:
leogermani 2019-03-28 15:23:06 -03:00
commit 9e3dcfff3e
187 changed files with 22949 additions and 4369 deletions

231
docs/exporter-flow.md Normal file
View File

@ -0,0 +1,231 @@
# The Exporter flow
This page describes how Tainacan exporters work and is a reference to write your own exporter.
This documentation is still in construction. A very effective way to learn more on how to build an exporter is to look at the source code of the CSV Exporter class that is included in the tainacan package.
## Introduction
Exporters can export items from a single collection, or even create a bunch of collections, taxonomies and items all at once.
In order to create an Exporter, you have to extend the `\Tainacan\Exporter` Class and register it using the global `Tainacan\Export_Handler->register_exporter()` method.
This method takes an array as argument, with the defintion of your exporter. These are the expected attributes.
```
@type string $name The name of the exporter. e.g. 'Example exporter'
@type string $slug A unique slug for the exporter. e.g. 'example-exporter'
@type string $description The exporter description. e.g. 'This is an example exporter description'
@type string $class_name The Exporter Class. e.g. '\Tainacan\Exporter\Test_Exporter'
@type bool $manual_mapping Wether Tainacan must present the user with an interface to manually choose
a mapping standard. This will allow them to export the items mapped to a
chosen standard instead of in its original form.
The exporter will also be able to inform what mappers it supports. See `set_accepted_mapping_methods`
and `accept_no_mapping` below.
Note that this will only work when exporting items from one single collection.
@type bool $manual_collection Wether Tainacan will let the user choose the source collection.
If set to true, Tainacan give the user a select box from where he/she will Choose
one (and only one) Collection to export items from.
Otherwise, the child exporter class must choose the collections somehow
(it could be in its options form) and add them to the collections property using `add_collection()`
```
Note that depending on the value of `manual_mapping` and `manual_collection` you will have to implement some methods in your exporter class.
## Initializing a new exporter
When the user starts a new export process, he/she first choose which export to use.
Once the Exporter is chosen, the first thing that happens is the creation of a new instance of the chosen Exporter. This fires the `__construct()` method.
## Choose a collection (if `manual_collection` is true)
After choosing the exporter, user will be given the choice to choose the source collection.
If called from inside a collection, this step is skipped and the current collection is set as source.
## Set options
Now its time to set the exporter options. Each exporter may have its own set of options, that will be used during the export process. It could be anything, from the delimiter character in a CSV exporter, to an API key for a exporter that sends data to an external API.
exporter classes should declare the default values for its options in the `__construct()` method, by calling `set_default_options()`.
```
namespace Tainacan\exporter;
class Myexporter extends Exporter {
function __construct() {
parent::construct();
$this->set_default_options(['
'foo' => 'bar'
']);
}
}
```
The exporter classes must also implement the `options_form` method, in which it will echo the form that the user will interact to set the options.
```
function options_form() {
$form = '<div class="field">';
$form .= '<label class="label">' . __('My exporter Option 1', 'tainacan') . '</label>';
$form .= '<div class="control">';
$form .= '<input type="text" class="input" name="my_exporter_option_1" value="' . $this->get_option('my_exporter_option_1') . '" />';
$form .= '</div>';
$form .= '</div>';
return $form;
}
```
## Accepting mappers
If you set `manual_mapping` as true and want to give users the ability to export a mapped version of their collections, you can also
define which mappers you accept.
```
public function __construct($attributes = array()) {
parent::__construct($attributes);
$this->set_accepted_mapping_methods('any'); // set all method to mapping
$this->accept_no_mapping = true;
}
```
`$this->set_accepted_mapping_methods()` lets you do that. If you set it to "any", all mappers will be available. If you set it to "list", you can then pass a second argument with the list of mappers you want to be available for the users.
```
public function __construct($attributes = array()) {
parent::__construct($attributes);
$this->set_accepted_mapping_methods('list', [ "dublin-core" ]); // set specific list of methods to mapping
}
```
Finally, `$this->accept_no_mapping = true;` informs that you also allow users to export items in their original form, without any mapping. In other words, to choose a Mapper is not mandatory if this is set to true.
## exporter steps
An exporter may have several steps, that will handle different parts of the process. Each step will be handled by a different callback in the exporter class.
First, lets have a look at a simple CSV exporter, that only have one step, in which it exports the items from the source collection into a CSV file. After that we will have a look on how to create custom steps.
### Simple exporter - One step that exports items
By default, exporters must implement 3 methods: `output_header`, `output_footer` and `process_item`.
`output_header` and `output_footer` are invoked at the beginning and end of each collection being exported. It can be useful, for example, to write the header and footer of a csv or xml file.
Inside this methods you may do whatever you want. It could be a POST to an API or to write a new file (see handling files below).
The `process_item` method will be invoked for every item being exported. Tainacan will automatically loop through the collections in the queue, fetch and prepare the items, and then send them, one at a time, to this method. (see adding collections below).
This method gets two parameters, the `$item` object (instance of \Tainacan\Entities\Item), and its `$metadata`, with an array of '\Tainacan\Entities\Item_Metadata_Entity' objects.
Note that, in this method, you dont need to bother about mapping. If a mapper was chosen by the user, you will receive this array of metadata already mapped, which means they will be only the ones defined in the mapper. (Note that, if a collection fail to map one of its metadata to a metadata expected by the chosen mapper, they will be empy elements in this array).
Now you can loop through the metadata and access any propery you want from the item to do whatever you like. In the case of the CSV exporter, it will add one line to the CSV file.
If you need to access the Mapper object, with everything about the the chosen mapper standard, you can do so by calling `$this->get_current_mapper()`. If a object is not returned, it means no mapper was selected by the user.
#### Adding collections
If your exporter does not use the `manual_collection` option, you might want to programatically add collections to be exported to the queue.
To add or remove a collection from the queue, use the `add_collection()` and `remove_collection()` methods passing the collection definition.
The collection definition is an array with their IDs and the total number of items to be exported.
Example of the structure of this propery for one collection:
```
[
'id' => 12,
'total_items' => 1234,
]
```
#### Handling files
Your export may generate one or more files, that will be downloaded by the user as a package at the end.
To create and write contents to a file, use the `append_to_file()` method.
It takes 2 arguments: `$key` and `$data`. `$key` is the file identifier and will serve as the filename, prepended with the ID of the process. If a file with this key does not exist yet, it will be created. `$data` is the content to be appended to the file.
Dont forget to add a link to the generated file at the output at the end of the process. This will be the only way users will have to get them. See "Final output" below).
TODO: If more than one file was created, Tainacan will create a zip of them at the end. Yet to be implemented.
#### Using transients
Since exporters are handled as background processes, they will run accross multiple requests. For that reason, you can not simply add properties to your class and trust their values will be kept during all the time the process is running.
If you want a value to persist so you can use it accross all methods of your exporter, at any time, you should use `transients` to store them in the database.
This is as simple as calling `set_transient()` and `get_transient()`. See the example below:
```
function callback_for_step_1() {
$this->add_transient('time_step_1', time());
}
// ...
function callback_for_step_5() {
$time_step_1 = get_transient('time_step_1');
}
```
#### Handling user feedback
There are two information Tainacan exporters give to the user about the status of the process while it is running in feedback. the `progress label` and the `progress value`.
The `progress label` is a string that can be anything that tells the user what is going on. By default, it is the Step Name, but you can inform a specific `progress_label` attribute when registering the steps.
The `progress value` is a number between 0 and 100 that indicates the progress of the current step or the whole exporter, Thats up to you. By default, it calculates it automatically using the `total` attribute registered with the steps, against the `$this->get_in_step_count()` value. In the case of the default Process Items callback, it calculates based on the number of items found in each collection.
See the `finish_processing` dummy callback in the Test Importer. You will notice that when we registered the step, we informed a `total` attribute to this step with the value of 5. This will tell Tainacan that the total number iterations this step need to complete is 5 and allow it to calculate the progress.
If it is no possible to know `total` of a step beforehand, you can set it at any time, even inside the step callback itself, using the `set_current_step_total($value)` or `set_step_total($step, $value)` methods.
##### Final output
When the process finishes, Background processes define an "output", which is a final report to the user of what happened.
This could be simply a message saying "All good", or could be a report with the names and links to the collections created. HTML is welcome.
Remember that for a more detailed and technical report, you should use Logs (see Logs below). This output is meant as a short but descriptive user friendly message.
In order to achieve this, exporters must implement a method called `get_output()` that returns a string.
This method will be called only once, when the exporter ends, so you might need to save information using `transients` during the process and use them in `get_output()` to compose your message.
To get a list of the generated files to display to users, use `$this->get_output_files()`.
#### Logs
There are two useful methods to write information to the logs: `add_log()` and `add_error_log()`. These are written into a log file related to the exporter background process and a link to it will be presented to the user.
## Run exporter
Finally, everything is ready. The exporter runs.
This will trigger a Background Process (documentation needed) and the exporter will run through as many background requests as needed.

152
docs/extra-view-modes.md Normal file
View File

@ -0,0 +1,152 @@
# Extra View Modes
Extra View Modes are a way of creating your own templates for items list visualization. By default, Tainacan offers the following view modes:
- Table
- Cards
- Records
- Masonry
- Thumbnails
- Slideshow
Each has it's specificities, but in case you're not satisfied with them, a developer can easily create a plugin to offer a custom template for displaying items list.
## Creating your extra view mode
As shown in [our post for extra view modes](http://tainacan.org/2018/06/13/custom-view-modes-how-will-the-world-see-your-collection/), we've created [a sample plugin](https://github.com/tainacan/tainacan-extra-viewmodes) with some inspirational ideas for custom view modes. We here describe the process to create such plugin. You will basically need three files:
1. The .php file for registering the plugin and view mode;
2. The .php file with the items list template;
3. The .css file with the styling for your template;
### Registering your plugin
As in any WordPress Plugin, you'll first need to create a php header as follows:
```php
<?php
/*
Plugin Name: Name of Your Extra View Mode Plugin
Plugin URI: A URL for a related link
Description: An extra view modes plugin for Tainacan
Author: Your Name Here
Version: 0.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
```
Only Plugin Name is obligatory. Save the file with a name unique to your plugin (a good practice is to use the plugin name, such as `name-of-your-extra-view-mode-plugin.php`).
The rest of the file will contain the register function for your view mode. We discuss it in details ahead:
```php
add_action( 'after_setup_theme', function() {
tainacan_register_view_mode('MyViewMode', [
'label' => 'My View Mode',
'icon' => '<span class="icon"><i class="mdi mdi-view-quilt mdi-24px"></i></span>',
'description' => 'This is my view mode. It looks great the way it is.',
'dynamic_metadata' => false,
'template' => __DIR__ . './my-view-mode.php',
]);
} );
?> /* End of file */
```
The function `tainacan_register_view_mode` is part of Tainacan's plugin. It's first paramether is a unique *slug* that will be used to identify your view mode. Then follows an array of paramethers:
| Type | Name | Description | Default |
|--------|------------------|-------------|-------------------------------------------|
| string | label | Label, visible to users on the view modes dropdown. | Same of the variable $slug |
| string | icon | HTML that outputs an icon that represents the view mode. Visible to users on view modes dropdown. | None |
| string | description | Description, visible only to editors in the admin. | None |
| string | type | Type. Accepted values are 'template' or 'component'. | 'template' |
| string | template | Full path to the template file to be used. Required if $type is set to template. | 'theme-path/tainacan/view-mode-{$slug}.php' |
| string | component | Component tag name. The web component js must be included and must accept two props: 1) items: the list of items to be rendered ; 2) displayed-metadata: list of metadata to be displayed; | 'view-mode-{$slug}' |
| string | thumbnail | Full URL to a thumbnail that represents the view mode. Displayed only in Admin. | None |
| string | skeleton_template | HTML that outputs a preview of the items to be loaded, such as gray blocks, mimicking the shape of the items. | None |
| bool | show_pagination | Wether to display or not pagination controls. | true |
| bool | full-screen | Wether the view mode will display full screen or not. | false |
| bool | dynamic_metadata | Wether to display or not (and use or not) the "displayed metadata" selector. | false |
| bool | implements_skeleton | Wheter the view modes takes care of showing it's own Skeleton/Ghost css classes for loading items. | false |
The `type` parameter is one of the most relevants here. When registering view modes, you can either create a simple PHP `template` using WordPress functions (as the ones in our sample plugin), or more complex Vue.js `component`. When passing a template, the file path should be provided, while for components the name of previously loaded .vue component must be provided. Vue components must also have two props, one for receiving the items list as a parsed JSON Object and other for an array of metadata that will be displayed.
View modes as Cards and Grid do not allow users to choose which metadata should be displayed, but rather decide that only certain will be visible. For this kind of view mode, it is used the `dynamic_metadata` parameter as `false`.
By default a spinning circle loading animation is shown when items are being fetch. Most of our oficial view modes override this by implementing a so called skeleton/ghost list, that mimics a list of gray blocks in the shape of items before they arrived. If your view mode does that, you should set `implements_skeleton` to true and provide a HTML template with such skeleton to `skeleton_template`. Tainacan will take care of rendering this skeleton while items are being loaded.
## Making an extra view mode template
The file path indicated on the register above should point to the .php file where your template lives. It will probably have some structure similar to the following sample:
```php
<?php if ( have_posts() ) : ?>
<div class="my-view-mode-container">
<?php while ( have_posts() ) : the_post(); ?>
<a class="my-view-mode-item" href="<?php the_permalink(); ?>">
<div class="media">
<?php if ( tainacan_current_view_displays('thumbnail') ): ?>
<a href="<?php the_permalink(); ?>">
<?php if ( has_post_thumbnail() ): ?>
<?php the_post_thumbnail('tainacan-medium', array('class' => 'mr-4')); ?>
<?php else: ?>
<?php echo '<div class="mr-4"><img alt="Thumbnail placeholder" src="'.get_stylesheet_directory_uri().'/assets/images/thumbnail_placeholder.png"></div>'?>
<?php endif; ?>
</a>
<?php endif; ?>
<div class="list-metadata media-body">
<?php if ( tainacan_current_view_displays('title') ): ?>
<p class="metadata-title">
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</p>
<?php endif; ?>
<?php tainacan_the_metadata(array('metadata__in' => $view_mode_displayed_metadata['meta'], 'exclude_title' => true, 'before_title' => '<h3 class="metadata-label">', 'before_value' => '<p class="metadata-value">')); ?>
</div>
</div>
</a>
<?php endwhile; ?>
</div>
<?php else : ?>
<div class="my-view-mode-container">
<section class="section">
<div class="content has-text-gray4 has-text-centered">
<p>
<span class="icon is-large">
<i class="mdi mdi-48px mdi-file-multiple"></i>
</span>
</p>
<p>'No item was found.','tainacan-interface'</p>
</div>
</section>
</div>
<?php endif; ?>
```
The classes `my-view-mode-container` and `my-view-mode-item`, and so forth should be implemented by you on your style file. Other classes as the `skeleton`, `section` are part of Tainacan's plugin CSS, and can be used if you wish to keep a standard.
Thumbnail is obtained via the function `the_post_thumbnail()`, which accepts as first parameter any of the following:
- 'tainacan-small' (40px width, 40px height, cropped);
- 'tainacan-medium' (275px width, 275 height, cropped);
- 'tainacan-medium-full', (max. 205px width, max. 1500px height, not cropped );
You can see that this view mode displays the array of metadata obtained from `tainacan_the_metadata()` function.

View File

@ -40,7 +40,7 @@ When the user starts a new import process, he/she first choose which import to u
Once the Importer is chosen, the first thing that happens is the creation of a new instance of the chosen Importer. This fires the `__construct()` method.
## Choose a collection (if manual_mapping is true)
## Choose a collection (if `manual_collection` is true)
After choosing the importer, user will be given the choice to choose the destination collection.
@ -131,15 +131,15 @@ public function get_source_metadata(){
An Importer may have several steps, that will handle different parts of the process. Each step will be handled by a different callback in the Importer class.
First, lets have a look at a simple CSV importer, that only have one steps, in which it imports the items from the source into a chosen collection. After that we will have a look on how to create custom steps.
First, lets have a look at a simple CSV importer, that only have one step, in which it imports the items from the source into a chosen collection. After that we will have a look on how to create custom steps.
### Simple Importer - One step that imports items
By default, the only method an Importer class must implement to functino is the `process_item()` class.
By default, the only method an Importer class must implement to function is the `process_item()` class.
This method gets two parameters, the `$index` of the item to be inserted, and the `$collection_definition`, with information on the target collection.
Inside this metho you must fetch the item from the source and format it according to the `mapping` definition of the collection.
Inside this method you must fetch the item from the source and format it according to the `mapping` definition of the collection.
The `mapping` defines how the item metadata from the source should be mapped to the metadata present in the target collection. It was created either manually, by the user, or programatically by the importer in an earlier step (see advanced importers below). This is an array where the keys are the `metadata IDs` and the values are the `identifers` found in source.
@ -159,7 +159,7 @@ By default, Tainacan Importer super class is registering one single step to the
]
```
This step will lopp though all the collections added to the importer (manuall or programatically) and add the items to it.
This step will lopp through all the collections added to the importer (manuall or programatically) and add the items to it.
You may register as many steps and callbacks as you want in your importer, but you should consider keeping this default step at some point to handle the items insertion. For example, see how the Test Importer adds other steps before and after but keeps this default step in the middle:
@ -208,7 +208,7 @@ class Test_Importer extends Importer {
Each step has its own callback. The callback may do anything necessary, just keep in mind that you should allow the importer to break very long processes into several requests.
In order to that, your step callback might be called several times, and each time run a part of the process and returnt its current status, until its done.
In order to that, your step callback might be called several times, and each time run a part of the process and return its current status, until its done.
When you run the importer, Tainacan will automatically iterate over your steps. If a step callback returns `false`, it assumes the step is over and it will pass to the next step in the next iteration. If the step callback returns an integer, it will keep the pointer in this step and call the same step again in the next iteration. The current position, which is the integer returned the last time the callback was invoked, will be accessible via the `$this->get_in_step_count()` method.

View File

@ -10,6 +10,9 @@ Assuming:
* $BUILD_PATH is where the plugin is condigured to buid
* $SVN_PATH is where the WordPress.org SVN repo is
## Pre-release
Before we publish a new version, we always release one or more Release Candidates so the community have time to test and make sure the new version of Tainacan is clean and ready to reach the world.
### Start in the git repository
@ -19,10 +22,22 @@ git checkout develop
git pull
```
### Create a new Release branch
Create a new `release/$NEW_VERSION` branch. If using git flow:
```
git flow release start $NEW_VERSION
```
### Edit version numbers
Edit `src/readme.txt` and `src/tainacan.php` and change the version numbers to `$NEW_VERSION`.
When releasing a RC version, append RC (number) to the version.
Also increase the `Tested Up` version, if applicable.
### Set build to production mode
Edit `webpack.config.js` to set production mode.
@ -34,6 +49,62 @@ Edit `webpack.config.js` to set production mode.
cd $BUILD_PATH
rm -r admin/scss/.sass-cache
```
### Set build to development mode
```
cd $GIT_PATH
git checkout webpack.config.js
```
### Publish the RC
Create a ZIP package with the built plugin and publish a blog post calling for tests.
Commit and push to Git!
### Test
Using the Test guide as a resource, test every feature of the plugin, including importers and exporters. With time, we can build more detailed test scripts and distribute tests among people in the community.
### Fix and publish new RC, or finish
If bugs are found, fix them and commit to the release branch. Publish a new RC, following the steps above, until we have a stable version we feel confident to release.
## Release
The plugin is ready to go. We have published one or more RCs and the community have tested it. Lets get it live to the world!
### Finish version number
Back to the git repository, make sure everything is up to date:
```
cd $GIT_PATH
git checkout release/$NEW_VERSION
git pull
```
Edit `src/readme.txt` and `src/tainacan.php` and change the version numbers to `$NEW_VERSION`.
Commit and push.
### Set build to production mode
Edit `webpack.config.js` to set production mode.
### Build and cleanup
```
./build.sh
cd $BUILD_PATH
rm -r admin/scss/.sass-cache
```
### Set build to development mode
```
cd $GIT_PATH
git checkout webpack.config.js
```
### Prepare SVN repo
@ -98,17 +169,14 @@ Check if everything is ok.
Once the release is tested and confirmed, commit and create the tag on git.
Don't forget to undo the changes to `webpack.config.js`, setting production mode to false again.
Merge the release branch into master and develop branches and create a tag.
Using git flow:
```
cd $GIT_PATH
git checkout webpack.config.js
git commit -am "Releasing verion $NEW_VERSION"
git tag $NEW_VERSION
git checkout master
git merge develop
git flow release finish $NEW_VERSION
git push --all
git push --tags
```

4552
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,16 +7,16 @@
"build": "cross-env NODE_ENV=development webpack --display-error-details --mode development --progress --hide-modules"
},
"dependencies": {
"@brainhubeu/react-carousel": "^1.10.1",
"axios": "^0.18.0",
"buefy": "^0.7.0",
"bulma": "^0.7.2",
"buefy": "^0.7.3",
"bulma": "^0.7.4",
"mdi": "^2.2.43",
"moment": "^2.22.2",
"node-sass": "^4.9.4",
"qs": "^6.5.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react": "^16.8.3",
"react-autocomplete": "^1.8.1",
"react-dom": "^16.8.3",
"t": "^0.5.1",
"v-tooltip": "^2.0.0-rc.33",
"vue": "^2.5.17",
@ -35,8 +35,7 @@
"babel-loader": "^8.0.4",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"element-theme-chalk": "^2.4.8",
"eslint": "^5.7.0",
"eslint": "^4.0.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-vue": "^4.7.1",
"file-loader": "^2.0.0",
@ -49,6 +48,6 @@
"vue-template-compiler": "^2.5.17",
"webpack": "^4.22.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.9"
"webpack-dev-server": ">=3.1.11"
}
}

View File

@ -42,6 +42,15 @@ class Admin {
array( &$this, 'admin_page' ),
plugin_dir_url( __FILE__ ) . 'images/tainacan_logo_symbol.svg'
);
add_submenu_page(
$this->menu_slug,
__('System check', 'tainacan'),
__('System check', 'tainacan'),
'manage_options',
'tainacan_systemcheck',
array( &$this, 'systemcheck_page' )
);
add_action( 'load-' . $page_suffix, array( &$this, 'load_admin_page' ) );
}
@ -213,6 +222,23 @@ class Admin {
$settings['form_hooks'] = Admin_Hooks::get_instance()->get_registered_hooks();
$wp_post_types = get_post_types(['show_ui' => true], 'objects');
if (isset($wp_post_types['attachment'])) {
unset($wp_post_types['attachment']);
}
$wp_post_types = array_map(function($i) {
return [
'slug' => $i->name,
'label' => $i->label
];
}, $wp_post_types);
$settings['wp_post_types'] = $wp_post_types;
// add an alternative to enable select all items in all pages while we temporarly disable bulk edit for all (see #199)
$settings['enable_select_all_items_pages'] = defined('TAINACAN_ENABLE_SELECT_ALL_ITEMS_PAGES') ? TAINACAN_ENABLE_SELECT_ALL_ITEMS_PAGES : false;
return $settings;
}
@ -309,6 +335,12 @@ class Admin {
wp_die();
}
public function systemcheck_page() {
require_once('system-check/class-tainacan-system-check.php');
$check = new System_Check();
$check->admin_page();
}
}

View File

@ -392,7 +392,7 @@
all: true,
order: 'asc',
offset: 0,
number: 10,
number: 100,
}).then((res) => {
this.termList = res.terms;

View File

@ -10,7 +10,7 @@
label-width="120px">
<div class="columns">
<div class="column is-4">
<div class="column is-5">
<!-- Name -------------------------------- -->
<b-field
@ -34,7 +34,8 @@
v-if="formHooks != undefined &&
formHooks['collection'] != undefined &&
formHooks['collection']['begin-left'] != undefined">
<form
<form
class="form-hook-region"
id="form-collection-begin-left"
v-html="this.formHooks['collection']['begin-left'].join('')"/>
</template>
@ -172,7 +173,8 @@
class="two-columns-dropdown"
ref="enabledViewModesDropdown"
:mobile-modal="true"
:disabled="Object.keys(registeredViewModes).length < 0">
:disabled="Object.keys(registeredViewModes).length < 0"
aria-role="list">
<button
class="button is-white"
slot="trigger"
@ -187,7 +189,8 @@
v-for="(viewMode, index) in Object.keys(registeredViewModes)"
:key="index"
class="control"
custom>
custom
aria-role="listitem">
<b-checkbox
v-if="registeredViewModes[viewMode] != undefined"
@input="updateViewModeslist(viewMode)"
@ -245,11 +248,11 @@
<form
ref="form-collection-end-left"
id="form-collection-end-left"
class="form-hook-region"
v-html="formHooks['collection']['end-left'].join('')"/>
</template>
</div>
<div class="column is-1" />
<div class="column">
<!-- Status -------------------------------- -->
@ -319,6 +322,7 @@
formHooks['collection']['begin-right'] != undefined">
<form
id="form-collection-begin-right"
class="form-hook-region"
v-html="formHooks['collection']['begin-right'].join('')"/>
</template>
@ -430,6 +434,7 @@
formHooks['collection']['end-right'] != undefined">
<form
id="form-collection-end-right"
class="form-hook-region"
v-html="formHooks['collection']['end-right'].join('')"/>
</template>
</div>
@ -690,10 +695,10 @@ export default {
// Generates options for parent collection
this.isFetchingCollections = true;
this.fetchCollectionsForParent()
.then((collections) => {
this.collections = collections;
this.isFetchingCollections = false;
})
.then((collections) => {
this.collections = collections;
this.isFetchingCollections = false;
})
.catch((error) => {
this.$console.error(error);
this.isFetchingCollections = false;
@ -801,12 +806,14 @@ export default {
frame_button: this.$i18n.get('label_select_file'),
},
relatedPostId: this.collectionId,
onSave: (mediaId) => {
this.updateThumbnail({collectionId: this.collectionId, thumbnailId: mediaId})
.then((res) => {
this.collection.thumbnail = res.thumbnail;
onSave: (media) => {
this.updateThumbnail({
collectionId: this.collectionId, thumbnailId: media.id
})
.catch(error => this.$console.error(error));
.then((res) => {
this.collection.thumbnail = res.thumbnail;
})
.catch(error => this.$console.error(error));
}
}
);
@ -931,9 +938,10 @@ export default {
@import "../../scss/_variables.scss";
.column {
padding-left: 0;
padding-right: 0;
@media screen and (max-width: 1024px) {
.column:last-of-type {
padding-left: $page-side-padding !important;
}
}
.field {

View File

@ -3,7 +3,7 @@
<tainacan-title
:bread-crumb-items="[
{ path: $routerHelper.getAvailableExportersPath(), label: $i18n.get('exporters') },
{ path: '', label: exporterType != undefined ? exporterType : $i18n.get('title_exporter_page') }
{ path: '', label: exporterType != undefined ? (exporterName != undefined ? exporterName : exporterType) : $i18n.get('title_exporter_page') }
]"/>
<b-loading
:active.sync="isLoading"
@ -119,6 +119,7 @@
data(){
return {
exporterType: '',
exporterName: '',
collections: [],
adminFullURL: tainacan_plugin.admin_url + 'admin.php?page=tainacan_admin#',
isFetchingCollections: false,
@ -133,6 +134,7 @@
},
methods: {
...mapActions('exporter', [
'fetchAvailableExporters',
'createExporterSession',
'updateExporterSession',
'runExporterSession'
@ -164,15 +166,18 @@
let exporterSessionUpdated = {
body: {
collection: {
id: this.selectedCollection
},
mapping_selected: this.selectedMapping ? this.selectedMapping : this.selectedMapping,
send_email: this.sendEmail
},
id: this.exporterSession.id,
};
if (this.exporterSession.manual_collection) {
exporterSessionUpdated['body']['collection'] = {
id: this.selectedCollection
};
}
this.updateExporterSession(exporterSessionUpdated)
.then(exporterSessionUpdated => {
this.verifyError(exporterSessionUpdated);
@ -194,7 +199,7 @@
},
formIsValid(){
return (
this.selectedCollection &&
((this.exporterSession.manual_collection && this.selectedCollection) || !this.exporterSession.manual_collection) &&
((!this.exporterSession.accept_no_mapping && this.selectedMapping) ||
this.exporterSession.accept_no_mapping) &&
!this.formErrorMessage
@ -235,6 +240,13 @@
this.isFetchingCollections = false;
this.$console.error(error);
});
// Set exporter's name
this.fetchAvailableExporters().then((exporterTypes) => {
if (exporterTypes[this.exporterType])
this.exporterName = exporterTypes[this.exporterType].name;
});
}
}
</script>

View File

@ -30,6 +30,7 @@
formHooks['filter']['begin-left'] != undefined">
<form
id="form-filter-begin-left"
class="form-hook-region"
v-html="formHooks['filter']['begin-left'].join('')"/>
</template>
@ -152,6 +153,7 @@
formHooks['filter']['end-left'] != undefined">
<form
id="form-filter-end-left"
class="form-hook-region"
v-html="formHooks['filter']['end-left'].join('')"/>
</template>
</div>

View File

@ -4,7 +4,7 @@
<tainacan-title
:bread-crumb-items="[
{ path: $routerHelper.getAvailableImportersPath(), label: $i18n.get('importers') },
{ path: '', label: importerType != undefined ? importerType : $i18n.get('title_importer_page') }
{ path: '', label: importerType != undefined ? (importerName != undefined ? importerName :importerType) : $i18n.get('title_importer_page') }
]"/>
<form
@click="formErrorMessage = ''"
@ -186,6 +186,7 @@ export default {
},
importerTypes: [],
importerType: '',
importerName: '',
importerFile: null,
importerSourceInfo: null,
collections: [],
@ -196,7 +197,7 @@ export default {
},
methods: {
...mapActions('importer', [
'fetchImporterTypes',
'fetchAvailableImporters',
'fetchImporter',
'sendImporter',
'updateImporter',
@ -402,6 +403,12 @@ export default {
this.onSelectCollection(this.collectionId);
}
// Set importer's name
this.fetchAvailableImporters().then((importerTypes) => {
if (importerTypes[this.importerType])
this.importerName = importerTypes[this.importerType].name;
});
if (this.sessionId != undefined)
this.loadImporter();
else

View File

@ -18,7 +18,7 @@
:to="$routerHelper.getAvailableImportersPath()">{{ $i18n.get('importers') }}</router-link> >
<router-link
tag="a"
:to="$routerHelper.getImporterPath(importerType, sessionId)">{{ importerType }}</router-link> >
:to="$routerHelper.getImporterPath(importerType, sessionId)">{{ importerType != undefined ? (importerName != undefined ? importerName :importerType) : $i18n.get('title_importer_page') }}</router-link> >
<router-link
tag="a"
:to="$routerHelper.getImporterMappingPath(importerType, sessionId, collectionId)">{{ $i18n.get('label_metadata_mapping') }}</router-link>
@ -88,9 +88,6 @@
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_select_metadatum_type') }}</h2>
<a
class="back-link"
@click="onMetadatumEditionCanceled(); isNewMetadatumModalActive = false">{{ $i18n.get('exit') }}</a>
<hr>
</div>
<section class="tainacan-form">
@ -103,6 +100,16 @@
<h4>{{ metadatumType.name }}</h4>
</div>
</div>
<div class="field is-grouped form-submit">
<div class="control">
<button
id="button-cancel-importer-edition"
class="button is-outlined"
type="button"
@click="onMetadatumEditionCanceled(); isNewMetadatumModalActive = false">
{{ $i18n.get('cancel') }}</button>
</div>
</div>
</section>
</div>
<div
@ -110,6 +117,11 @@
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_configure_new_metadatum') }}</h2>
<a
class="back-link"
@click="isEditingMetadatum = false">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<metadatum-edition-form
@ -184,6 +196,7 @@ export default {
'total_items': Number
},
importerType: '',
importerName: '',
importerSourceInfo: null,
collections: [],
collectionMetadata: [],
@ -207,7 +220,7 @@ export default {
},
methods: {
...mapActions('importer', [
'fetchImporterTypes',
'fetchAvailableImporters',
'fetchImporter',
'sendImporter',
'updateImporter',
@ -219,9 +232,6 @@ export default {
'runImporter',
'fetchMappingImporter'
]),
...mapActions('collection', [
'fetchCollectionsForParent'
]),
...mapActions('bgprocess', [
'fetchProcess'
]),
@ -404,6 +414,12 @@ export default {
this.collectionId = this.$route.params.collectionId;
this.mappedCollection['id'] = this.collectionId;
// Set importer's name
this.fetchAvailableImporters().then((importerTypes) => {
if (importerTypes[this.importerType])
this.importerName = importerTypes[this.importerType].name;
});
this.loadImporter();
this.loadMetadata();
}

View File

@ -61,12 +61,12 @@
<p
v-if="uploadedItems.length > 0 && (uploadedItems.length - amountFinished) > 1"
class="has-text-gray">
{{ (uploadedItems.length - amountFinished) + " " + $i18n.get('label_files_remaining') }}
{{ $i18n.getWithVariables('label_%s_files_remaining', [(uploadedItems.length - amountFinished)]) }}
</p>
<p
v-if="uploadedItems.length > 0 && (uploadedItems.length - amountFinished) == 1"
class="has-text-gray">
{{ "1 " + $i18n.get('label_file_remaining') }}
{{ $i18n.get('label_one_file_remaining') }}
</p>
</div>
@ -84,7 +84,7 @@
<div
class="document-item"
v-for="(item, index) of uploadedItems"
:key="index">
:key="item.id">
<img
v-if="item.document!= undefined && item.document != '' && item.document_type != 'empty'"
class="document-thumb"
@ -107,7 +107,7 @@
<span
v-if="item.document != '' && item.document_type != 'empty'"
class="icon has-text-success">
<i class="tainacan-icon tainacan-icon-24px tainacan-icon-approvedcircle" />
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-approvedcircle" />
</span>
</div>
<div

View File

@ -44,6 +44,7 @@
formHooks['item']['begin-left'] != undefined">
<form
id="form-item-begin-left"
class="form-hook-region"
v-html="formHooks['item']['begin-left'].join('')"/>
</template>
@ -197,6 +198,7 @@
<div class="control">
<button
id="button-submit-text-content-writing"
type="submit"
@click.prevent="confirmTextWriting()"
class="button is-success">
{{ $i18n.get('save') }}</button>
@ -349,6 +351,7 @@
formHooks['item']['end-left'] != undefined">
<form
id="form-item-end-left"
class="form-hook-region"
v-html="formHooks['item']['end-left'].join('')"/>
</template>
@ -362,6 +365,7 @@
formHooks['item']['begin-right'] != undefined">
<form
id="form-item-begin-right"
class="form-hook-region"
v-html="formHooks['item']['begin-right'].join('')"/>
</template>
@ -438,6 +442,7 @@
formHooks['item']['end-right'] != undefined">
<form
id="form-item-end-right"
class="form-hook-region"
v-html="formHooks['item']['end-right'].join('')"/>
</template>
</div>
@ -1009,8 +1014,8 @@ export default {
frame_title: this.$i18n.get('instruction_select_item_thumbnail'),
},
relatedPostId: this.itemId,
onSave: (mediaId) => {
this.updateThumbnail({itemId: this.itemId, thumbnailId: mediaId})
onSave: (media) => {
this.updateThumbnail({itemId: this.itemId, thumbnailId: media.id})
.then((res) => {
this.item.thumbnail = res.thumbnail;
})
@ -1063,9 +1068,13 @@ export default {
// Initializes Media Frames now that itemId exists
this.initializeMediaFrames();
this.fetchItem(this.itemId).then(res => {
this.fetchItem({ itemId: this.itemId, contextEdit: true }).then(res => {
this.item = res;
// Checks if user has permission to edit
if (!this.item.current_user_can_edit)
this.$router.push(this.$routerHelper.getCollectionPath(this.collectionId));
// Updates Collection BreadCrumb
if (this.isOnSequenceEdit) {
this.$root.$emit('onCollectionBreadCrumbUpdate', [
@ -1167,9 +1176,11 @@ export default {
}
// Obtains collection name
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
if (!this.isRepositoryLevel) {
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
}
// Obtains if collection allow items comments
this.fetchCollectionAllowComments(this.collectionId).then((collectionAllowComments) => {

View File

@ -28,10 +28,10 @@
</div>
<br>
<p v-if="items.length <= 0 && !isLoadingGroupInfo && bulkEditGroup.items_count == 1">
{{ $i18n.get('info_there_is') + ' ' + bulkEditGroup.items_count + ' ' + $i18n.get('info_item_being_edited') + '.' }}
{{ $i18n.get('info_there_is_one_item_being_edited') }}
</p>
<p v-if="items.length <= 0 && !isLoadingGroupInfo && bulkEditGroup.items_count > 1">
{{ $i18n.get('info_there_are') + ' ' + bulkEditGroup.items_count + ' ' + $i18n.get('info_items_being_edited') + '.' }}
{{ $i18n.getWithVariables('info_there_are_%s_items_being_edited', bulkEditGroup.items_count) }}
</p>
<p v-if="items.length <= 0 && !isLoadingGroupInfo">
{{ $i18n.get('info_no_preview_found') }}
@ -39,8 +39,8 @@
<transition-group name="item-appear">
<div
class="document-item"
v-for="(item, index) of items"
:key="index">
v-for="(item) of items"
:key="item.id">
<img
v-if="item.document!= undefined && item.document != '' && item.document_type != 'empty'"
class="document-thumb"

View File

@ -31,6 +31,7 @@
formHooks['metadatum']['begin-left'] != undefined">
<form
id="form-metadatum-begin-left"
class="form-hook-region"
v-html="formHooks['metadatum']['begin-left'].join('')"/>
</template>
@ -223,6 +224,7 @@
formHooks['metadatum']['end-left'] != undefined">
<form
id="form-metadatum-end-left"
class="form-hook-region"
v-html="formHooks['metadatum']['end-left'].join('')"/>
</template>
</div>
@ -392,25 +394,25 @@
border-top: 1px solid $gray2;
border-bottom: 1px solid $gray2;
margin-top: 1.0em;
}
form#metadatumEditForm .options-columns {
-moz-column-count: 2;
-moz-column-gap: 0;
-moz-column-rule: none;
-webkit-column-count: 2;
-webkit-column-gap: 0;
-webkit-column-rule: none;
column-count: 2;
column-gap: 4rem;
column-rule: none;
padding-bottom: 1.5rem;
.options-columns {
-moz-column-count: 2;
-moz-column-gap: 0;
-moz-column-rule: none;
-webkit-column-count: 2;
-webkit-column-gap: 0;
-webkit-column-rule: none;
column-count: 2;
column-gap: 4rem;
column-rule: none;
padding-bottom: 1.5rem;
&>.field, &>section {
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
&>.field, &>section {
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
}
</style>

View File

@ -14,114 +14,149 @@
v-if="taxonomy != null && taxonomy != undefined"
class="tainacan-form"
label-width="120px">
<!-- Name -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_name')"
:type="editFormErrors['name'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['name'] != undefined ? editFormErrors['name'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'name')"
:message="$i18n.getHelperMessage('taxonomies', 'name')"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@focus="clearErrors('name')"
@blur="updateSlug()"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['begin-left'] != undefined">
<form
id="form-taxonomy-begin-left"
v-html="formHooks['taxonomy']['begin-left'].join('')"/>
</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')"/>
<b-input
id="tainacan-text-description"
type="textarea"
v-model="form.description"
@focus="clearErrors('description')"/>
</b-field>
<!-- 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')"/>
<b-select
id="tainacan-select-status"
v-model="form.status"
@focus="clearErrors('status')"
:placeholder="$i18n.get('instruction_select_a_status')">
<option
v-for="statusOption in statusOptions"
:key="statusOption.value"
:value="statusOption.value"
:disabled="statusOption.disabled">{{ statusOption.label }}
</option>
</b-select>
</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')"/>
<b-input
@input="updateSlug()"
id="tainacan-text-slug"
v-model="form.slug"
@focus="clearErrors('slug')"
:disabled="isUpdatingSlug"/>
</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" />
<div class="columns">
<div class="column">
<!-- Name -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_name')"
:type="editFormErrors['name'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['name'] != undefined ? editFormErrors['name'] : ''">
<help-button
:title="$i18n.getHelperTitle('taxonomies', 'allow_insert')"
:message="$i18n.getHelperMessage('taxonomies', 'allow_insert')"/>
</label>
</b-field>
:title="$i18n.getHelperTitle('taxonomies', 'name')"
:message="$i18n.getHelperMessage('taxonomies', 'name')"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@focus="clearErrors('name')"
@blur="updateSlug()"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['end-left'] != undefined">
<form
id="form-taxonomy-end-left"
v-html="formHooks['taxonomy']['end-left'].join('')"/>
</template>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['begin-left'] != undefined">
<form
id="form-taxonomy-begin-left"
class="form-hook-region"
v-html="formHooks['taxonomy']['begin-left'].join('')"/>
</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')"/>
<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')"/>
</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')"/>
<div class="status-radios">
<b-radio
v-model="form.status"
v-for="statusOption in statusOptions"
:key="statusOption.value"
:native-value="statusOption.value">
<span class="icon has-text-gray">
<i
class="tainacan-icon tainacan-icon-18px"
:class="'tainacan-icon-' + getStatusIcon(statusOption.value)"/>
</span>
{{ statusOption.label }}
</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')"/>
<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')"/>
<div
v-for="wpPostType in wpPostTypes"
:key="wpPostType.slug"
class="field">
<b-checkbox
:native-value="wpPostType.slug"
:true-value="wpPostType.slug"
false-value=""
v-model="form.enabledPostTypes"
name="enabled_post_types" >
{{ wpPostType.label }}
</b-checkbox>
</div>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['end-left'] != undefined">
<form
id="form-taxonomy-end-left"
class="form-hook-region"
v-html="formHooks['taxonomy']['end-left'].join('')"/>
</template>
</div>
</div>
<!-- Submit -->
<div class="field is-grouped form-submit">
@ -180,7 +215,8 @@
status: String,
description: String,
slug: String,
allowInsert: String
allowInsert: String,
enabledPostTypes: Array
},
statusOptions: [{
value: 'publish',
@ -195,6 +231,7 @@
value: 'trash',
label: this.$i18n.get('trash')
}],
wpPostTypes: tainacan_plugin.wp_post_types,
editFormErrors: {},
formErrorMessage: '',
entityName: 'taxonomy'
@ -216,6 +253,8 @@
formNotSaved = true;
if (this.taxonomy.status != this.form.status)
formNotSaved = true;
if (this.taxonomy.enabled_post_types != this.form.enabledPostTypes)
formNotSaved = true;
if (formNotSaved) {
this.$modal.open({
@ -275,7 +314,8 @@
description: this.form.description,
slug: this.form.slug ? this.form.slug : '',
status: this.form.status,
allow_insert: this.form.allowInsert
allow_insert: this.form.allowInsert,
enabled_post_types: this.form.enabledPostTypes
};
this.fillExtraFormData(data);
this.updateTaxonomy(data)
@ -292,6 +332,7 @@
this.form.description = this.taxonomy.description;
this.form.status = this.taxonomy.status;
this.form.allowInsert = this.taxonomy.allow_insert;
this.form.enabledPostTypes = this.taxonomy.enabled_post_types;
this.isLoadingTaxonomy = false;
this.formErrorMessage = '';
@ -365,6 +406,15 @@
})
.catch(error => this.$console.error(error));
},
getStatusIcon(status) {
switch(status) {
case 'publish': return 'public';
case 'private': return 'private';
case 'draft': return 'draft';
case 'trash': return 'delete';
default: return 'item';
}
},
clearErrors(attribute) {
this.editFormErrors[attribute] = undefined;
},
@ -408,6 +458,7 @@
this.form.slug = this.taxonomy.slug;
this.form.status = this.taxonomy.status;
this.form.allowInsert = this.taxonomy.allow_insert;
this.form.enabledPostTypes = this.taxonomy.enabled_post_types;
this.isLoadingTaxonomy = false;
});
@ -416,5 +467,24 @@
}
</script>
<style>
.tab-content {
overflow: visible !important;
}
.status-radios {
display: flex;
}
.status-radios .control-lable {
display: flex;
align-items: center;
}
.tainacan-form>.columns {
margin-bottom: 76px;
}
.tainacan-form .column {
padding: 1rem 4.1666667%;
}
.tainacan-form .column:last-of-type {
padding-left: 0;
}
</style>

View File

@ -7,43 +7,6 @@
<h2>{{ $i18n.get("title_term_edition") }}</h2>
<hr>
</div>
<!-- Header Image -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_header_image')">
<div class="thumbnail-field">
<figure class="image">
<span
v-if="editForm.header_image === undefined || editForm.header_image === false"
class="image-placeholder">{{ $i18n.get('label_empty_header_image') }}</span>
<img
:alt="$i18n.get('label_header_image')"
:src="(editForm.header_image === undefined || editForm.header_image === false) ? headerPlaceholderPath : editForm.header_image">
</figure>
<div class="thumbnail-buttons-row">
<a
class="button is-rounded is-secondary"
id="button-edit-header"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
<a
class="button is-rounded is-secondary"
id="button-delete-header"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
</div>
<br>
</div>
</b-field>
<!-- Name -------------- -->
<b-field
@ -70,26 +33,71 @@
formHooks['term']['begin-left'] != undefined">
<form
id="form-term-begin-left"
class="form-hook-region"
v-html="formHooks['term']['begin-left'].join('')"/>
</template>
<!-- Description -------------- -->
<b-field
:addons="false"
:type="formErrors['description'] !== '' && formErrors['description'] !== undefined ? 'is-danger' : ''"
:message="formErrors['description']">
<label class="label">
{{ $i18n.get('label_description') }}
<help-button
:title="$i18n.get('label_description')"
:message="$i18n.get('info_help_term_description')"/>
</label>
<b-input
type="textarea"
name="description"
v-model="editForm.description"
@focus="clearErrors('description')"/>
</b-field>
<div class="columns is-gapless image-and-description-area">
<div class="column">
<!-- Header Image -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_image')">
<div class="thumbnail-field">
<figure class="image">
<span
v-if="editForm.header_image === undefined || editForm.header_image === false"
class="image-placeholder">{{ $i18n.get('label_empty_term_image') }}</span>
<img
:alt="$i18n.get('label_image')"
:src="(editForm.header_image === undefined || editForm.header_image === false) ? headerPlaceholderPath : editForm.header_image">
</figure>
<div class="thumbnail-buttons-row">
<a
class="button is-rounded is-secondary"
id="button-edit-header"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
</a>
<a
class="button is-rounded is-secondary"
id="button-delete-header"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-delete"/>
</span>
</a>
</div>
<br>
</div>
</b-field>
</div>
<div class="column">
<!-- Description -------------- -->
<b-field
:addons="false"
:type="formErrors['description'] !== '' && formErrors['description'] !== undefined ? 'is-danger' : ''"
:message="formErrors['description']">
<label class="label">
{{ $i18n.get('label_description') }}
<help-button
:title="$i18n.get('label_description')"
:message="$i18n.get('info_help_term_description')"/>
</label>
<b-input
type="textarea"
name="description"
v-model="editForm.description"
@focus="clearErrors('description')"/>
</b-field>
</div>
</div>
<!-- Parent -------------- -->
<b-field
@ -139,6 +147,7 @@
formHooks['term']['end-left'] != undefined">
<form
id="form-term-end-left"
class="form-hook-region"
v-html="formHooks['term']['end-left'].join('')"/>
</template>
@ -154,13 +163,14 @@
</button>
</div>
<div class="control">
<button
<a
type="button"
v-if="editForm.url != undefined && editForm.url!= ''"
class="button is-secondary"
target="_blank"
:href="editForm.url">
{{ $i18n.get('see') + ' ' + $i18n.get('term') }}
</button>
{{ $i18n.get('label_view_term') }}
</a>
</div>
<div class="control">
<button
@ -184,7 +194,7 @@
data() {
return {
formErrors: {},
headerPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_rectangle.png',
headerPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
headerImageMediaFrame: undefined,
isFetchingParentTerms: false,
parentTerms: [],
@ -218,6 +228,7 @@
description: this.editForm.description,
parent: this.hasParent ? this.editForm.parent : 0,
header_image_id: this.editForm.header_image_id,
header_image: this.editForm.header_image,
};
this.fillExtraFormData(data);
this.sendChildTerm({
@ -241,11 +252,12 @@
} else {
let data = {
term_id: this.editForm.id,
id: this.editForm.id,
name: this.editForm.name,
description: this.editForm.description,
parent: this.hasParent ? this.editForm.parent : 0,
header_image_id: this.editForm.header_image_id,
header_image: this.editForm.header_image,
}
this.fillExtraFormData(data);
this.updateChildTerm({
@ -279,13 +291,15 @@
);
},
initializeMediaFrames() {
this.headerImageMediaFrame = new wpMediaFrames.headerImageControl(
'my-header-image-media-frame', {
this.headerImageMediaFrame = new wpMediaFrames.thumbnailControl(
'my-thumbnail-image-media-frame', {
button_labels: {
frame_title: this.$i18n.get('instruction_select_term_header_image'),
frame_button: this.$i18n.get('label_select_file')
},
relatedPostId: this.editForm.id,
onSave: (croppedImage) => {
this.editForm = Object.assign({},
this.editForm,
{
@ -342,7 +356,7 @@
}
},
mounted() {
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
@ -419,6 +433,18 @@
}
}
.image-and-description-area {
margin-bottom: 0px;
margin-top: 24px;
.column:first-of-type {
margin-right: 24px;
}
.column:last-of-type {
flex-grow: 2;
}
}
.thumbnail-field {
.content {
@ -434,7 +460,7 @@
margin-right: auto;
width: 100%;
top: 35%;
font-size: 1.2rem;
font-size: 1.25rem;
font-weight: bold;
z-index: 99;
text-align: center;

View File

@ -120,20 +120,6 @@
v-for="(collection, index) of collections"
class="tainacan-card">
<ul class="menu-list">
<li>
<a
:href="collection.url"
target="_blank"
:aria-label="$i18n.get('label_view_collection')">
<b-tooltip
:label="$i18n.get('label_view_collection')"
position="is-bottom">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-see"/>
</span>
</b-tooltip>
</a>
</li>
<li>
<router-link
tag="a"
@ -149,7 +135,7 @@
<!-- <span class="menu-text">{{ $i18n.get('items') }}</span> -->
</router-link>
</li>
<li>
<li v-if="collection.current_user_can_edit">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionEditPath(collection.id) }"
@ -210,6 +196,20 @@
<!-- <span class="menu-text">{{ $i18n.get('activities') }}</span> -->
</router-link>
</li>
<li>
<a
:href="collection.url"
target="_blank"
:aria-label="$i18n.get('label_view_collection')">
<b-tooltip
:label="$i18n.get('label_view_collection')"
position="is-bottom">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-see"/>
</span>
</b-tooltip>
</a>
</li>
</ul>
<router-link
tag="a"

View File

@ -15,7 +15,8 @@
position="is-bottom-left"
v-if="$userCaps.hasCapability('delete_tainacan-collections')"
:disabled="!isSelectingCollections"
id="bulk-actions-dropdown">
id="bulk-actions-dropdown"
aria-role="list">
<button
class="button is-white"
slot="trigger">
@ -27,15 +28,61 @@
<b-dropdown-item
id="item-delete-selected-items"
@click="deleteSelectedCollections()">
@click="deleteSelectedCollections()"
aria-role="listitem">
{{ $i18n.get('label_delete_selected_collections') }}
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_collections') + ' (Not ready)' }}
<b-dropdown-item
disabled
aria-role="listitem">{{ $i18n.get('label_edit_selected_collections') + ' (Not ready)' }}
</b-dropdown-item>
</b-dropdown>
</div>
</div>
<div class="table-wrapper">
<!-- Context menu for right click selection -->
<div
v-if="cursorPosY > 0 && cursorPosX > 0"
class="context-menu">
<!-- Backdrop for escaping context menu -->
<div
@click.left="clearContextMenu()"
@click.right="clearContextMenu()"
class="context-menu-backdrop" />
<b-dropdown
inline
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }">
<b-dropdown-item
@click="openCollection()"
v-if="!isOnTrash">
{{ $i18n.getFrom('collections', 'view_item') }}
</b-dropdown-item>
<b-dropdown-item
@click="openCollectionOnNewTab()"
v-if="!isOnTrash">
{{ $i18n.get('label_open_collection_new_tab') }}
</b-dropdown-item>
<b-dropdown-item
@click="selectCollection()"
v-if="contextMenuIndex != null">
{{ !selectedCollections[contextMenuIndex] ? $i18n.get('label_select_collection') : $i18n.get('label_unselect_collection') }}
</b-dropdown-item>
<b-dropdown-item
@click="goToCollectionEditPage(contextMenuCollection)"
v-if="contextMenuCollection != null">
{{ $i18n.getFrom('collections', 'edit_item') }}
</b-dropdown-item>
<b-dropdown-item
@click="deleteOneCollection(contextMenuCollection)"
v-if="contextMenuCollection != null">
{{ $i18n.get('label_delete_collection') }}
</b-dropdown-item>
</b-dropdown>
</div>
<table class="tainacan-table">
<thead>
<tr>
@ -90,7 +137,8 @@
<!-- Thumbnail -->
<td
class="thumbnail-cell column-default-width"
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
:label="$i18n.get('label_thumbnail')"
:aria-label="$i18n.get('label_thumbnail')">
<span>
@ -103,7 +151,8 @@
<!-- Name -->
<td
class="column-default-width column-main-content"
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name') + ': ' + collection.name">
<p
@ -121,7 +170,8 @@
<!-- Description -->
<td
class="column-large-width"
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
:label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_description') + ': ' + (collection.description != undefined && collection.description != '') ? collection.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`">
<p
@ -138,7 +188,8 @@
</td>
<!-- Creation Date -->
<td
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
class="table-creation column-default-width"
:label="$i18n.get('label_creation_date')"
:aria-label="$i18n.get('label_creation_date') + ': ' + collection.creation_date">
@ -156,7 +207,8 @@
</td>
<!-- Created by -->
<td
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
class="table-creation column-default-width"
:label="$i18n.get('label_created_by')"
:aria-label="$i18n.get('label_created_by') + ': ' + collection.author_name">
@ -174,7 +226,8 @@
</td>
<!-- Total items -->
<td
@click="onClickCollection($event, collection.id, index)"
@click.left="onClickCollection($event, collection.id, index)"
@click.right="onRightClickCollection($event, collection.id, index)"
class="column-small-width column-align-right"
:label="$i18n.get('label_total_items')"
v-if="collection.total_items != undefined"
@ -192,13 +245,14 @@
v-html="getTotalItems(collection.total_items)" />
</td>
<!-- Actions -->
<td
<td
@click="onClickCollection($event, collection.id, index)"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
<a
id="button-edit"
v-if="collection.current_user_can_edit"
:aria-label="$i18n.getFrom('collections','edit_item')"
@click.prevent.stop="goToCollectionEditPage(collection.id)">
<span class="icon">
@ -206,7 +260,8 @@
</span>
</a>
<a
id="button-delete"
id="button-delete"
v-if="collection.current_user_can_delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneCollection(collection.id)">
<span class="icon">
@ -235,7 +290,11 @@ export default {
selectedCollections: [],
allCollectionsOnPageSelected: false,
isSelectingCollections: false,
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png'
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
cursorPosX: -1,
cursorPosY: -1,
contextMenuIndex: null,
contextMenuCollection: null
}
},
props: {
@ -312,6 +371,7 @@ export default {
}
});
this.clearContextMenu();
},
deleteSelectedCollections() {
this.$modal.open({
@ -351,6 +411,25 @@ export default {
}
});
},
openCollection() {
if (this.contextMenuCollection != null) {
this.$router.push(this.$routerHelper.getCollectionPath(this.contextMenuCollection));
}
this.clearContextMenu();
},
openCollectionOnNewTab() {
if (this.contextMenuCollection != null) {
let routeData = this.$router.resolve(this.$routerHelper.getCollectionPath(this.contextMenuCollection));
window.open(routeData.href, '_blank');
}
this.clearContextMenu();
},
selectCollection() {
if (this.contextMenuIndex != null) {
this.$set(this.selectedCollections, this.contextMenuIndex, !this.selectedCollections[this.contextMenuIndex]);
}
this.clearContextMenu();
},
onClickCollection($event, collectionId, index) {
if ($event.ctrlKey) {
this.$set(this.selectedCollections, index, !this.selectedCollections[index]);
@ -360,6 +439,20 @@ export default {
},
goToCollectionEditPage(collectionId) {
this.$router.push(this.$routerHelper.getCollectionEditPath(collectionId));
},
onRightClickCollection($event, collectionId, index) {
$event.preventDefault();
this.cursorPosX = $event.clientX;
this.cursorPosY = $event.clientY;
this.contextMenuCollection = collectionId;
this.contextMenuIndex = index;
},
clearContextMenu() {
this.cursorPosX = -1;
this.cursorPosY = -1;
this.contextMenuCollection = null;
this.contextMenuIndex = null;
}
},
mounted() {
@ -429,6 +522,23 @@ export default {
.total-items-header {
text-align: right;
}
.context-menu {
.dropdown {
position: fixed;
z-index: 99999999999;
}
.context-menu-backdrop {
position: fixed;
top: 0;
right: 0;
left: 0;
border: 0;
width: 100%;
height: 100vh;
z-index: 9999999;
}
}
</style>

View File

@ -34,7 +34,7 @@
</section>
<draggable
class="active-filters-area"
@change="handleChange"
@change="handleChangeOnFilter"
:class="{'filters-area-receive': isDraggingFromAvailable}"
v-model="activeFilterList"
:options="{
@ -56,7 +56,9 @@
v-for="(filter, index) in activeFilterList"
:key="index">
<div class="handle">
<span class="icon grip-icon">
<span
v-if="!(isSelectingFilterType || filter.id == undefined || openedFilterId != '' || choosenMetadatum.name == filter.name || isUpdatingFiltersOrder == true || isRepositoryLevel)"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="icon icon-level-identifier">
@ -66,7 +68,7 @@
'tainacan-icon-repository': filter.collection_id != collectionId,
'has-text-turquoise5': filter.enabled && filter.collection_id == collectionId,
'has-text-blue5': filter.enabled && filter.collection_id != collectionId,
'has-text-gray': !filter.enabled
'has-text-gray3': !filter.enabled
}"
class="tainacan-icon" />
</span>
@ -113,38 +115,6 @@
</a>
</span>
</div>
<div v-if="choosenMetadatum.id == filter.id && openedFilterId == ''">
<form class="tainacan-form">
<b-field :label="$i18n.get('label_filter_type')">
<b-select
v-model="selectedFilterType"
:placeholder="$i18n.get('instruction_select_a_filter_type')">
<option
v-for="(filterType, index) in allowedFilterTypes"
:key="index"
:selected="index == 0"
:value="filterType">
{{ filterType.name }}</option>
</b-select>
</b-field>
<div class="field is-grouped form-submit">
<div class="control">
<button
class="button is-outlined"
@click.prevent="cancelFilterTypeSelection()"
slot="trigger">{{ $i18n.get('cancel') }}</button>
</div>
<div class="control">
<button
class="button is-success"
type="submit"
:disabled="Object.keys(selectedFilterType).length == 0"
@click.prevent="confirmSelectedFilterType()">{{ $i18n.get('next') }}</button>
</div>
</div>
</form>
</div>
<transition name="form-collapse">
<b-field v-if="openedFilterId == filter.id">
<filter-edition-form
@ -163,8 +133,9 @@
<div class="field" >
<h3 class="label has-text-secondary"> {{ $i18n.get('label_available_metadata') }}</h3>
<draggable
v-if="availableMetadatumList.length > 0"
v-model="availableMetadatumList"
@change="handleChangeOnMetadata"
v-if="availableMetadata.length > 0 && !isLoadingMetadatumTypes"
v-model="availableMetadata"
:options="{
sort: false,
group: { name:'filters', pull: !isSelectingFilterType, put: false, revertClone: true },
@ -177,7 +148,7 @@
'disabled-metadatum': isSelectingFilterType
}"
v-if="metadatum.enabled"
v-for="(metadatum, index) in availableMetadatumList"
v-for="(metadatum, index) in availableMetadata"
:key="index"
@click.prevent="addMetadatumViaButton(metadatum, index)">
<span class="icon grip-icon">
@ -193,7 +164,7 @@
</draggable>
<section
v-else
v-if="availableMetadata.length <= 0 && !isLoadingMetadatumTypes"
class="field is-grouped-centered section">
<div class="content has-text-gray has-text-centered">
<p>
@ -213,6 +184,77 @@
</div>
</div>
</div>
<b-modal
ref="filterTypeModal"
:width="680"
:active.sync="isSelectingFilterType">
<div
class="tainacan-modal-content"
style="width: auto">
<header class="tainacan-modal-title">
<h2>{{ this.$i18n.get('label_available_filter_types') }}</h2>
<hr>
</header>
<section class="tainacan-form">
<form class="tainacan-form">
<div class="columns">
<div class="column">
<div
role="list"
class="filter-types-container">
<p>{{ $i18n.get('instruction_click_to_select_a_filter_type') }}</p>
<br>
<div
role="listitem"
class="filter-type"
v-for="(filterType, index) in allowedFilterTypes"
:key="index"
@click="onFilterTypeSelected(filterType)"
@mouseover="currentFilterTypePreview = { name: filterType.name, template: filterType.preview_template }"
@mouseleave="currentFilterTypePreview = undefined">
<h4>{{ filterType.name }}</h4>
</div>
</div>
</div>
<div class="column">
<div
:style="{ 'min-height': getProperPreviewMinHeight() + 'px'}"
class="filter-type-preview">
<span class="filter-type-label">{{ $i18n.get('label_filter_type_preview') }}</span>
<div
v-if="currentFilterTypePreview != undefined && currentFilterTypePreview.template != ''"
class="field">
<span class="collapse-handle">
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
</span>
<label class="label has-tooltip">
{{ currentFilterTypePreview.name }}
</label>
</span>
<div v-html="currentFilterTypePreview.template"/>
</div>
<span
v-else
class="has-text-gray">
{{ $i18n.get('instruction_hover_a_filter_type_to_preview') }}
</span>
</div>
</div>
</div>
</form>
<footer class="field is-grouped form-submit">
<div class="control">
<button
class="button is-outlined"
type="button"
@click="onCancelFilterTypeSelection()">{{ $i18n.get('cancel') }}</button>
</div>
</footer>
</section>
</div>
</b-modal>
</div>
</template>
@ -241,9 +283,10 @@ export default {
allowedFilterTypes: [],
selectedFilterType: {},
choosenMetadatum: {},
newIndex: 0,
availableMetadatumList: [],
filterTypes: []
newFilterIndex: 0,
availableMetadata: [],
filterTypes: [],
currentFilterTypePreview: undefined
}
},
computed: {
@ -289,8 +332,8 @@ export default {
'fetchFilters',
'sendFilter',
'deleteFilter',
'addTemporaryFilter',
'deleteTemporaryFilter',
// 'addTemporaryFilter',
// 'deleteTemporaryFilter',
'updateFilters',
'updateCollectionFiltersOrder'
]),
@ -307,9 +350,9 @@ export default {
...mapActions('collection', [
'fetchCollectionName'
]),
handleChange($event) {
handleChangeOnFilter($event) {
if ($event.added) {
this.addNewFilter($event.added.element, $event.added.newIndex);
this.prepareFilterTypeSelection($event.added.element, $event.added.newIndex);
} else if ($event.removed) {
this.removeFilter($event.removed.element);
} else if ($event.moved) {
@ -317,6 +360,63 @@ export default {
this.updateFiltersOrder();
}
},
prepareFilterTypeSelection(choosenMetadatum, newFilterIndex) {
this.choosenMetadatum = choosenMetadatum;
this.newFilterIndex = newFilterIndex;
this.allowedFilterTypes = [];
this.selectedFilterType = {};
for (let filter of this.filterTypes) {
for (let supportedType of filter['supported_types']) {
if (choosenMetadatum.metadata_type_object.primitive_type == supportedType)
this.allowedFilterTypes.push(filter);
}
}
this.isSelectingFilterType = true;
},
addMetadatumViaButton(metadatum, metadatumIndex) {
this.oldMetadatumIndex = metadatumIndex;
// Removes element from metadata list, as from button this does not happens
this.availableMetadata.splice(metadatumIndex, 1);
// Inserts it at the end of the list
let lastFilterIndex = this.activeFilterList.length;
// // Updates store with temporary Filter
// this.addTemporaryFilter(metadatumType);
this.prepareFilterTypeSelection(metadatum, lastFilterIndex);
},
onFilterTypeSelected(filterType) {
this.isSelectingFilterType = false;
this.allowedFilterTypes = [];
this.currentFilterTypePreview = undefined;
this.selectedFilterType = filterType;
this.createChoosenFilter();
},
onCancelFilterTypeSelection() {
this.isSelectingFilterType = false;
this.allowedFilterTypes = [];
this.currentFilterTypePreview = undefined;
this.selectedFilterType = {};
// Puts element back to metadata list
this.availableMetadata.splice(this.oldMetadatumIndex, 0, this.choosenMetadatum)
this.choosenMetadatum = {};
// Removes element from filters list
this.activeFilterList.splice(this.newFilterIndex, 1);
},
handleChangeOnMetadata($event) {
if ($event.removed) {
this.oldMetadatumIndex = $event.removed.oldIndex;
}
},
updateFiltersOrder() {
let filtersOrder = [];
for (let filter of this.activeFilterList) {
@ -340,7 +440,7 @@ export default {
}
}
this.availableMetadatumList = availableMetadata;
this.availableMetadata = availableMetadata;
},
onChangeEnable($event, index) {
let filtersOrder = [];
@ -353,34 +453,6 @@ export default {
.then(() => { this.isUpdatingFiltersOrder = false; })
.catch(() => { this.isUpdatingFiltersOrder = false; });
},
addMetadatumViaButton(metadatumType, metadatumIndex) {
if (this.isSelectingFilterType == false) {
this.isSelectingFilterType = true;
this.availableMetadatumList.splice(metadatumIndex, 1);
let lastIndex = this.activeFilterList.length;
// Updates store with temporary Filter
this.addTemporaryFilter(metadatumType);
this.addNewFilter(metadatumType, lastIndex);
}
},
addNewFilter(choosenMetadatum, newIndex) {
this.choosenMetadatum = choosenMetadatum;
this.newIndex = newIndex;
this.openedFilterId = '';
this.allowedFilterTypes = [];
this.selectedFilterType = {};
for (let filter of this.filterTypes) {
for (let supportedType of filter['supported_types']) {
if (choosenMetadatum.metadata_type_object.primitive_type == supportedType)
this.allowedFilterTypes.push(filter);
}
}
},
createChoosenFilter() {
this.sendFilter({
collectionId: this.collectionId,
@ -389,14 +461,14 @@ export default {
filterType: this.selectedFilterType.name,
status: 'auto-draft',
isRepositoryLevel: this.isRepositoryLevel,
newIndex: this.newIndex
newIndex: this.newFilterIndex
})
.then((filter) => {
if (!this.isRepositoryLevel)
this.updateFiltersOrder();
this.newIndex = 0;
this.newFilterIndex = 0;
this.choosenMetadatum = {};
this.selectedFilterType = {}
this.allowedFilterTypes = [];
@ -405,7 +477,7 @@ export default {
})
.catch((error) => {
this.$console.error(error);
this.newIndex = 0;
this.newFilterIndex = 0;
this.choosenMetadatum = {};
this.selectedFilterType = {}
this.allowedFilterTypes = [];
@ -429,12 +501,12 @@ export default {
},
cancelFilterTypeSelection() {
this.isSelectingFilterType = false;
this.availableMetadatumList.push(this.choosenMetadatum);
this.availableMetadata.push(this.choosenMetadatum);
this.choosenMetadatum = {};
this.allowedFilterTypes = [];
this.selectedFilterType = {};
this.deleteTemporaryFilter(this.newIndex);
this.newIndex = 0;
// this.deleteTemporaryFilter(this.newFilterIndex);
this.newFilterIndex = 0;
},
editFilter(filter) {
// Closing collapse
@ -445,12 +517,12 @@ export default {
} else {
if (this.openedFilterId == '' && this.choosenMetadatum.id != undefined) {
this.availableMetadatumList.push(this.choosenMetadatum);
this.availableMetadata.push(this.choosenMetadatum);
this.choosenMetadatum = {};
this.allowedFilterTypes = [];
this.selectedFilterType = {};
this.deleteTemporaryFilter(this.newIndex);
this.newIndex = 0;
// this.deleteTemporaryFilter(this.newFilterIndex);
this.newFilterIndex = 0;
}
this.openedFilterId = filter.id;
// First time opening
@ -475,6 +547,17 @@ export default {
this.formWithErrors = '';
delete this.editForms[this.openedFilterId];
this.openedFilterId = '';
},
getProperPreviewMinHeight() {
for (let filterType of this.allowedFilterTypes) {
if (filterType.component == 'tainacan-filter-taginput' ||
filterType.component == 'tainacan-filter-checkbox' ||
filterType.component == 'tainacan-filter-taxonomy-taginput' ||
filterType.component == 'tainacan-filter-taxonomy-checkbox') {
return 330;
}
}
return 190;
}
},
mounted() {
@ -520,9 +603,15 @@ export default {
// Obtains collection name
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
if (!this.isRepositoryLevel) {
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
}
// Sets modal callback function
this.$refs.filterTypeModal.onCancel = () => {
this.onCancelFilterTypeSelection();
}
}
}
@ -681,9 +770,6 @@ export default {
.metadatum-name {
color: $secondary;
}
.handle .label-details, .handle .icon {
color: $gray3 !important;
}
}
&.disabled-metadatum {
color: $gray3;
@ -849,7 +935,7 @@ export default {
}
}
.inherited-filter {
.inherited-filter {
&.active-filter-item:hover:not(.not-sortable-item) {
background-color: $blue5;
border-color: $blue5;
@ -879,6 +965,102 @@ export default {
}
}
.tainacan-modal-content {
.column {
overflow: visible;
}
.filter-types-container {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
p { margin-bottom: 16px; }
.filter-type {
border-bottom: 1px solid $gray2;
padding: 15px 8.3333333%;
cursor: pointer;
&:first-child {
margin-top: 15px;
}
&:last-child {
border-bottom: none;
}
&:hover {
background-color: $gray2;
}
}
}
.filter-type-preview {
background: $gray1;
margin: 12px auto;
padding: 12px 30px;
border-radius: 3px;
z-index: 9999999999999;
width: 218px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
cursor: none;
flex-wrap: wrap;
max-width: 260px;
width: 100%;
height: 100%;
min-height: 290px;
align-items: normal;
@media screen and (max-width: 769px) {
max-width: 100%;
}
.filter-type-label {
font-weight: 600;
color: $gray4;
width: 100%;
font-size: 1rem;
margin-left: -16px;
}
input, select, textarea,
.input, .tags, .tag {
pointer-events: none;
cursor: none;
background-color: rgba(255,255,255,0.60) !important;
}
.autocomplete>.control, .autocomplete>.control>input, .dropdown-content {
background-color: $gray0 !important;
}
.taginput {
margin-bottom: 80px;
}
input[type="checkbox"]:checked + .check {
background: rgba(255,255,255,0.60) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3Cpath style='fill:rgb(69,70,71)' d='M 0.04038059,0.6267767 0.14644661,0.52071068 0.42928932,0.80355339 0.3232233,0.90961941 z M 0.21715729,0.80355339 0.85355339,0.16715729 0.95961941,0.2732233 0.3232233,0.90961941 z'%3E%3C/path%3E%3C/svg%3E") no-repeat center center !important
}
textarea {
min-height: 70px;
}
.field {
width: 100%;
margin: 16px;
.label {
color: $gray5;
font-weight: normal;
}
}
.add-new-term {
font-size: 0.75rem;
text-decoration: underline;
margin: 0.875rem 1.5rem;
}
}
}
}
</style>

View File

@ -8,7 +8,7 @@
<div class="field select-all is-pulled-left">
<span>
<b-checkbox
@click.native="selectAllItemsOnPage()"
@click.native.prevent="selectAllItemsOnPage()"
:value="allItemsOnPageSelected">
{{ $i18n.get('label_select_all_items_page') }}
</b-checkbox>
@ -16,11 +16,11 @@
<span
style="margin-left: 10px"
v-if="allItemsOnPageSelected && items.length > 1">
v-if="enableSelectAllItemsPages == true && allItemsOnPageSelected && items.length > 1">
<b-checkbox
@click.native="selectAllItems()"
@click.native.prevent="selectAllItems()"
v-model="isAllItemsSelected">
{{ `${$i18n.get('label_select_all')} ${totalItems} ${$i18n.get('items').toLowerCase()}` }}
{{ `${$i18n.getWithVariables('label_select_all_%s_items', [totalItems])}` }}
</b-checkbox>
</span>
</div>
@ -31,7 +31,8 @@
position="is-bottom-left"
v-if="items.length > 0 && items[0].current_user_can_edit"
:disabled="selectedItemsIDs.every(id => id === false) || this.selectedItemsIDs.filter(item => item !== false).length <= 1"
id="bulk-actions-dropdown">
id="bulk-actions-dropdown"
aria-role="list">
<button
class="button is-white"
slot="trigger">
@ -43,23 +44,27 @@
<b-dropdown-item
v-if="$route.params.collectionId && $userCaps.hasCapability('edit_others_posts') && !isOnTrash"
@click="openBulkEditionModal()">
@click="openBulkEditionModal()"
aria-role="listitem">
{{ $i18n.get('label_bulk_edit_selected_items') }}
</b-dropdown-item>
<b-dropdown-item
v-if="$route.params.collectionId && $userCaps.hasCapability('edit_others_posts') && !isOnTrash"
@click="sequenceEditSelectedItems()">
@click="sequenceEditSelectedItems()"
aria-role="listitem">
{{ $i18n.get('label_sequence_edit_selected_items') }}
</b-dropdown-item>
<b-dropdown-item
v-if="collectionId"
@click="deleteSelectedItems()"
id="item-delete-selected-items">
id="item-delete-selected-items"
aria-role="listitem">
{{ isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('label_send_to_trash') }}
</b-dropdown-item>
<b-dropdown-item
v-if="collectionId && isOnTrash"
@click="untrashSelectedItems()">
@click="untrashSelectedItems()"
aria-role="listitem">
{{ $i18n.get('label_untrash_selected_items') }}
</b-dropdown-item>
</b-dropdown>
@ -67,6 +72,48 @@
</div>
<div class="table-wrapper">
<!-- Context menu for right click selection -->
<div
v-if="cursorPosY > 0 && cursorPosX > 0"
class="context-menu">
<!-- Backdrop for escaping context menu -->
<div
@click.left="clearContextMenu()"
@click.right="clearContextMenu()"
class="context-menu-backdrop" />
<b-dropdown
inline
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }">
<b-dropdown-item
@click="openItem()"
v-if="!isOnTrash">
{{ $i18n.getFrom('items','view_item') }}
</b-dropdown-item>
<b-dropdown-item
@click="openItemOnNewTab()"
v-if="!isOnTrash">
{{ $i18n.get('label_open_item_new_tab') }}
</b-dropdown-item>
<b-dropdown-item
@click="selectItem()"
v-if="contextMenuIndex != null">
{{ !selectedItems[contextMenuIndex] ? $i18n.get('label_select_item') : $i18n.get('label_unselect_item') }}
</b-dropdown-item>
<b-dropdown-item
@click="goToItemEditPage(contextMenuItem)"
v-if="contextMenuItem != null && contextMenuItem.current_user_can_edit">
{{ $i18n.getFrom('items','edit_item') }}
</b-dropdown-item>
<b-dropdown-item
@click="deleteOneItem(contextMenuItem.id)"
v-if="contextMenuItem != null && contextMenuItem.current_user_can_edit">
{{ $i18n.get('label_delete_item') }}
</b-dropdown-item>
</b-dropdown>
</div>
<!-- GRID (THUMBNAILS) VIEW MODE -->
<div
@ -109,7 +156,8 @@
autoHide: false,
placement: 'auto-start'
}"
@click="onClickItem($event, item, index)">
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)">
{{ item.title != undefined ? item.title : '' }}
</p>
</div>
@ -117,7 +165,8 @@
<!-- Thumbnail -->
<a
v-if="item.thumbnail != undefined"
@click="onClickItem($event, item, index)"
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)"
class="grid-item-thumbnail"
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)) + ')' }">
<img
@ -201,16 +250,18 @@
:style="{
'padding-left': !collectionId ? '0 !important' : '1rem'
}"
@click="onClickItem($event, item, index)"
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)"
class="metadata-title">
<p>{{ item.title != undefined ? item.title : '' }}</p>
</div>
<!-- Thumbnail -->
<div
@click="onClickItem($event, item, index)"
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)"
v-if="item.thumbnail != undefined"
class="thumbnail"
class="tainacan-masonry-item-thumbnail"
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][0] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[0] : thumbPlaceholderPath)) + ')' }">
<img
:alt="$i18n.get('label_thumbnail')"
@ -292,7 +343,8 @@
autoHide: false,
placement: 'auto-start'
}"
@click="onClickItem($event, item, index)">
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)">
{{ item.title != undefined ? item.title : '' }}
</p>
</div>
@ -334,7 +386,8 @@
<!-- Remaining metadata -->
<div
class="media"
@click="onClickItem($event, item, index)">
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)">
<div
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)) + ')' }"
class="card-thumbnail">
@ -352,13 +405,13 @@
show: 500,
hide: 300,
},
content: item.description != undefined && item.description != '' ? item.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`,
content: item.description != undefined && item.description != '' ? item.description : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`,
html: true,
autoHide: false,
placement: 'auto-start'
}"
class="metadata-description"
v-html="item.description != undefined && item.description != '' ? getLimitedDescription(item.description) : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`" />
v-html="item.description != undefined && item.description != '' ? getLimitedDescription(item.description) : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`" />
<!-- Author-->
<p
v-tooltip="{
@ -444,7 +497,8 @@
v-for="(column, columnIndex) in tableMetadata"
:key="columnIndex"
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click="onClickItem($event, item, index)"
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-tooltip="{
@ -460,7 +514,8 @@
v-for="(column, columnIndex) in tableMetadata"
:key="columnIndex"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click="onClickItem($event, item, index)"
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)"
v-html="item.title != undefined ? item.title : ''" />
</div>
<!-- Actions -->
@ -501,9 +556,10 @@
<!-- Remaining metadata -->
<div
class="media"
@click="onClickItem($event, item, index)">
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)">
<div class="list-metadata media-body">
<div class="thumbnail">
<div class="tainacan-record-thumbnail">
<img
:alt="$i18n.get('label_thumbnail')"
v-if="item.thumbnail != undefined"
@ -606,7 +662,8 @@
column.metadata_type_object.primitive_type == 'compound') : false,
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' || column.metadata_type_object.related_mapped_prop == 'description') : false,
}"
@click="onClickItem($event, item, index)">
@click.left="onClickItem($event, item, index)"
@click.right="onRightClickItem($event, item, index)">
<p
v-tooltip="{
@ -614,7 +671,7 @@
show: 500,
hide: 300,
},
content: item.title != undefined && item.title != '' ? item.title : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
content: item.title != undefined && item.title != '' ? item.title : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
html: true,
autoHide: false,
placement: 'auto-start'
@ -622,14 +679,14 @@
v-if="collectionId == undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object.related_mapped_prop == 'title'"
v-html="(item.title != undefined && item.title != '') ? item.title : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
v-html="(item.title != undefined && item.title != '') ? item.title : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
<p
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: item.description != undefined && item.description != '' ? item.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
content: item.description != undefined && item.description != '' ? item.description : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
html: true,
autoHide: false,
placement: 'auto-start'
@ -637,14 +694,14 @@
v-if="collectionId == undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object.related_mapped_prop == 'description'"
v-html="(item.description != undefined && item.description) != '' ? item.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
v-html="(item.description != undefined && item.description) != '' ? item.description : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
<p
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: renderMetadata(item.metadata, column) != '' ? renderMetadata(item.metadata, column) : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
content: renderMetadata(item.metadata, column) != '' ? renderMetadata(item.metadata, column) : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`,
html: true,
autoHide: false,
placement: 'auto-start'
@ -656,7 +713,7 @@
column.metadatum !== 'row_author' &&
column.metadatum !== 'row_title' &&
column.metadatum !== 'row_description'"
v-html="renderMetadata(item.metadata, column) != '' ? renderMetadata(item.metadata, column, column.metadata_type_object.component) : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
v-html="renderMetadata(item.metadata, column) != '' ? renderMetadata(item.metadata, column, column.metadata_type_object.component) : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
<span v-if="column.metadatum == 'row_thumbnail'">
<img
@ -740,6 +797,11 @@ export default {
selectedItemsIDs: [],
queryAllItemsSelected: {},
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
cursorPosX: -1,
cursorPosY: -1,
contextMenuIndex: null,
contextMenuItem: null,
enableSelectAllItemsPages: tainacan_plugin.enable_select_all_items_pages
}
},
props: {
@ -830,13 +892,15 @@ export default {
for (let i = 0; i < this.selectedItems.length; i++) {
this.selectedItems.splice(i, 1, !this.allItemsOnPageSelected);
}
if (!this.allItemsOnPageSelected)
this.queryAllItemsSelected = {};
},
selectAllItems(){
this.isAllItemsSelected = !this.isAllItemsSelected;
this.queryAllItemsSelected = this.$route.query;
for (let i = 0; i < this.selectedItems.length; i++) {
this.selectedItems.splice(i, 1, !this.isAllItemsSelected);
this.selectedItems.splice(i, 1, this.isAllItemsSelected);
}
},
untrashOneItem(itemId) {
@ -849,6 +913,7 @@ export default {
message: this.$i18n.get('info_warning_remove_item_from_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.createEditGroup({
collectionID: this.collectionId,
@ -877,6 +942,7 @@ export default {
message: this.isOnTrash ? this.$i18n.get('info_warning_item_delete') : this.$i18n.get('info_warning_item_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.deleteItem({
itemId: itemId,
@ -887,6 +953,7 @@ export default {
}
}
});
this.clearContextMenu();
},
untrashSelectedItems(){
this.$modal.open({
@ -898,6 +965,7 @@ export default {
message: this.$i18n.get('info_warning_selected_items_remove_from_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.createEditGroup({
collectionID: this.collectionId,
@ -926,6 +994,7 @@ export default {
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_items_delete') : this.$i18n.get('info_warning_selected_items_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.createEditGroup({
collectionID: this.collectionId,
@ -953,6 +1022,25 @@ export default {
}
});
},
openItem() {
if (this.contextMenuItem != null) {
this.$router.push(this.$routerHelper.getItemPath(this.contextMenuItem.collection_id, this.contextMenuItem.id));
}
this.clearContextMenu();
},
openItemOnNewTab() {
if (this.contextMenuItem != null) {
let routeData = this.$router.resolve(this.$routerHelper.getItemPath(this.contextMenuItem.collection_id, this.contextMenuItem.id));
window.open(routeData.href, '_blank');
}
this.clearContextMenu();
},
selectItem() {
if (this.contextMenuIndex != null) {
this.$set(this.selectedItems, this.contextMenuIndex, !this.selectedItems[this.contextMenuIndex]);
}
this.clearContextMenu();
},
onClickItem($event, item, index) {
if ($event.ctrlKey || $event.shiftKey) {
this.$set(this.selectedItems, index, !this.selectedItems[index]);
@ -969,6 +1057,20 @@ export default {
}
}
},
onRightClickItem($event, item, index) {
$event.preventDefault();
this.cursorPosX = $event.clientX;
this.cursorPosY = $event.clientY;
this.contextMenuItem = item;
this.contextMenuIndex = index;
},
clearContextMenu() {
this.cursorPosX = -1;
this.cursorPosY = -1;
this.contextMenuItem = null;
this.contextMenuIndex = null;
},
goToItemEditPage(item) {
this.$router.push(this.$routerHelper.getItemEditPath(item.collection_id, item.id));
},
@ -978,8 +1080,6 @@ export default {
if (!metadata || itemMetadata == undefined) {
return '';
} else if (metadata.date_i18n) {
return metadata.date_i18n;
} else {
if (component != undefined && component == 'tainacan-textarea')
return metadata.value_as_string;
@ -1021,6 +1121,23 @@ export default {
}
}
.context-menu {
.dropdown {
position: fixed;
z-index: 99999999999;
}
.context-menu-backdrop {
position: fixed;
top: 0;
right: 0;
left: 0;
border: 0;
width: 100%;
height: 100vh;
z-index: 9999999;
}
}
</style>

View File

@ -60,7 +60,9 @@
v-for="(metadatum, index) in activeMetadatumList"
:key="index">
<div class="handle">
<span class="icon grip-icon">
<span
v-if="!(isRepositoryLevel || metadatum.id == undefined || openedMetadatumId != '' || isUpdatingMetadataOrder)"
class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="icon icon-level-identifier">
@ -70,7 +72,7 @@
'tainacan-icon-repository': (metadatum.collection_id == 'default') || isRepositoryLevel,
'has-text-turquoise5': metadatum.enabled && (metadatum.collection_id != 'default' && !isRepositoryLevel),
'has-text-blue5': metadatum.enabled && (metadatum.collection_id == 'default' || isRepositoryLevel),
'has-text-gray': !metadatum.enabled
'has-text-gray3': !metadatum.enabled
}"
class="tainacan-icon" />
</span>
@ -171,25 +173,21 @@
:class="{ 'hightlighted-metadatum' : hightlightedMetadatum == metadatum.name, 'inherited-metadatum': isRepositoryLevel }"
v-for="(metadatum, index) in availableMetadatumList"
:key="index">
<div
v-if="metadatum.preview_template"
class="metadata-type-preview tainacan-form">
<div class="field">
<span class="collapse-handle">
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
</span>
<label class="label has-tooltip">
{{ metadatum.name }}
</label>
</span>
<div v-html="metadatum.preview_template"/>
</div>
</div>
<span class="icon grip-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-drag"/>
</span>
<span class="metadatum-name">{{ metadatum.name }}</span>
<span class="metadatum-name">
{{ metadatum.name }}
<span
v-tooltip.top="{
classes: ['metadata-type-preview-tooltip'],
content: getPreviewTemplateContent(metadatum),
html: true
}"
class="icon preview-help-icon has-text-secondary">
<i class="tainacan-icon tainacan-icon-help"/>
</span>
</span>
<span
class="loading-spinner"
v-if="hightlightedMetadatum == metadatum.name"/>
@ -199,7 +197,8 @@
</div>
</div>
</b-tab-item>
<!-- Exposer -->
<!-- Exposer --------------- -->
<b-tab-item
:label="$i18n.get('mapping')"
v-model="activeMetadatumList">
@ -221,7 +220,6 @@
<div class="field is-grouped form-submit">
<b-select
id="mappers-options-dropdown"
class="button is-secondary"
:placeholder="$i18n.get('instruction_select_a_mapper')">
<option
v-for="metadatum_mapper in metadatum_mappers"
@ -792,6 +790,22 @@ export default {
.catch(() => {
this.isLoadingMetadata = false;
});
},
getPreviewTemplateContent(metadatum) {
return `<div class="metadata-type-preview tainacan-form">
<span class="metadata-type-label">` + this.$i18n.get('label_metadatum_type_preview') + `</span>
<div class="field">
<span class="collapse-handle">
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
<label class="label has-tooltip">`
+ metadatum.name +
`</label>
</span>
<div>` + metadatum.preview_template + `</div>
</div>
</div>`;
}
},
mounted() {
@ -820,9 +834,11 @@ export default {
});
// Obtains collection name
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
if (!this.isRepositoryLevel) {
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
}
}
}
</script>
@ -861,7 +877,12 @@ export default {
width: 100%;
}
}
.b-tabs .tab-content {
overflow: visible;
min-height: 500px;
}
.column:not(.available-metadata-area){
overflow: hidden;
flex-grow: 2;
@ -869,11 +890,11 @@ export default {
.page-title {
border-bottom: 1px solid $secondary;
margin: 1em 0em 2.0em 0em;
h2 {
color: $blue5;
font-weight: 500;
}
margin: 1em 0em 2.0em 0em;
}
.w-100 {
@ -992,9 +1013,6 @@ export default {
.metadatum-name {
color: $secondary;
}
.handle .label-details, .handle .icon {
color: $gray3 !important;
}
}
&.disabled-metadatum {
color: $gray3;
@ -1094,6 +1112,10 @@ export default {
position: relative;
bottom: 1px;
}
.preview-help-icon {
position: absolute;
top: 6px;
}
.metadatum-name {
text-overflow: ellipsis;
overflow-x: hidden;
@ -1130,48 +1152,18 @@ export default {
border-bottom-width: 20px;
left: -20px;
}
&:hover {
.metadata-type-preview {
visibility: visible;
opacity: 1;
left: -210px;
transition-delay: 1s;
&::before {
border-color: transparent $gray1 transparent transparent;
border-left-width: 16px;
border-top-width: 20px;
border-bottom-width: 20px;
right: -19px;
}
}
}
.metadata-type-preview {
position: absolute;
background: $gray1;
padding: 12px;
border-radius: 3px;
z-index: 9999999999999;
width: 180px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
left: -180px;
top: -40px;
visibility: hidden;
opacity: 0;
transition: opacity ease 0.3s, visibility ease 0.3s, left ease 0.3s;
transition-delay: 0.1s;
}
}
.sortable-drag {
opacity: 1 !important;
}
.sortable-chosen {
.metadata-type-preview {
display: none;
}
}
@keyframes hightlighten {
0% {
color: #222;
@ -1289,10 +1281,6 @@ export default {
}
}
#mappers-options-dropdown {
background-color: transparent;
color: #fff;
}
}

View File

@ -62,6 +62,7 @@
</a>
</span>
</div>
<transition-group
class="children-area"
name="filter-item">
@ -137,7 +138,7 @@ export default {
this.$termsListBus.onAddNewChildTerm(this.term.id);
},
toggleShowChildren() {
if (this.term.children == undefined || this.term.children.length <= 0) {
if (!this.isLoadingTerms && (this.term.children == undefined || this.term.children.length <= 0)) {
this.loadChildTerms(this.term.id);
} else {
this.showChildren = !this.showChildren;
@ -242,7 +243,27 @@ export default {
eventOnEditTerm() {
this.isEditingTerm = true;
},
eventOnTermEditionSaved() {
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.term.opened = false;
},

View File

@ -16,7 +16,8 @@
position="is-bottom-left"
v-if="$userCaps.hasCapability('delete_tainacan-taxonomies')"
:disabled="!isSelecting"
id="bulk-actions-dropdown">
id="bulk-actions-dropdown"
aria-role="list">
<button
class="button is-white"
slot="trigger">
@ -28,10 +29,13 @@
<b-dropdown-item
id="item-delete-selected-items"
@click="deleteSelected()">
@click="deleteSelected()"
aria-role="listitem">
{{ $i18n.get('label_delete_selected_taxonomies') }}
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_taxonomies') + ' (Not ready)' }}
<b-dropdown-item
disabled
aria-role="listitem">{{ $i18n.get('label_edit_selected_taxonomies') + ' (Not ready)' }}
</b-dropdown-item>
</b-dropdown>
</div>
@ -54,6 +58,10 @@
<th>
<div class="th-wrap">{{ $i18n.get('label_description') }}</div>
</th>
<!-- Collections -->
<th>
<div class="th-wrap">{{ $i18n.get('label_collections_using') }}</div>
</th>
<!-- Actions -->
<th class="actions-header">
&nbsp;
@ -110,6 +118,25 @@
}"
v-html="(taxonomy.description != undefined && taxonomy.description != '') ? taxonomy.description : `<span class='has-text-gray is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`" />
</td>
<!-- Collections using -->
<td
class="column-large-width has-text-gray "
:class="{ 'is-italic' : !(taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) }"
:label="$i18n.get('label_collections_using')"
:aria-label="(taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? taxonomy.collections.toString() : $i18n.get('label_no_collections_using_taxonomy')">
<p
@click.self="onClickTaxonomy($event, taxonomy.id, index)"
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: (taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections) : $i18n.get('label_no_collections_using_taxonomy'),
autoHide: false,
placement: 'auto-start'
}"
v-html="(taxonomy.collections != undefined && taxonomy.collections.length != undefined && taxonomy.collections.length > 0) ? renderListOfCollections(taxonomy.collections) : $i18n.get('label_no_collections_using_taxonomy')" />
</td>
<!-- Actions -->
<td
@click="onClickTaxonomy($event, taxonomy.id, index)"
@ -153,7 +180,8 @@
return {
selected: [],
allOnPageSelected: false,
isSelecting: false
isSelecting: false,
adminUrl: tainacan_plugin.admin_url
}
},
props: {
@ -272,7 +300,24 @@
} else {
this.$router.push(this.$routerHelper.getTaxonomyEditPath(taxonomyId));
}
}
},
renderListOfCollections(collections) {
let htmlList = '';
for (let i = 0; i < collections.length; i++) {
htmlList += `<a target="_blank" href=${ this.adminUrl + 'admin.php?page=tainacan_admin#' + this.$routerHelper.getCollectionPath(collections[i].id)}>${collections[i].name}</a>`;
if (collections.length > 2 && i > 0 && i < collections.length - 1) {
if (i < collections.length - 2)
htmlList += ', '
else
htmlList += ' ' + this.$i18n.get('label_and') + ' ';
} else if (collections.length == 2 && i == 0) {
htmlList += ' ' + this.$i18n.get('label_and') + ' ';
}
}
return htmlList;
}
}
}
</script>

View File

@ -41,7 +41,8 @@
:disabled="isEditingTerm">
<span
@click="searchTerms(0)"
class="icon is-right">
class="icon is-right"
:class="{ 'has-text-gray3': isEditingTerm }">
<i class="tainacan-icon tainacan-icon-search" />
</span>
</div>
@ -241,6 +242,29 @@ export default {
},
onTermEditionFinished($event) {
this.$termsListBus.onTermEditionSaved($event);
for (let i = 0; i < this.termsList.length; i++) {
if (this.termsList[i].id == $event.term.id) {
this.$set(this.termsList[i], 'description', $event.term.description);
this.$set(this.termsList[i], 'header_image', $event.term.header_image);
this.$set(this.termsList[i], 'header_image_id', $event.term.header_image_id);
this.$set(this.termsList[i], 'name', $event.term.name);
this.$set(this.termsList[i], 'parent', $event.term.parent);
this.$set(this.termsList[i], 'id', $event.term.id);
}
else if (this.termsList[i].children != undefined) {
for (let j = 0; j < this.termsList[i].children.length; j++) {
if (this.termsList[i].children[j].id == $event.term.id) {
this.$set(this.termsList[i].children[j], 'description', $event.term.description);
this.$set(this.termsList[i].children[j], 'header_image', $event.term.header_image);
this.$set(this.termsList[i].children[j], 'header_image_id', $event.term.header_image_id);
this.$set(this.termsList[i].children[j], 'name', $event.term.name);
this.$set(this.termsList[i].children[j], 'parent', $event.term.parent);
this.$set(this.termsList[i].children[j], 'id', $event.term.id);
}
}
}
}
},
onTermEditionCanceled($event) {

View File

@ -55,89 +55,93 @@
<li
:class="activeRoute == 'ItemPage' || activeRoute == 'CollectionItemsPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionItemsPath(id, '') }"
:aria-label="$i18n.get('label_collection_items')">
<b-tooltip
<b-tooltip
:label="$i18n.get('items')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionItemsPath(id, '') }"
:aria-label="$i18n.get('label_collection_items')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-items"/>
</span>
</b-tooltip>
<!-- <span class="menu-text">{{ $i18n.get('items') }}</span> -->
</router-link>
<!-- <span class="menu-text">{{ $i18n.get('items') }}</span> -->
</router-link>
</b-tooltip>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'CollectionEditionForm' ? 'is-active':''"
class="level-item">
<router-link
<b-tooltip
:label="$i18n.get('label_settings')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionEditPath(id) }"
:aria-label="$i18n.get('label_settings')">
<b-tooltip
:label="$i18n.get('label_settings')"
position="is-bottom">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-settings"/>
</span>
</b-tooltip>
<!-- <span class="menu-text">{{ $i18n.get('label_settings') }}</span> -->
</router-link>
</router-link>
</b-tooltip>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'MetadataList' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionMetadataPath(id) }"
:aria-label="$i18n.get('label_collection_metadata')">
<b-tooltip
:label="$i18n.getFrom('metadata', 'name')"
position="is-bottom">
<b-tooltip
:label="$i18n.getFrom('metadata', 'name')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionMetadataPath(id) }"
:aria-label="$i18n.get('label_collection_metadata')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/>
</span>
</b-tooltip>
<!-- <span class="menu-text">{{ $i18n.getFrom('metadata', 'name') }}</span> -->
</router-link>
</router-link>
</b-tooltip>
</li>
<li
v-if="currentUserCanEdit"
:class="activeRoute == 'FiltersList' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionFiltersPath(id) }"
:aria-label="$i18n.get('label_collection_filters')">
<b-tooltip
animated
:label="$i18n.getFrom('filters', 'name')"
position="is-bottom">
<b-tooltip
animated
:label="$i18n.getFrom('filters', 'name')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionFiltersPath(id) }"
:aria-label="$i18n.get('label_collection_filters')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/>
</span>
</b-tooltip>
<!-- <span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span> -->
</router-link>
</router-link>
</b-tooltip>
</li>
<li
:class="activeRoute == 'CollectionActivitiesPage' ? 'is-active':''"
class="level-item">
<b-tooltip
:label="$i18n.get('activities')"
position="is-bottom">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionActivitiesPath(id) }"
:aria-label="$i18n.get('label_collection_activities')">
<b-tooltip
:label="$i18n.get('activities')"
position="is-bottom">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-activities"/>
</span>
</b-tooltip>
<!-- <span class="menu-text">{{ $i18n.get('activities') }}</span> -->
</router-link>
</router-link>
</b-tooltip>
</li>
</ul>
@ -162,6 +166,7 @@ export default {
},
props: {
id: Number,
currentUserCanEdit: Boolean
},
watch: {
'$route' (to, from) {

View File

@ -53,13 +53,14 @@
<b-dropdown
ref="advancedSearchShortcut"
class="advanced-search-header-dropdown"
position="is-bottom-left">
position="is-bottom-left"
aria-role="list">
<a
class="advanced-search-text"
slot="trigger">
{{ $i18n.get('advanced_search') }}
</a>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<div :style="{'height': '25px'}">
<p class="is-pulled-left advanced-search-text-di">{{ $i18n.get('advanced_search') }}</p>
<span
@ -72,7 +73,8 @@
</b-dropdown-item>
<b-dropdown-item
style="padding-left: 0 !important; padding-right: 0 !important;"
:custom="true">
:custom="true"
aria-role="listitem">
<advanced-search
:is-repository-level="true"
:is-header="true"/>
@ -94,7 +96,7 @@
class="level-item"
:href="wordpressAdmin">
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-wordpress"/>
<i class="tainacan-icon tainacan-icon-wordpress"/>
</span>
</a>
</div>
@ -208,6 +210,10 @@
.button:hover, .button:active, .button:focus {
background-color: white !important;
}
.tainacan-icon-wordpress {
font-size: 26px;
}
.search-area {
display: flex;

View File

@ -105,6 +105,14 @@ export default {
return this.getCollectionURL();
}
},
watch: {
'$route' (to, from) {
if (!this.isRepositoryLevel && from.path != undefined && to.path != from.path) {
this.collectionId = this.$route.params.collectionId;
this.fetchCollectionNameAndURL(this.collectionId);
}
}
},
methods: {
...mapActions('collection', [
'fetchCollectionNameAndURL'
@ -114,6 +122,7 @@ export default {
'getCollectionURL'
]),
openAvailableExportersModal(){
this.$modal.open({
parent: this,
component: AvailableExportersModal,
@ -124,12 +133,6 @@ export default {
}
});
}
},
mounted() {
if (!this.isRepositoryLevel) {
this.collectionId = this.$route.params.collectionId;
this.fetchCollectionNameAndURL(this.collectionId);
}
}
}
</script>
@ -180,7 +183,7 @@ export default {
h1 {
font-size: 1.125rem;
color: white;
line-height: 1.125rem;
line-height: 1.4rem;
max-width: 100%;
text-overflow: ellipsis;
white-space: nowrap;

View File

@ -7,10 +7,14 @@
<h2>{{ this.$i18n.get('exporters') }}</h2>
<hr>
</header>
<section class="tainacan-form">
<p>{{ $i18n.get('instruction_select_an_exporter_type') }}</p>
<div class="exporter-types-container">
<div
role="list"
class="exporter-types-container">
<div
role="listitem"
class="exporter-type"
v-for="exporterType in availableExporters"
:key="exporterType.slug"
@ -20,6 +24,16 @@
<p>{{ exporterType.description }}</p>
</div>
</div>
<footer class="field is-grouped form-submit">
<div class="control">
<button
id="button-cancel-exporter-selection"
class="button is-outlined"
type="button"
@click="$parent.close();">
{{ $i18n.get('cancel') }}</button>
</div>
</footer>
<b-loading
:active.sync="isLoading"

View File

@ -9,8 +9,11 @@
</header>
<section class="tainacan-form">
<p>{{ $i18n.get('instruction_select_an_importer_type') }}</p>
<div class="importer-types-container">
<div
role="list"
class="importer-types-container">
<div
role="listitem"
class="importer-type"
v-for="importerType in availableImporters"
:key="importerType.slug"
@ -19,22 +22,24 @@
<h4>{{ importerType.name }}</h4>
<p>{{ importerType.description }}</p>
</div>
</div>
<b-loading
<b-loading
:is-full-page="false"
:active.sync="isLoading"
:can-cancel="false"/>
<!-- <footer class="field is-grouped form-submit">
</div>
<footer class="field is-grouped form-submit">
<div class="control">
<button
class="button is-outlined"
type="button"
@click="$parent.close()">Close</button>
</div>
<div class="control">
<!-- <div class="control">
<button class="button is-success">Confirm</button>
</div>
</footer> -->
</div> -->
</footer>
</section>
</div>
</form>
@ -83,6 +88,7 @@ export default {
@import "../../scss/_variables.scss";
.importer-types-container {
position: relative;
.importer-type {
border-bottom: 1px solid $gray2;

View File

@ -449,7 +449,7 @@
this.isSearchingLoading = true;
let query_items = { 'current_query': this.query };
let query = `?order=asc&number=${this.maxNumSearchResultsShow}&searchterm=${this.optionName}&` + qs.stringify(query_items);
let query = `?order=asc&number=${this.maxNumSearchResultsShow}&search=${this.optionName}&` + qs.stringify(query_items);
if (!this.isFilter)
query += '&hideempty=0';

View File

@ -20,11 +20,21 @@
<h4>{{ collection.name }}</h4>
<p>{{ collection.length > 200 ? (collection.description.substring(0,197) + '...') : collection.description }}</p>
</div>
</div>
<b-loading
<b-loading
:is-full-page="false"
:active.sync="isLoading"
:can-cancel="false"/>
</div>
<footer class="field is-grouped form-submit">
<div class="control">
<button
class="button is-outlined"
type="button"
@click="$parent.close()">Close</button>
</div>
</footer>
</section>
</div>
</form>
@ -73,6 +83,7 @@ export default {
@import "../../scss/_variables.scss";
.collection-types-container {
position: relative;
.collection-type {
border-bottom: 1px solid $gray2;

View File

@ -29,9 +29,17 @@
</h1>
</header>
{{ message }}
<div v-if="showNeverShowAgainOption">
<b-checkbox
@input="changeNeverShowMessageAgain($event)"
:native-value="neverShowAgain">
{{ $i18n.get('instruction_never_show_message_again') }}
</b-checkbox>
</div>
</section>
<footer class="modal-card-foot form-submit">
<button
v-if="!hideCancel"
class="button is-outlined"
type="button"
@click="$parent.close()">
@ -59,6 +67,25 @@
onConfirm: {
type: Function,
default: () => {}
},
hideCancel: {
type: Boolean,
default: false,
},
showNeverShowAgainOption: {
type: Boolean,
default: false
},
messageKeyForUserPrefs: ''
},
data() {
return {
neverShowAgain: false
}
},
methods: {
changeNeverShowMessageAgain($event) {
this.$userPrefs.set('neverShow' + this.messageKeyForUserPrefs + 'Dialog', $event);
}
}
}
@ -71,5 +98,13 @@
font-size: 56px;
}
button.is-success {
margin-left: auto;
}
.b-checkbox.checkbox {
margin-top: 12px;
}
</style>

View File

@ -87,9 +87,12 @@
</span>
</div>
<p>{{ $i18n.get('info_other_item_listing_options') }}</p>
<div class="exposer-types-list">
<div
role="list"
class="exposer-types-list">
<div
class="exposer-type"
role="listitem"
v-for="(exposerType, index ) in availableExposers"
:key="index"
@click="siteLinkCopied = false; selectExposer(exposerType)">
@ -101,10 +104,12 @@
<div
v-if="selectedExposer != undefined"
class="exposer-item-container">
class="exposer-item-container"
role="list">
<b-field
:addons="false"
class="exposer-item"
role="listitem"
v-for="(exposerMapper, index) in selectedExposerMappers"
:key="index">
<span
@ -131,9 +136,11 @@
</span>
<transition name="filter-item">
<div
role="list"
class="exposer-item-links-list"
v-show="!exposerMapper.collapsed">
<div
role="listitem"
:key="pagedLink"
v-for="pagedLink in totalPages"
class="exposer-item-link">
@ -292,14 +299,17 @@ export default {
availableExposers() {
let exposers = this.getAvailableExposers();
exposers.unshift({
accept_no_mapper: true,
class_name: 'API',
mappers: [],
name: this.$i18n.get('label_tainacan_api'),
description: this.$i18n.get('info_tainacan_api'),
slug: 'tainacan-api'
});
let tainacanApiExposerIndex = exposers.findIndex((aExposer) => aExposer.slug == 'tainacan-api');
if (tainacanApiExposerIndex < 0) {
exposers.unshift({
accept_no_mapper: true,
class_name: 'API',
mappers: [],
name: this.$i18n.get('label_tainacan_api'),
description: this.$i18n.get('info_tainacan_api'),
slug: 'tainacan-api'
});
}
return exposers;
}
},
@ -409,7 +419,7 @@ export default {
this.isLoading = false;
});
if (!this.collectionId != undefined) {
if (this.collectionId != undefined) {
this.fetchCollectionNameAndURL(this.collectionId);
}
}

View File

@ -36,14 +36,21 @@
<div class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2 v-if="file.title != undefined">{{ file.title.rendered }}</h2>
<a
@click="isPreviewModalActive = false"
class="back-link">{{ $i18n.get('exit') }}</a>
<hr>
</div>
<div
class="is-flex rendered-content"
v-html="file.description.rendered" />
<div class="field is-grouped form-submit">
<div class="control">
<button
id="button-cancel-importer-edition"
class="button is-outlined"
type="button"
@click="isPreviewModalActive = false">
{{ $i18n.get('exit') }}</button>
</div>
</div>
</div>
</b-modal>
</template>
@ -69,7 +76,7 @@ export default {
getIconForMimeType(mimeType) {
let type = mimeType.split('/');
if (type[0] == 'application' && type[1] != undefined){
switch (type[1]) {
case 'pdf':

View File

@ -340,7 +340,7 @@ export default {
}
li:hover {
background-color: $gray1;
background-color: $gray0;
.action-icon{
visibility: visible;

View File

@ -1,6 +1,7 @@
<template>
<b-field class="filter-item-forms">
<b-collapse
aria-id="collection-filters-collapse"
class="show"
:open="open"
animation="filter-item">

View File

@ -75,6 +75,10 @@
font-size: 0.75rem;
margin-bottom: -0.375rem;
@media only screen and (max-width: 768px) {
padding-top: 1rem;
}
&.is-inline-flex {
flex-wrap: wrap;
justify-content: flex-start;

View File

@ -10,9 +10,23 @@
$i18n.get('info_showing_items') +
getFirstItem() +
$i18n.get('info_to') +
getLastItemNumber() +
$i18n.get('info_of') + totalItems + '.'
getLastItemNumber() +
$i18n.get('info_of')
}}
<span :class="{ 'has-text-warning': isSortingByCustomMetadata }">
{{ totalItems + '.' }}
</span>
<span
v-tooltip="{
content: $i18n.get('info_items_hidden_due_sorting'),
autoHide: false,
placement: 'auto-start'
}"
style="margin-top: -3px"
class="icon has-text-warning"
v-if="isSortingByCustomMetadata">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-alertcircle" />
</span>
</div>
<div class="items-per-page">
<b-field
@ -38,7 +52,8 @@
:label="$i18n.get('label_go_to_page')">
<b-dropdown
position="is-top-right"
@change="onPageChange">
@change="onPageChange"
aria-role="list">
<button
aria-labelledby="go-to-page-dropdown"
class="button is-white"
@ -53,7 +68,8 @@
role="button"
:key="pageNumber"
v-for="pageNumber in totalPages"
:value="Number(pageNumber)">
:value="Number(pageNumber)"
aria-role="listitem">
{{ pageNumber }}
</b-dropdown-item>
</b-dropdown>
@ -78,10 +94,6 @@ import { mapGetters } from 'vuex';
export default {
name: 'Pagination',
data(){
return {
}
},
computed: {
totalItems(){
return this.getTotalItems();
@ -96,6 +108,9 @@ export default {
return Math.ceil(Number(this.totalItems)/Number(this.itemsPerPage));
}
},
props: {
isSortingByCustomMetadata: Boolean
},
watch: {
page( value ){
if (value < 1)
@ -129,7 +144,7 @@ export default {
if( this.totalItems == 0 )
return 0;
return ( this.itemsPerPage * ( this.page - 1 ) + 1)
},
}
}
}
</script>

View File

@ -6,7 +6,6 @@
import Vue from 'vue';
import Buefy from 'buefy';
import VTooltip from 'v-tooltip';
// import { VueHammer } from 'vue2-hammer';
import VueMasonry from 'vue-masonry-css';
import draggable from 'vuedraggable';
import VueTheMask from 'vue-the-mask';
@ -49,7 +48,6 @@ import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, UserCap
// Configure and Register Plugins
Vue.use(Buefy);
Vue.use(VTooltip);
// Vue.use(VueHammer);
Vue.use(VueMasonry);
Vue.use(I18NPlugin);
Vue.use(UserPrefsPlugin);
@ -102,4 +100,23 @@ new Vue({
store,
router,
render: h => h(AdminPage)
});
});
// Display Icons only once everything is loaded
function listen(evnt, elem, func) {
if (elem.addEventListener) // W3C DOM
elem.addEventListener(evnt,func,false);
else if (elem.attachEvent) { // IE DOM
var r = elem.attachEvent("on"+evnt, func);
return r;
}
else {
jQuery('head').append('<style>.tainacan-icon{ opacity: 1 !important; }</style>');
}
}
listen("load", window, function() {
var iconsStyle = document.createElement("style");
iconsStyle.setAttribute('type', 'text/css');
iconsStyle.innerText = '.tainacan-icon{ opacity: 1 !important; }';
document.head.appendChild(iconsStyle);
});

View File

@ -2,7 +2,6 @@
import Vue from 'vue';
import Buefy from 'buefy';
import VTooltip from 'v-tooltip';
// import { VueHammer } from 'vue2-hammer';
import VueMasonry from 'vue-masonry-css';
// Custom elements
@ -48,7 +47,6 @@ import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin } from '
// Configure and Register Plugins
Vue.use(Buefy);
Vue.use(VTooltip);
// Vue.use(VueHammer);
Vue.use(VueMasonry);
Vue.use(I18NPlugin);
Vue.use(UserPrefsPlugin);
@ -129,4 +127,23 @@ export const ThemeItemsListing = new Vue({
}
});
});
// Display Icons only once everything is loaded
function listen(evnt, elem, func) {
if (elem.addEventListener) // W3C DOM
elem.addEventListener(evnt,func,false);
else if (elem.attachEvent) { // IE DOM
var r = elem.attachEvent("on"+evnt, func);
return r;
}
else {
jQuery('head').append('<style>.tainacan-icon{ opacity: 1 !important; }</style>');
}
}
listen("load", window, function() {
var iconsStyle = document.createElement("style");
iconsStyle.setAttribute('type', 'text/css');
iconsStyle.innerText = '.tainacan-icon{ opacity: 1 !important; }';
document.head.appendChild(iconsStyle);
});

View File

@ -91,6 +91,28 @@ I18NPlugin.install = function (Vue, options = {}) {
let string = tainacan_plugin.i18n['helpers_label'][entity][key].description;
return (string != undefined && string != null && string != '' ) ? string : "Invalid i18n helper object. ";
},
/**
* Parsed strings created with variables according to WordPress Logic.
* Check https://developer.wordpress.org/themes/functionality/internationalization/#variables
* An example: ('This sentence has %s letters', [nLetters])
* or ('This one has %1$s letters and %2$s words', [nLetters, nWords]).
*/
getWithVariables(key, variables) { // TRY WITH regex: \%((\d)\$)*s
let rawString = tainacan_plugin.i18n[key];
if (rawString != undefined && rawString != null && rawString != '' ) {
let splits = rawString.match(/\%((\d)\$)*s/gm); // An array with all the %s, %1$s, %2$s, etc
let parsedString = '';
for (let i = 0; i < splits.length; i++) {
parsedString += rawString.split(splits[i]).join(variables[i]);
}
return parsedString;
} else {
"Invalid i18n key: " + tainacan_plugin.i18n[key];
}
}
}
};
@ -114,7 +136,11 @@ UserPrefsPlugin.install = function (Vue, options = {}) {
'view_mode': undefined,
'admin_view_mode': 'cards',
'fetch_only': 'thumbnail,creation_date,author_name',
'fetch_only_meta': ''
'fetch_only_meta': '',
'taxonomies_order': 'desc',
'taxonomies_order_by': 'date',
'collections_order': 'desc',
'collections_order_by': 'date'
},
init() {
if (tainacan_plugin.user_prefs == undefined || tainacan_plugin.user_prefs == '') {

View File

@ -113,11 +113,11 @@ export default {
id: this.params.relatedPostId
}
this.params.attachment = attachment;
this.params.onSave(attachment.id);
this.params.onSave(attachment);
}
}),
// CroppedImageControl, with presets for thumbnail dimensions
// CroppedImageControl, with presets for header dimensions
headerImageControl: wp.customize.CroppedImageControl.extend({
initFrame: function() {
@ -137,7 +137,7 @@ export default {
this.params.flex_width = true;
this.params.flex_height = true;
this.params.width = 2000;
this.params.height = 280;
this.params.height = 625;
}
this.frame = wp.media({

View File

@ -111,12 +111,15 @@
<section class="home-section home-section-collection">
<div class="home-section-header collections-section-header">
<div class="home-section-icon">
<span class="icon">
<router-link
tag="span"
class="icon"
to="/collections">
<i class="tainacan-icon tainacan-icon-collections"/>
</span>
</router-link>
</div>
<h1>{{ $i18n.get('collections') }}</h1>
<router-link
<router-link
tag="a"
to="/collections">
<span class="icon">
@ -165,7 +168,7 @@ export default {
loadCollections() {
this.cleanCollections();
this.isLoadingCollections = true;
this.fetchCollections({ 'page': 1, 'collectionsPerPage': 5 })
this.fetchCollections({ page: 1, collectionsPerPage: 5, status: undefined, contextEdit: true })
.then(() => {
this.isLoadingCollections = false;
})
@ -232,6 +235,10 @@ export default {
display: flex;
align-items: center;
justify-content: center;
.icon:hover {
cursor: pointer;
}
}
h1 {

View File

@ -1,13 +1,17 @@
<template>
<div class="repository-level-page page-container">
<b-loading :active.sync="isLoadingMetadatumMappers"/>
<b-loading :active.sync="isLoading"/>
<tainacan-title
:bread-crumb-items="[{ path: '', label: this.$i18n.get('collections') }]"/>
<div
class="sub-header"
v-if="$userCaps.hasCapability('edit_tainacan-collections')">
<!-- New Collection button -->
<div class="header-item">
<b-dropdown id="collection-creation-options-dropdown">
<b-dropdown
aria-role="list"
id="collection-creation-options-dropdown">
<button
class="button is-secondary"
slot="trigger">
@ -16,7 +20,7 @@
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
</button>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<router-link
id="a-create-collection"
tag="div"
@ -29,7 +33,8 @@
<b-dropdown-item
:key="metadatum_mapper.slug"
v-for="metadatum_mapper in metadatum_mappers"
v-if="metadatum_mapper.metadata != false">
v-if="metadatum_mapper.metadata != false"
aria-role="listitem">
<router-link
:id="'a-create-collection-' + metadatum_mapper.slug"
tag="div"
@ -37,7 +42,7 @@
{{ $i18n.get(metadatum_mapper.name) }}
</router-link>
</b-dropdown-item>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<div
id="a-import-collection"
tag="div"
@ -49,6 +54,39 @@
</b-dropdown-item>
</b-dropdown>
</div>
<!-- Sorting options ---- -->
<b-field class="header-item">
<b-select
class="sorting-select"
:disabled="collections.length <= 0"
@input="onChangeOrderBy($event)"
:value="orderBy"
:label="$i18n.get('label_sorting')">
<option
v-for="(option, index) in sortingOptions"
:value="option.value"
:key="index">
{{ option.label }}
</option>
</b-select>
<button
:disabled="collections.length <= 0 || isLoading || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
</span>
</button>
<button
:disabled="collections.length <= 0 || isLoading || order == 'desc'"
class="button is-white is-small"
@click="onChangeOrder('desc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortdescending tainacan-icon-20px"/>
</span>
</button>
</b-field>
</div>
<div class="above-subheader">
@ -94,7 +132,10 @@
<p v-if="status == 'trash'">{{ $i18n.get('info_no_collection_trash') }}</p>
<div v-if="$userCaps.hasCapability('edit_tainacan-collections') && status == undefined || status == ''">
<b-dropdown id="collection-creation-options-dropdown">
<b-dropdown
:disabled="isLoadingMetadatumMappers"
id="collection-creation-options-dropdown"
aria-role="list">
<button
class="button is-secondary"
slot="trigger">
@ -103,7 +144,7 @@
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
</button>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<router-link
id="a-create-collection"
tag="div"
@ -116,7 +157,8 @@
<b-dropdown-item
:key="metadatum_mapper.slug"
v-for="metadatum_mapper in metadatum_mappers"
v-if="metadatum_mapper.metadata != false">
v-if="metadatum_mapper.metadata != false"
aria-role="listitem">
<router-link
:id="'a-create-collection-' + metadatum_mapper.slug"
tag="div"
@ -124,7 +166,7 @@
{{ $i18n.get(metadatum_mapper.name) }}
</router-link>
</b-dropdown-item>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<div
id="a-import-collection"
tag="div"
@ -198,7 +240,13 @@ export default {
page: 1,
collectionsPerPage: 12,
isLoadingMetadatumMappers: true,
status: ''
status: '',
order: 'desc',
ordeBy: 'date',
sortingOptions: [
{ label: this.$i18n.get('label_title'), value: 'title' },
{ label: this.$i18n.get('label_creation_date'), value: 'date' },
]
}
},
components: {
@ -236,6 +284,33 @@ export default {
this.status = status;
this.loadCollections();
},
onChangeOrder(newOrder) {
if (newOrder != this.order) {
this.$userPrefs.set('collections_order', newOrder)
.then((newOrder) => {
this.order = newOrder;
})
.catch(() => {
this.$console.log("Error settings user prefs for collections order")
});
}
this.order = newOrder;
this.loadCollections()
},
onChangeOrderBy(newOrderBy) {
if (newOrderBy != this.orderBy) {
this.$userPrefs.set('collections_order_by', newOrderBy)
.then((newOrderBy) => {
this.orderBy = newOrderBy;
})
.catch(() => {
this.$console.log("Error settings user prefs for collections orderby")
});
}
this.orderBy = newOrderBy;
this.loadCollections();
},
onChangeCollectionsPerPage(value) {
if (value != this.collectionsPerPage) {
@ -258,10 +333,13 @@ export default {
this.cleanCollections();
this.isLoading = true;
this.fetchCollections({
'page': this.page,
'collectionsPerPage': this.collectionsPerPage,
'status': this.status,
'contextEdit': true })
page: this.page,
collectionsPerPage: this.collectionsPerPage,
status: this.status,
contextEdit: true,
order: this.order,
orderby: this.orderBy
})
.then((res) => {
this.isLoading = false;
this.totalCollections = res.total;
@ -297,12 +375,26 @@ export default {
mounted(){
if (this.collectionsPerPage != this.$userPrefs.get('collections_per_page'))
this.collectionsPerPage = this.$userPrefs.get('collections_per_page');
if (!this.collectionsPerPage) {
this.collectionsPerPage = 12;
this.$userPrefs.set('collections_per_page', 12);
}
if (this.order != this.$userPrefs.get('collections_order'))
this.order = this.$userPrefs.get('collections_order');
if (!this.order) {
this.order = 'asc';
this.$userPrefs.set('collections_order', 'asc');
}
if (this.orderBy != this.$userPrefs.get('collections_order_by'))
this.orderBy = this.$userPrefs.get('collections_order_by');
if (!this.orderBy) {
this.orderBy = 'date';
this.$userPrefs.set('collections_order_by', 'date');
}
this.loadCollections();
}
}
@ -318,10 +410,17 @@ export default {
padding-left: 0;
padding-right: 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
.header-item {
display: inline-block;
padding-right: 8em;
.header-item:not(:last-child) {
padding-right: 0.5em;
}
.header-item .button .icon i{
width: 100%;
}
@media screen and (max-width: 769px) {
@ -330,7 +429,7 @@ export default {
padding-top: 0.9em;
.header-item {
padding-right: 0.5em;
padding-right: 0.2em;
}
}
}

View File

@ -1,10 +1,4 @@
<template>
<!-- <div <IF WE USE HAMMERJS>
v-hammer:swipe="onSwipeFiltersMenu"
:class="{
'repository-level-page': isRepositoryLevel,
'is-fullscreen': registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen
}"> -->
<div
:class="{
'repository-level-page': isRepositoryLevel,
@ -29,8 +23,9 @@
v-if="!openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
class="is-hidden-mobile"
id="filter-menu-compress-button"
:style="{ top: !isOnTheme ? (isRepositoryLevel ? '172px' : '120px') : '76px' }"
:aria-label="isFiltersMenuCompressed ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters')"
:style="{ top: !isOnTheme ? (isRepositoryLevel ? '172px' : '120px') : '76px' }"
@click="isFiltersMenuCompressed = !isFiltersMenuCompressed">
<span class="icon">
<i
@ -45,8 +40,9 @@
v-if="!openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
class="is-hidden-tablet"
id="filter-menu-compress-button-mobile"
:style="{ top: !isOnTheme ? (isRepositoryLevel ? (searchControlHeight + 100) : (searchControlHeight + 70) + 'px') : (searchControlHeight - 25) + 'px' }"
:aria-label="isFiltersMenuCompressed ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters')"
:style="{ top: !isOnTheme ? (isRepositoryLevel ? (searchControlHeight + 100) : (searchControlHeight + 70) + 'px') : (searchControlHeight - 25) + 'px' }"
@click="isFilterModalActive = !isFilterModalActive">
<span class="icon">
<i
@ -64,7 +60,7 @@
role="region"
aria-labelledby="filters-label-landmark"
:style="{ top: searchControlHeight + 'px' }"
v-if="!isFiltersMenuCompressed &&
v-show="!isFiltersMenuCompressed &&
!openAdvancedSearch &&
!(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
class="filters-menu tainacan-form is-hidden-mobile">
@ -174,7 +170,8 @@
v-if="!isOnTheme">
<b-dropdown
:mobile-modal="true"
id="item-creation-options-dropdown">
id="item-creation-options-dropdown"
aria-role="list">
<button
class="button is-secondary"
slot="trigger">
@ -184,7 +181,9 @@
</span>
</button>
<b-dropdown-item v-if="!isRepositoryLevel">
<b-dropdown-item
v-if="!isRepositoryLevel"
aria-role="listitem">
<router-link
id="a-create-item"
tag="div"
@ -192,7 +191,9 @@
{{ $i18n.get('add_one_item') }}
</router-link>
</b-dropdown-item>
<b-dropdown-item v-if="isRepositoryLevel">
<b-dropdown-item
v-if="isRepositoryLevel"
aria-role="listitem">
<div
id="a-create-item"
tag="div"
@ -200,7 +201,9 @@
{{ $i18n.get('add_one_item') }}
</div>
</b-dropdown-item>
<b-dropdown-item v-if="!isRepositoryLevel">
<b-dropdown-item
v-if="!isRepositoryLevel"
aria-role="listitem">
<router-link
id="a-item-add-bulk"
tag="div"
@ -210,7 +213,7 @@
<small class="is-small">{{ $i18n.get('info_bulk_add_items') }}</small>
</router-link>
</b-dropdown-item>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<div
id="a-import-items"
tag="div"
@ -240,7 +243,8 @@
ref="displayedMetadataDropdown"
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show">
class="show metadata-options-dropdown"
aria-role="list">
<button
:aria-label="$i18n.get('label_displayed_metadata')"
class="button is-white"
@ -255,7 +259,8 @@
v-for="(column, index) in localDisplayedMetadata"
:key="index"
class="control"
custom>
custom
aria-role="listitem">
<b-checkbox
v-model="column.display"
:native-value="column.display">
@ -277,15 +282,16 @@
<!-- Change OrderBy Select and Order Button-->
<div class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_sorting') + ':' }}</label>
<b-dropdown
:mobile-modal="true"
:disabled="totalItems <= 0"
@input="onChangeOrderBy($event)">
@input="onChangeOrderBy($event)"
aria-role="list">
<button
:aria-label="$i18n.get('label_sorting')"
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_sorting') }}</span>
<span>{{ orderByName }}</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
@ -293,17 +299,12 @@
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': metadatum != undefined && orderBy == metadatum.slug }"
:class="{ 'is-active': (orderBy != 'meta_value' && orderBy != 'meta_value_num' && orderBy == metadatum.slug) || ((orderBy == 'meta_value' || orderBy == 'meta_value_num') && metaKey == metadatum.id) }"
v-for="metadatum of sortingMetadata"
v-if="
totalItems > 0 &&
metadatum != undefined &&
metadatum.slug === 'creation_date' || (
metadatum.metadata_type_object &&
metadatum.metadata_type_object.related_mapped_prop == 'title'
)"
v-if="metadatum != undefined"
:value="metadatum"
:key="metadatum.slug">
:key="metadatum.slug"
aria-role="listitem">
{{ metadatum.name }}
</b-dropdown-item>
<!-- Once we have sorting by metadata we can use this -->
@ -329,21 +330,21 @@
<button
aria-controls="items-list-results"
class="button is-white is-small"
:aria-label="$i18n.get('label_sort_ascending')"
:aria-label="$i18n.get('label_sort_descending')"
:disabled="totalItems <= 0 || order == 'DESC'"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortascending"/>
<i class="tainacan-icon tainacan-icon-sortdescending"/>
</span>
</button>
<button
aria-controls="items-list-results"
:disabled="totalItems <= 0 || order == 'ASC'"
:aria-label="$i18n.get('label_sort_descending')"
:aria-label="$i18n.get('label_sort_ascending')"
class="button is-white is-small"
@click="onChangeOrder()">
<span class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-sortdescending"/>
<i class="tainacan-icon tainacan-icon-sortascending"/>
</span>
</button>
</b-field>
@ -354,20 +355,22 @@
v-if="isOnTheme"
class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_visualization') + ':&nbsp; ' }}</label>
<b-dropdown
@change="onChangeViewMode($event)"
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')">
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
<button
:aria-label="$i18n.get('label_view_mode')"
:aria-label="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization')"
class="button is-white"
slot="trigger">
<span
class="gray-icon view-mode-icon"
v-if="registeredViewModes[viewMode] != undefined"
v-html="registeredViewModes[viewMode].icon"/>
<span class="is-hidden-touch">&nbsp;&nbsp;&nbsp;{{ $i18n.get('label_visualization') }}</span>
<span class="is-hidden-touch">&nbsp;&nbsp;&nbsp;{{ registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization') }}</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
@ -379,7 +382,8 @@
v-for="(viewModeOption, index) of enabledViewModes"
:key="index"
:value="viewModeOption"
v-if="registeredViewModes[viewModeOption] != undefined && registeredViewModes[viewModeOption].full_screen == false">
v-if="registeredViewModes[viewModeOption] != undefined && registeredViewModes[viewModeOption].full_screen == false"
aria-role="listitem">
<span
class="gray-icon"
v-html="registeredViewModes[viewModeOption].icon"/>
@ -392,17 +396,19 @@
v-if="!isOnTheme"
class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_visualization') + ':' }}</label>
<b-dropdown
@change="onChangeAdminViewMode($event)"
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')">
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
<button
:aria-label="$i18n.get('label_view_mode')"
class="button is-white"
slot="trigger">
<span>
<span class="icon is-small gray-icon">
<span class="view-mode-icon icon is-small gray-icon">
<i
:class="{'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
'tainacan-icon-viewcards' : adminViewMode == 'cards',
@ -412,7 +418,7 @@
class="tainacan-icon"/>
</span>
</span>
&nbsp;&nbsp;&nbsp;{{ $i18n.get('label_visualization') }}
&nbsp;&nbsp;&nbsp;{{ adminViewMode != undefined ? $i18n.get('label_' + adminViewMode) : $i18n.get('label_table') }}
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
@ -421,7 +427,8 @@
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'table' }"
:value="'table'">
:value="'table'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewtable"/>
</span>
@ -431,7 +438,8 @@
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'cards' }"
:value="'cards'">
:value="'cards'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewcards"/>
</span>
@ -441,7 +449,8 @@
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'grid' }"
:value="'grid'">
:value="'grid'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewminiature"/>
</span>
@ -451,7 +460,8 @@
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'records' }"
:value="'records'">
:value="'records'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewrecords"/>
</span>
@ -461,7 +471,8 @@
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'masonry' }"
:value="'masonry'">
:value="'masonry'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewmasonry"/>
</span>
@ -495,7 +506,7 @@
<button
class="button is-white"
:aria-label="$i18n.get('label_urls')"
:disabled="this.totalItems == undefined || this.totalItems <= 0"
:disabled="totalItems == undefined || totalItems <= 0"
@click="openExposersModal()">
<span class="gray-icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-url"/>
@ -563,7 +574,7 @@
:open-form-advanced-search="openFormAdvancedSearch"
:is-do-search="isDoSearch"/>
<div class="advanced-searh-form-submit">
<div class="advanced-search-form-submit">
<p
v-if="advancedSearchResults"
class="control">
@ -591,18 +602,18 @@
<li
@click="onChangeTab('')"
:class="{ 'is-active': status == undefined || status == ''}">
<a>{{ `${$i18n.get('label_all_items')}` }}<span class="has-text-gray">&nbsp;{{ `${collection && collection.total_items ? ` (${Number(collection.total_items.private) + Number(collection.total_items.publish)})` : ` (${repositoryTotalItems ? repositoryTotalItems.private + repositoryTotalItems.publish : ''})`}` }}</span></a>
<a>{{ `${$i18n.get('label_all_items')}` }}<span class="has-text-gray">&nbsp;{{ collection && collection.total_items ? ` (${Number(collection.total_items.private) + Number(collection.total_items.publish)})` : (isRepositoryLevel && repositoryTotalItems) ? ` (${ repositoryTotalItems.private + repositoryTotalItems.publish })` : '' }}</span></a>
</li>
<li
@click="onChangeTab('draft')"
:class="{ 'is-active': status == 'draft'}">
<a>{{ `${$i18n.get('label_draft_items')}` }}<span class="has-text-gray">&nbsp;{{ `${collection && collection.total_items ? ` (${collection.total_items.draft})` : ` (${repositoryTotalItems ? repositoryTotalItems.draft : ''})`}` }}</span></a>
<a>{{ `${$i18n.get('label_draft_items')}` }}<span class="has-text-gray">&nbsp;{{ collection && collection.total_items ? ` (${collection.total_items.draft})` : (isRepositoryLevel && repositoryTotalItems) ? ` (${ repositoryTotalItems.draft })` : '' }}</span></a>
</li>
<li
v-if="!isRepositoryLevel"
@click="onChangeTab('trash')"
:class="{ 'is-active': status == 'trash'}">
<a>{{ `${$i18n.get('label_trash_items')}` }}<span class="has-text-gray">&nbsp;{{ `${collection && collection.total_items ? ` (${collection.total_items.trash})` : ` (${repositoryTotalItems ? repositoryTotalItems.trash : ''})`}` }}</span></a>
<a>{{ `${$i18n.get('label_trash_items')}` }}<span class="has-text-gray">&nbsp;{{ collection && collection.total_items ? ` (${collection.total_items.trash})` : (isRepositoryLevel && repositoryTotalItems) ? ` (${ repositoryTotalItems.trash })` : '' }}</span></a>
</li>
</ul>
</div>
@ -626,7 +637,7 @@
<h3
id="items-list-landmark"
class="is-hidden">
class="sr-only">
{{ $i18n.get('label_items_list') }}
</h3>
@ -662,7 +673,8 @@
:total-items="totalItems"
:is-loading="isLoadingItems"
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"/>
:view-mode="adminViewMode"
@updateIsLoading="newIsLoading => isLoadingItems = newIsLoading"/>
<!-- Theme View Modes -->
<div
@ -688,7 +700,7 @@
<!-- Empty Placeholder (only used in Admin) -->
<section
v-if="!isOnTheme && !isLoadingItems && totalItems <= 0"
v-if="!isOnTheme && !isLoadingItems && totalItems == 0"
class="section">
<div class="content has-text-grey has-text-centered">
<p>
@ -713,6 +725,7 @@
<!-- Pagination -->
<pagination
:is-sorting-by-custom-metadata="isSortingByCustomMetadata"
v-if="totalItems > 0 &&
(!isOnTheme || (registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].show_pagination)) &&
(advancedSearchResults || !openAdvancedSearch)"/>
@ -797,6 +810,7 @@
import AvailableImportersModal from '../../components/other/available-importers-modal.vue';
import ExposersModal from '../../components/other/exposers-modal.vue';
import CollectionsModal from '../../components/other/collections-modal.vue';
import CustomDialog from '../../components/other/custom-dialog.vue';
import { mapActions, mapGetters } from 'vuex';
export default {
@ -823,7 +837,8 @@
searchControlHeight: 0,
sortingMetadata: [],
isFilterModalActive: false,
collection: undefined
collection: undefined,
hasAnOpenModal: false
}
},
props: {
@ -832,6 +847,9 @@
enabledViewModes: Object // Used only on theme
},
computed: {
isSortingByCustomMetadata() {
return (this.orderBy != undefined && this.orderBy != '' && this.orderBy != 'title' && this.orderBy != 'date');
},
repositoryTotalItems(){
let collections = this.getCollections();
@ -858,6 +876,7 @@
return this.getItemsListTemplate();
},
totalItems() {
this.updateCollectionInfo();
return this.getTotalItems();
},
filters() {
@ -886,6 +905,27 @@
},
showLoading() {
return this.isLoadingItems || this.isLoadingFilters || this.isLoadingMetadata;
},
metaKey() {
return this.getMetaKey();
},
orderByName() {
if (this.getOrderByName() != null && this.getOrderByName() != undefined && this.getOrderByName() != '') {
return this.getOrderByName();
} else {
for (let metadatum of this.sortingMetadata) {
if (
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug == 'creation_date' && (!metadatum.metadata_type_object || !metadatum.metadata_type_object.core)) && this.orderBy == 'date') ||
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug != 'creation_date' && (metadatum.metadata_type_object != undefined && metadatum.metadata_type_object.core)) && this.orderBy == metadatum.metadata_type_object.related_mapped_prop) ||
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug != 'creation_date' && (!metadatum.metadata_type_object || !metadatum.metadata_type_object.core)) && this.orderBy == metadatum.slug) ||
((this.orderBy == 'meta_value' || this.orderBy == 'meta_value_num') && this.getMetaKey() == metadatum.id)
)
return metadatum.name;
}
}
}
},
components: {
@ -933,10 +973,12 @@
'getSearchQuery',
'getStatus',
'getOrderBy',
'getOrderByName',
'getOrder',
'getViewMode',
'getTotalItems',
'getAdminViewMode',
'getMetaKey'
]),
onSwipeFiltersMenu($event) {
if (this.registeredViewModes[this.viewMode] == undefined ||
@ -990,6 +1032,7 @@
},
onChangeOrderBy(metadatum) {
this.$eventBusSearch.setOrderBy(metadatum);
this.showItemsHiddingDueSorting();
},
onChangeOrder() {
this.order == 'DESC' ? this.$eventBusSearch.setOrder('ASC') : this.$eventBusSearch.setOrder('DESC');
@ -1044,13 +1087,13 @@
let authorNameMetadatum = this.localDisplayedMetadata.find(metadatum => metadatum.slug == 'author_name');
let descriptionMetadatum = this.localDisplayedMetadata.find(metadatum => metadatum.metadata_type_object != undefined ? metadatum.metadata_type_object.related_mapped_prop == 'description' : false);
// Updates Search
this.$eventBusSearch.addFetchOnly(
thumbnailMetadatum != undefined && thumbnailMetadatum.display ? 'thumbnail' : null +','+
creationDateMetadatum != undefined && creationDateMetadatum.display ? 'creation_date' : null +','+
authorNameMetadatum != undefined && authorNameMetadatum.display ? 'author_name': null +','+
(this.isRepositoryLevel ? 'title' : null) +','+
((thumbnailMetadatum != undefined && thumbnailMetadatum.display) ? 'thumbnail' : null) + ',' +
((creationDateMetadatum != undefined && creationDateMetadatum.display) ? 'creation_date' : null) + ',' +
((authorNameMetadatum != undefined && authorNameMetadatum.display) ? 'author_name': null) + ',' +
(this.isRepositoryLevel ? 'title' : null) + ',' +
(this.isRepositoryLevel && descriptionMetadatum.display ? 'description' : null), false, fetchOnlyMetadatumIds.toString());
// Closes dropdown
@ -1169,8 +1212,16 @@
if (display) {
fetchOnlyMetadatumIds.push(metadatum.id);
}
if (
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship'
) {
this.sortingMetadata.push(metadatum);
}
}
this.sortingMetadata.push(metadatum);
}
let creationDateMetadatumDisplay = prefsFetchOnlyObject ? (prefsFetchOnlyObject[1] != null) : true;
@ -1235,20 +1286,32 @@
display: authorNameMetadatumDisplay
});
}
// Loads only basic attributes necessary to view modes that do not allow custom meta
} else {
this.$eventBusSearch.addFetchOnly('thumbnail,creation_date,author_name,title,description', true, '');
this.sortingMetadata.push({
name: this.$i18n.get('label_title'),
metadatum: 'row_title',
metadata_type_object: {core: true, related_mapped_prop: 'title'},
metadata_type: undefined,
slug: 'title',
id: undefined,
display: true
});
if (this.isRepositoryLevel) {
this.sortingMetadata.push({
name: this.$i18n.get('label_title'),
metadatum: 'row_title',
metadata_type_object: {core: true, related_mapped_prop: 'title'},
metadata_type: undefined,
slug: 'title',
id: undefined,
display: true
});
}
for (let metadatum of this.metadata) {
if (metadatum.display !== 'never' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship') {
this.sortingMetadata.push(metadatum);
}
}
this.sortingMetadata.push({
name: this.$i18n.get('label_creation_date'),
@ -1268,6 +1331,38 @@
this.isLoadingMetadata = false;
});
},
updateCollectionInfo () {
if (this.collectionId) {
this.fetchCollectionTotalItems(this.collectionId)
.then((data) => {
this.collection = data;
})
}
},
showItemsHiddingDueSorting() {
if (this.isSortingByCustomMetadata &&
this.$userPrefs.get('neverShowItemsHiddenDueSortingDialog') != true) {
this.hasAnOpenModal = true;
this.$modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_items_hidden_due_sorting'),
onConfirm: () => {
this.hasAnOpenModal = false;
},
hideCancel: true,
showNeverShowAgainOption: tainacan_plugin.user_caps != undefined && tainacan_plugin.user_caps.length != undefined && tainacan_plugin.user_caps.length > 0,
messageKeyForUserPrefs: 'ItemsHiddenDueSorting'
}
});
}
},
adjustSearchControlHeight: _.debounce( function() {
this.$nextTick(() => {
if (this.$refs['search-control'] != undefined)
@ -1291,13 +1386,6 @@
},
created() {
if(this.collectionId) {
this.fetchCollectionTotalItems(this.collectionId)
.then((data) => {
this.collection = data;
})
}
this.isOnTheme = (this.$route.name === null);
this.isRepositoryLevel = (this.collectionId === undefined);
@ -1319,7 +1407,7 @@
});
this.$eventBusSearch.$on('hasToPrepareMetadataAndFilters', (to) => {
/* This condition is to prevent a incorrect fetch by filter or metadata when we coming from items
/* This condition is to prevent an incorrect fetch by filter or metadata when we coming from items
* at collection level to items page at repository level
*/
@ -1338,8 +1426,8 @@
});
},
mounted() {
mounted() {
this.prepareFilters();
this.prepareMetadata();
this.localDisplayedMetadata = JSON.parse(JSON.stringify(this.displayedMetadata));
@ -1386,6 +1474,8 @@
}
}
this.showItemsHiddingDueSorting();
// Watches window resize to adjust filter's top position and compression on mobile
this.adjustSearchControlHeight();
window.addEventListener('resize', this.adjustSearchControlHeight);
@ -1487,7 +1577,7 @@
}
}
.advanced-searh-form-submit {
.advanced-search-form-submit {
display: flex;
justify-content: flex-end;
padding-right: $page-side-padding;
@ -1647,6 +1737,14 @@
flex-basis: 100%;
}
.label {
font-size: 0.875rem;
font-weight: normal;
margin-top: 3px;
margin-bottom: 2px;
cursor: default;
}
.button {
display: flex;
align-items: center;
@ -1667,8 +1765,9 @@
}
.view-mode-icon {
margin-right: 4px !important;
margin-right: 3px !important;
margin-top: 1px;
margin-left: 6px !important;
}
.dropdown-menu {
@ -1678,7 +1777,7 @@
padding: 0;
.metadata-options-container {
max-height: 240px;
max-height: 288px;
overflow: auto;
}
.dropdown-item {
@ -1690,7 +1789,7 @@
.dropdown-item-apply {
width: 100%;
border-top: 1px solid #efefef;
padding: 8px 12px 2px 12px;
padding: 8px 12px;
text-align: right;
}
.dropdown-item-apply .button {

View File

@ -6,6 +6,8 @@
<div
class="sub-header"
v-if="$userCaps.hasCapability('edit_tainacan-taxonomies')">
<!-- New Taxonomy Button ---- -->
<div class="header-item">
<router-link
id="button-create-taxonomy"
@ -15,6 +17,40 @@
{{ $i18n.getFrom('taxonomies', 'new_item') }}
</router-link>
</div>
<!-- Sorting options ---- -->
<b-field class="header-item">
<label class="label">{{ $i18n.get('label_sorting') + ':' }}</label>
<b-select
class="sorting-select"
:disabled="taxonomies.length <= 0"
@input="onChangeOrderBy($event)"
:value="orderBy"
:label="$i18n.get('label_sorting')">
<option
v-for="(option, index) in sortingOptions"
:value="option.value"
:key="index">
{{ option.label }}
</option>
</b-select>
<button
:disabled="taxonomies.length <= 0 || isLoading || order == 'asc'"
class="button is-white is-small"
@click="onChangeOrder('asc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortascending tainacan-icon-20px"/>
</span>
</button>
<button
:disabled="taxonomies.length <= 0 || isLoading || order == 'desc'"
class="button is-white is-small"
@click="onChangeOrder('desc')">
<span class="icon gray-icon is-small">
<i class="tainacan-icon tainacan-icon-sortdescending tainacan-icon-20px"/>
</span>
</button>
</b-field>
</div>
<div class="above-subheader">
@ -128,7 +164,13 @@
total: 0,
page: 1,
taxonomiesPerPage: 12,
status: ''
status: '',
order: 'asc',
ordeBy: 'date',
sortingOptions: [
{ label: this.$i18n.get('label_name'), value: 'title' },
{ label: this.$i18n.get('label_creation_date'), value: 'date' },
]
}
},
components: {
@ -146,6 +188,33 @@
this.status = status;
this.load();
},
onChangeOrder(newOrder) {
if (newOrder != this.order) {
this.$userPrefs.set('taxonomies_order', newOrder)
.then((newOrder) => {
this.order = newOrder;
})
.catch(() => {
this.$console.log("Error settings user prefs for taxonomies order")
});
}
this.order = newOrder;
this.load();
},
onChangeOrderBy(newOrderBy) {
if (newOrderBy != this.orderBy) {
this.$userPrefs.set('taxonomies_order_by', newOrderBy)
.then((newOrderBy) => {
this.orderBy = newOrderBy;
})
.catch(() => {
this.$console.log("Error settings user prefs for taxonomies orderby")
});
}
this.orderBy = newOrderBy;
this.load();
},
onChangePerPage(value) {
if (value != this.taxonomiesPerPage) {
this.$userPrefs.set('taxonomies_per_page', value)
@ -167,7 +236,13 @@
load() {
this.isLoading = true;
this.fetch({ 'page': this.page, 'taxonomiesPerPage': this.taxonomiesPerPage, 'status': this.status })
this.fetch({
page: this.page,
taxonomiesPerPage: this.taxonomiesPerPage,
status: this.status,
order: this.order,
orderby: this.orderBy
})
.then((res) => {
this.isLoading = false;
this.total = res.total;
@ -195,11 +270,25 @@
mounted(){
if (this.taxonomiesPerPage != this.$userPrefs.get('taxonomies_per_page'))
this.taxonomiesPerPage = this.$userPrefs.get('taxonomies_per_page');
if (!this.taxonomiesPerPage) {
this.taxonomiesPerPage = 12;
this.$userPrefs.set('taxonomies_per_page', 12);
}
if (this.order != this.$userPrefs.get('taxonomies_order'))
this.order = this.$userPrefs.get('taxonomies_order');
if (!this.order) {
this.order = 'asc';
this.$userPrefs.set('taxonomies_order', 'asc');
}
if (this.orderBy != this.$userPrefs.get('taxonomies_order_by'))
this.orderBy = this.$userPrefs.get('taxonomies_order_by');
if (!this.orderBy) {
this.orderBy = 'date';
this.$userPrefs.set('taxonomies_order_by', 'date');
}
this.load();
}
@ -215,10 +304,22 @@
padding-left: 0;
padding-right: 0;
border-bottom: 1px solid #ddd;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
.header-item {
display: inline-block;
padding-right: 8em;
.header-item:not(:last-child) {
padding-right: 0.5em;
}
.header-item .button .icon i{
width: 100%;
}
.header-item .label{
font-weight: normal;
font-size: 0.875rem;
margin-top: 3px;
}
@media screen and (max-width: 769px) {
@ -226,8 +327,8 @@
margin-top: -0.5em;
padding-top: 0.9em;
.header-item {
padding-right: 0.5em;
.header-item:not(:last-child) {
padding-right: 0.2em;
}
}
}

View File

@ -1,10 +1,5 @@
<template>
<!-- <div <IF WE USE HAMMER JS>
v-hammer:swipe="onSwipeFiltersMenu"
:class="{
'repository-level-page': isRepositoryLevel,
'is-fullscreen': registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen
}"> -->
<div
:class="{
'repository-level-page': isRepositoryLevel,
@ -84,7 +79,9 @@
<span
@click="updateSearch()"
class="icon is-right">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-search"/>
</span>
</span>
</div>
</div>
@ -96,7 +93,11 @@
{{ $i18n.get('advanced_search') }}
</button> -->
<h3 class="has-text-weight-semibold">{{ $i18n.get('filters') }}</h3>
<h3
id="filters-label-landmark"
class="has-text-weight-semibold">
{{ $i18n.get('filters') }}
</h3>
<button
v-if="!isLoadingFilters &&
((filters.length >= 0 &&
@ -169,7 +170,8 @@
v-if="!isOnTheme">
<b-dropdown
:mobile-modal="true"
id="item-creation-options-dropdown">
id="item-creation-options-dropdown"
aria-role="list">
<button
class="button is-secondary"
slot="trigger">
@ -179,7 +181,7 @@
</span>
</button>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<router-link
id="a-create-item"
tag="div"
@ -187,13 +189,17 @@
{{ $i18n.get('add_one_item') }}
</router-link>
</b-dropdown-item>
<b-dropdown-item disabled>
<b-dropdown-item
aria-role="listitem"
disabled>
{{ $i18n.get('add_items_bulk') + ' (Not ready)' }}
</b-dropdown-item>
<b-dropdown-item disabled>
<b-dropdown-item
aria-role="listitem"
disabled>
{{ $i18n.get('add_items_external_source') + ' (Not ready)' }}
</b-dropdown-item>
<b-dropdown-item>
<b-dropdown-item aria-role="listitem">
<div
id="a-import-collection"
tag="div"
@ -211,17 +217,27 @@
v-if="!isOnTheme || (registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].dynamic_metadata)"
class="search-control-item">
<b-dropdown
v-tooltip="{
delay: {
show: 500,
hide: 300,
},
content: (totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? (adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? $i18n.get('info_current_view_mode_metadata_not_allowed') : $i18n.get('info_cant_select_metadata_without_items') : '',
autoHide: false,
placement: 'auto-start'
}"
ref="displayedMetadataDropdown"
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show">
class="show metadata-options-dropdown"
aria-role="list">
<button
class="button is-white"
:aria-label="$i18n.get('label_displayed_metadata')"
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_displayed_metadata') }}</span>
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
</span>
</button>
<div class="metadata-options-container">
@ -229,7 +245,8 @@
v-for="(column, index) in localDisplayedMetadata"
:key="index"
class="control"
custom>
custom
aria-role="listitem">
<b-checkbox
v-model="column.display"
:native-value="column.display">
@ -251,32 +268,29 @@
<!-- Change OrderBy Select and Order Button-->
<div class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_sorting') + ':' }}</label>
<b-dropdown
:disabled="totalItems <= 0"
@input="onChangeOrderBy($event)">
:mobile-modal="true"
@input="onChangeOrderBy($event)"
aria-role="list">
<button
:aria-label="$i18n.get('label_sorting')"
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_sorting') }}</span>
<span>{{ orderByName }}</span>
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown "/>
</span>
</button>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': metadatum != undefined && orderBy == metadatum.slug }"
:class="{ 'is-active': (orderBy != 'meta_value' && orderBy != 'meta_value_num' && orderBy == metadatum.slug) || ((orderBy == 'meta_value' || orderBy == 'meta_value_num') && metaKey == metadatum.id) }"
v-for="metadatum of sortingMetadata"
v-if="
totalItems > 0 &&
metadatum != undefined &&
metadatum.slug === 'creation_date' || (
metadatum.metadata_type_object &&
metadatum.metadata_type_object.related_mapped_prop == 'title'
)"
v-if="metadatum != undefined"
:value="metadatum"
:key="metadatum.slug">
:key="metadatum.slug"
aria-role="listitem">
{{ metadatum.name }}
</b-dropdown-item>
<!-- Once we have sorting by metadata we can use this -->
@ -327,22 +341,24 @@
v-if="isOnTheme"
class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_visualization') + ':&nbsp; ' }}</label>
<b-dropdown
@change="onChangeViewMode($event)"
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')">
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
<button
class="button is-white"
:aria-label="$i18n.get('label_view_mode')"
:aria-label="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization')"
slot="trigger">
<span
class="gray-icon view-mode-icon"
v-if="registeredViewModes[viewMode] != undefined"
v-html="registeredViewModes[viewMode].icon"/>
<span class="is-hidden-touch">&nbsp;&nbsp;&nbsp;{{ $i18n.get('label_visualization') }}</span>
<span class="is-hidden-touch">&nbsp;&nbsp;&nbsp;{{ registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization') }}</span>
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
</button>
<b-dropdown-item
@ -352,11 +368,12 @@
v-for="(viewModeOption, index) of enabledViewModes"
:key="index"
:value="viewModeOption"
v-if="registeredViewModes[viewModeOption] != undefined && registeredViewModes[viewModeOption].full_screen == false">
v-if="registeredViewModes[viewModeOption] != undefined && registeredViewModes[viewModeOption].full_screen == false"
aria-role="listitem">
<span
class="gray-icon"
v-html="registeredViewModes[viewModeOption].icon"/>
{{ registeredViewModes[viewModeOption].label }}
<span>{{ registeredViewModes[viewModeOption].label }}</span>
</b-dropdown-item>
</b-dropdown>
</b-field>
@ -365,17 +382,19 @@
v-if="!isOnTheme"
class="search-control-item">
<b-field>
<label class="label is-hidden-mobile">{{ $i18n.get('label_visualization') + ':' }}</label>
<b-dropdown
@change="onChangeAdminViewMode($event)"
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')">
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
<button
class="button is-white"
:aria-label="$i18n.get('label_view_mode')"
slot="trigger">
<span>
<span class="icon is-small gray-icon">
<span class="view-mode-icon icon is-small gray-icon">
<i
:class="{'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
'tainacan-icon-viewcards' : adminViewMode == 'cards',
@ -385,60 +404,65 @@
class="tainacan-icon"/>
</span>
</span>
&nbsp;&nbsp;&nbsp;{{ $i18n.get('label_visualization') }}
&nbsp;&nbsp;&nbsp;{{ adminViewMode != undefined ? $i18n.get('label_' + adminViewMode) : $i18n.get('label_table') }}
<span class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"/>
</span>
</button>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'table' }"
:value="'table'">
:value="'table'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewtable"/>
</span>
{{ $i18n.get('label_table') }}
<span>{{ $i18n.get('label_table') }}</span>
</b-dropdown-item>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'cards' }"
:value="'cards'">
:value="'cards'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewcards"/>
</span>
{{ $i18n.get('label_cards') }}
<span>{{ $i18n.get('label_cards') }}</span>
</b-dropdown-item>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'grid' }"
:value="'grid'">
:value="'grid'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewminiature"/>
</span>
{{ $i18n.get('label_thumbnails') }}
<span>{{ $i18n.get('label_thumbnails') }}</span>
</b-dropdown-item>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'records' }"
:value="'records'">
:value="'records'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewrecords"/>
</span>
{{ $i18n.get('label_records') }}
<span>{{ $i18n.get('label_records') }}</span>
</b-dropdown-item>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'masonry' }"
:value="'masonry'">
:value="'masonry'"
aria-role="listitem">
<span class="icon gray-icon">
<i class="tainacan-icon tainacan-icon-viewmasonry"/>
</span>
{{ $i18n.get('label_masonry') }}
<span>{{ $i18n.get('label_masonry') }}</span>
</b-dropdown-item>
</b-dropdown>
</b-field>
@ -468,7 +492,7 @@
<button
class="button is-white"
:aria-label="$i18n.get('label_urls')"
:disabled="this.totalItems == undefined || this.totalItems <= 0"
:disabled="totalItems == undefined || totalItems <= 0"
@click="openExposersModal()">
<span class="gray-icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-url"/>
@ -544,7 +568,7 @@
<button
aria-controls="items-list-results"
@click="advancedSearchResults = !advancedSearchResults"
class="button is-small is-outlined">{{ $i18n.get('edit_search') }}</button>
class="button is-outlined">{{ $i18n.get('edit_search') }}</button>
</p>
<p
v-if="advancedSearchResults"
@ -552,7 +576,7 @@
<button
aria-controls="items-list-results"
@click="isDoSearch = !isDoSearch"
class="button is-small is-secondary">{{ $i18n.get('search') }}</button>
class="button is-success">{{ $i18n.get('search') }}</button>
</p>
</div>
</div>
@ -592,7 +616,7 @@
<h3
id="items-list-landmark"
class="is-hidden">
class="sr-only">
{{ $i18n.get('label_items_list') }}
</h3>
@ -628,7 +652,8 @@
:total-items="totalItems"
:is-loading="isLoadingItems"
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"/>
:view-mode="adminViewMode"
@updateIsLoading="newIsLoading => isLoadingItems = newIsLoading"/>
<!-- Theme View Modes -->
<div
@ -654,7 +679,7 @@
<!-- Empty Placeholder (only used in Admin) -->
<section
v-if="!isOnTheme && !isLoadingItems && totalItems <= 0"
v-if="!isOnTheme && !isLoadingItems && totalItems == 0"
class="section">
<div class="content has-text-grey has-text-centered">
<p>
@ -679,6 +704,7 @@
<!-- Pagination -->
<pagination
:is-sorting-by-custom-metadata="isSortingByCustomMetadata"
v-if="totalItems > 0 &&
(!isOnTheme || (registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].show_pagination)) &&
(advancedSearchResults || !openAdvancedSearch)"/>
@ -763,6 +789,7 @@
import AdvancedSearch from '../../components/advanced-search/advanced-search.vue';
import ExposersModal from '../../components/other/exposers-modal.vue';
import AvailableImportersModal from '../../components/other/available-importers-modal.vue';
import CustomDialog from '../../components/other/custom-dialog.vue';
import { mapActions, mapGetters } from 'vuex';
export default {
@ -800,6 +827,9 @@
enabledViewModes: Object // Used only on theme,
},
computed: {
isSortingByCustomMetadata() {
return (this.orderBy != undefined && this.orderBy != '' && this.orderBy != 'title' && this.orderBy != 'date');
},
items() {
return this.getItems();
},
@ -838,6 +868,26 @@
},
showLoading() {
return this.isLoadingItems || this.isLoadingFilters || this.isLoadingMetadata;
},
metaKey() {
return this.getMetaKey();
},
orderByName() {
if (this.getOrderByName() != null && this.getOrderByName() != undefined && this.getOrderByName() != '') {
return this.getOrderByName();
} else {
for (let metadatum of this.sortingMetadata) {
if (
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug == 'creation_date' && (!metadatum.metadata_type_object || !metadatum.metadata_type_object.core)) && this.orderBy == 'date') ||
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug != 'creation_date' && (metadatum.metadata_type_object != undefined && metadatum.metadata_type_object.core)) && this.orderBy == metadatum.metadata_type_object.related_mapped_prop) ||
((this.orderBy != 'meta_value' && this.orderBy != 'meta_value_num' && metadatum.slug != 'creation_date' && (!metadatum.metadata_type_object || !metadatum.metadata_type_object.core)) && this.orderBy == metadatum.slug) ||
((this.orderBy == 'meta_value' || this.orderBy == 'meta_value_num') && this.getMetaKey() == metadatum.id)
)
return metadatum.name;
}
}
}
},
components: {
@ -882,10 +932,12 @@
'getSearchQuery',
'getStatus',
'getOrderBy',
'getOrderByName',
'getOrder',
'getViewMode',
'getTotalItems',
'getAdminViewMode'
'getAdminViewMode',
'getMetaKey'
]),
onSwipeFiltersMenu($event) {
if (this.registeredViewModes[this.viewMode] == undefined ||
@ -932,6 +984,7 @@
},
onChangeOrderBy(metadatum) {
this.$eventBusSearch.setOrderBy(metadatum);
this.showItemsHiddingDueSorting();
},
onChangeOrder() {
this.order == 'DESC' ? this.$eventBusSearch.setOrder('ASC') : this.$eventBusSearch.setOrder('DESC');
@ -965,7 +1018,8 @@
// Updates searchControlHeight before in case we need to adjust filters position on mobile
setTimeout(() => {
this.searchControlHeight = this.$refs['search-control'].clientHeight;
if (this.$refs['search-control'] != undefined)
this.searchControlHeight = this.$refs['search-control'].clientHeight;
}, 500);
},
onChangeDisplayedMetadata() {
@ -988,12 +1042,11 @@
// Updates Search
this.$eventBusSearch.addFetchOnly(
thumbnailMetadatum != undefined && thumbnailMetadatum.display ? 'thumbnail' : null +','+
creationDateMetadatum != undefined && creationDateMetadatum.display ? 'creation_date' : null +','+
authorNameMetadatum != undefined && authorNameMetadatum.display ? 'author_name': null +','+
(this.isRepositoryLevel ? 'title' : null) +','+
(this.isRepositoryLevel && descriptionMetadatum.display ? 'description' : null)
, false, fetchOnlyMetadatumIds.toString());
((thumbnailMetadatum != undefined && thumbnailMetadatum.display) ? 'thumbnail' : null) + ',' +
((creationDateMetadatum != undefined && creationDateMetadatum.display) ? 'creation_date' : null) + ',' +
((authorNameMetadatum != undefined && authorNameMetadatum.display) ? 'author_name': null) + ',' +
(this.isRepositoryLevel ? 'title' : null) + ',' +
(this.isRepositoryLevel && descriptionMetadatum.display ? 'description' : null), false, fetchOnlyMetadatumIds.toString());
// Closes dropdown
this.$refs.displayedMetadataDropdown.toggle();
@ -1118,10 +1171,20 @@
multiple: metadatum.multiple,
});
if (display)
fetchOnlyMetadatumIds.push(metadatum.id);
if (display) {
fetchOnlyMetadatumIds.push(metadatum.id);
}
if (
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship'
) {
this.sortingMetadata.push(metadatum);
}
}
this.sortingMetadata.push(metadatum);
}
let creationDateMetadatumDisplay = prefsFetchOnlyObject ? (prefsFetchOnlyObject[1] != null) : true;
@ -1186,20 +1249,31 @@
display: authorNameMetadatumDisplay
});
}
// Loads only basic attributes necessay to view modes that do not allow custom meta
// Loads only basic attributes necessary to view modes that do not allow custom meta
} else {
this.$eventBusSearch.addFetchOnly('thumbnail,creation_date,author_name,title,description', true, '');
this.sortingMetadata.push({
name: this.$i18n.get('label_title'),
metadatum: 'row_title',
metadata_type_object: {core: true, related_mapped_prop: 'title'},
metadata_type: undefined,
slug: 'title',
id: undefined,
display: true
});
if (this.isRepositoryLevel) {
this.sortingMetadata.push({
name: this.$i18n.get('label_title'),
metadatum: 'row_title',
metadata_type_object: {core: true, related_mapped_prop: 'title'},
metadata_type: undefined,
slug: 'title',
id: undefined,
display: true
});
}
for (let metadatum of this.metadata) {
if (metadatum.display !== 'never' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship') {
this.sortingMetadata.push(metadatum);
}
}
this.sortingMetadata.push({
name: this.$i18n.get('label_creation_date'),
@ -1219,25 +1293,51 @@
this.isLoadingMetadata = false;
});
},
showItemsHiddingDueSorting() {
if (this.isSortingByCustomMetadata &&
this.$userPrefs.get('neverShowItemsHiddenDueSortingDialog') != true) {
this.hasAnOpenModal = true;
this.$modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_items_hidden_due_sorting'),
onConfirm: () => {
this.hasAnOpenModal = false;
},
hideCancel: true,
showNeverShowAgainOption: tainacan_plugin.user_caps != undefined && tainacan_plugin.user_caps.length != undefined && tainacan_plugin.user_caps.length > 0,
messageKeyForUserPrefs: 'ItemsHiddenDueSorting'
}
});
}
},
adjustSearchControlHeight: _.debounce( function() {
this.$nextTick(() => {
this.searchControlHeight = this.$refs['search-control'] ? this.$refs['search-control'].clientHeight : 0;
if (this.$refs['search-control'] != undefined)
this.searchControlHeight = this.$refs['search-control'] ? this.$refs['search-control'].clientHeight + this.$refs['search-control'].offsetTop : 0;
this.isFiltersMenuCompressed = jQuery(window).width() <= 768;
});
}, 500)
},
removeEventListeners() {
// Component
this.$off();
// Window
window.removeEventListener('resize', this.adjustSearchControlHeight);
// $root
this.$root.$off('openAdvancedSearch');
// $eventBusSearch
this.$eventBusSearch.$off('isLoadingItems');
this.$eventBusSearch.$off('hasFiltered');
this.$eventBusSearch.$off('advancedSearchResults');
this.$eventBusSearch.$off('hasToPrepareMetadataAndFilters');
}, 500),
removeEventListeners() {
// Component
this.$off();
// Window
window.removeEventListener('resize', this.adjustSearchControlHeight);
// $root
this.$root.$off('openAdvancedSearch');
// $eventBusSearch
this.$eventBusSearch.$off('isLoadingItems');
this.$eventBusSearch.$off('hasFiltered');
this.$eventBusSearch.$off('advancedSearchResults');
this.$eventBusSearch.$off('hasToPrepareMetadataAndFilters');
},
},
created() {
@ -1267,7 +1367,7 @@
});
this.$eventBusSearch.$on('hasToPrepareMetadataAndFilters', (to) => {
/* This condition is to prevent a incorrect fetch by filter or metadata when we come from items
/* This condition is to prevent an incorrect fetch by filter or metadata when we come from items
* at collection level to items page at repository level
*/
@ -1316,7 +1416,7 @@
} else {
let prefsAdminViewMode = !this.isRepositoryLevel ? 'admin_view_mode_' + this.collectionId : 'admin_view_mode';
if (this.$userPrefs.get(prefsAdminViewMode) == undefined)
this.$eventBusSearch.setInitialAdminViewMode('cards');
this.$eventBusSearch.setInitialAdminViewMode('table');
else {
let existingViewMode = this.$userPrefs.get(prefsAdminViewMode);
if (existingViewMode == 'cards' ||
@ -1326,10 +1426,12 @@
existingViewMode == 'masonry')
this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode));
else
this.$eventBusSearch.setInitialAdminViewMode('cards');
this.$eventBusSearch.setInitialAdminViewMode('table');
}
}
this.showItemsHiddingDueSorting();
// Watches window resize to adjust filter's top position and compression on mobile
this.adjustSearchControlHeight();
window.addEventListener('resize', this.adjustSearchControlHeight);
@ -1340,6 +1442,7 @@
// Cancels previous Request
if (this.$eventBusSearch.searchCancel != undefined)
this.$eventBusSearch.searchCancel.cancel('Item search Canceled.');
}
}
</script>
@ -1348,6 +1451,16 @@
@import '../../scss/_variables.scss';
@keyframes open-full-screen {
from {
opacity: 0;
transform: scale(0.6);
}
to {
opacity: 1;
transform: scale(1.0);
}
}
.is-fullscreen {
position: absolute;
@ -1359,7 +1472,8 @@
height: 100vh;
z-index: 999999999;
background-color: black;
transition: all 0.3s ease;
transition: background-color 0.3s ease, width 0.3s ease, height 0.3s ease;
animation: open-full-screen 0.4s ease;
}
.collapse-all {
@ -1374,9 +1488,9 @@
h1, h2 {
font-size: 20px;
font-weight: 500;
margin-bottom: 0;
color: $gray5;
display: inline-block;
margin-bottom: 0;
}
.field.is-grouped {
margin-left: auto;
@ -1400,9 +1514,9 @@
h1, h2 {
font-size: 20px;
font-weight: 500;
margin-bottom: 0;
color: $gray5;
display: inline-block;
margin-bottom: 0;
}
.field.is-grouped {
margin-left: auto;
@ -1569,6 +1683,14 @@
flex-basis: 100%;
}
.label {
font-size: 0.875rem;
font-weight: normal;
margin-top: 3px;
margin-bottom: 2px;
cursor: default;
}
.button {
display: flex;
align-items: center;
@ -1582,7 +1704,6 @@
color: $gray4 !important;
padding-right: 10px;
}
.gray-icon .icon i::before,
.gray-icon i::before {
font-size: 1.3125rem !important;
@ -1590,8 +1711,9 @@
}
.view-mode-icon {
margin-right: 4px !important;
margin-right: 3px !important;
margin-top: 1px;
margin-left: 6px !important;
}
.dropdown-menu {
@ -1601,7 +1723,7 @@
padding: 0;
.metadata-options-container {
max-height: 240px;
max-height: 288px;
overflow: auto;
}
.dropdown-item {
@ -1613,7 +1735,7 @@
.dropdown-item-apply {
width: 100%;
border-top: 1px solid #efefef;
padding: 8px 12px 2px 12px;
padding: 8px 12px;
text-align: right;
}
.dropdown-item-apply .button {

View File

@ -1,7 +1,9 @@
<template>
<div class="columns is-fullheight">
<section class="column is-secondary-content">
<tainacan-collection-subheader :id="collectionId"/>
<tainacan-collection-subheader
:current-user-can-edit="currentUserCanEdit"
:id="collectionId"/>
<router-view
id="collection-page-container"
@ -13,20 +15,32 @@
<script>
import TainacanCollectionSubheader from '../../components/navigation/tainacan-collection-subheader.vue';
import { mapActions } from 'vuex';
export default {
name: 'CollectionPage',
data(){
return {
collectionId: Number
collectionId: Number,
currentUserCanEdit: Boolean
}
},
components: {
TainacanCollectionSubheader
},
methods: {
...mapActions('collection', [
'fetchCollectionUserCanEdit'
])
},
created(){
this.collectionId = parseInt(this.$route.params.collectionId);
this.$eventBusSearch.setCollectionId(this.collectionId);
},
mounted() {
this.fetchCollectionUserCanEdit(this.collectionId).then((caps) => {
this.currentUserCanEdit = caps;
}).catch((error) => this.$console.error(error));
}
}
</script>

View File

@ -31,6 +31,7 @@
formHooks['view-item']['begin-left'] != undefined">
<div
id="view-item-begin-left"
class="form-hook-region"
v-html="formHooks['view-item']['begin-left'].join('')"/>
</template>
@ -197,6 +198,7 @@
formHooks['view-item']['end-left'] != undefined">
<div
id="view-item-end-left"
class="form-hook-region"
v-html="formHooks['view-item']['end-left'].join('')"/>
</template>
@ -210,6 +212,7 @@
formHooks['view-item']['begin-right'] != undefined">
<div
id="view-item-begin-right"
class="form-hook-region"
v-html="formHooks['view-item']['begin-right'].join('')"/>
</template>
@ -278,7 +281,8 @@
v-for="(metadatum, index) of metadatumList"
:key="index"
class="field">
<b-collapse
<b-collapse
:aria-id="'metadatum-collapse-' + metadatum.id"
animation="filter-item"
:open="open">
<label
@ -292,14 +296,7 @@
</span>
{{ metadatum.metadatum.name }}
</label>
<div
v-if="metadatum.date_i18n"
class="content">
<p v-html="metadatum.date_i18n != '' ? metadatum.date_i18n : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
</div>
<div
v-else
class="content">
<div class="content">
<p v-html="metadatum.value_as_html != '' ? metadatum.value_as_html : `<span class='has-text-gray is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
</div>
</b-collapse>
@ -313,6 +310,7 @@
formHooks['view-item']['end-right'] != undefined">
<div
id="view-item-end-right"
class="form-hook-region"
v-html="formHooks['view-item']['end-right'].join('')"/>
</template>
</b-tab-item>
@ -338,6 +336,7 @@
<div class="footer">
<div class="form-submission-footer">
<router-link
v-if="item.current_user_can_edit"
class="button is-secondary"
:to="{ path: $routerHelper.getItemEditPath(collectionId, itemId)}">
{{ $i18n.getFrom('items','edit_item') }}
@ -466,7 +465,7 @@
});
// Obtains Item
this.fetchItem(this.itemId).then((item) => {
this.fetchItem({ itemId: this.itemId, contextEdit: true }).then((item) => {
this.$root.$emit('onCollectionBreadCrumbUpdate', [
{path: this.$routerHelper.getCollectionPath(this.collectionId), label: this.$i18n.get('items')},
{path: '', label: item.title}
@ -474,10 +473,12 @@
this.loadMetadata();
});
// Obtains collection name
// Obtains collection name
if (!this.isRepositoryLevel) {
this.fetchCollectionName(this.collectionId).then((collectionName) => {
this.collectionName = collectionName;
});
}
// Get attachments
this.fetchAttachments(this.itemId);

View File

@ -8,6 +8,7 @@ button.link-style:active {
color: $secondary;
padding: 0;
margin: 0;
font-weight: normal;
background: transparent;
&:hover {
@ -77,4 +78,5 @@ button.link-style:active {
.button:not(.is-small):not(.is-medium):not(.is-large) {
height: 1.875rem !important;
font-size: 0.875rem !important;
line-height: 1.5rem;
}

View File

@ -21,15 +21,20 @@
padding: 0px;
border-radius: 0px;
min-width: 6rem;
.dropdown-content {
padding: 6px 0px;
padding: 0px;
border-radius: 0px !important;
max-height: 240px;
overflow-y: auto;
.dropdown-item {
display: block;
text-decoration: none;
padding: 0.375rem 1rem;
font-size: 0.8125rem;
color: $tainacan-input-color !important;
label { margin-bottom: 0; }
&.control { font-size: 0.8125rem !important; }
.b-checkbox { width: 100% };
@ -66,6 +71,13 @@
}
}
// This dropdown has a particular way of dealing with scroll
.metadata-options-dropdown {
.dropdown-content {
max-height: unset !important;
}
}
.taginput-container {
padding: 0px !important;
background-color: white !important;

View File

@ -2,6 +2,12 @@
.modal .animation-content {
width: 100%;
}
.modal .modal-close {
z-index: 99999;
@media only screen and (max-width: 768px) {
&:before, &:after { background-color: #298596; }
}
}
.tainacan-modal-title {
display: flex;
@ -13,6 +19,7 @@
h1, h2 {
font-size: 1.25rem;
font-weight: normal;
font-weight: 500;
color: $gray5;
display: inline-block;
width: 90%;
@ -36,9 +43,11 @@
background-color: white;
padding: 40px 50px;
position: relative;
max-height: 100vh;
max-height: 86%;
max-height: 86vh;
overflow-y: auto;
overflow-x: hidden;
figure {
margin: 0;
text-align: center;
@ -50,6 +59,11 @@
.form-submit {
padding: 40px 0em 0.4em 0em !important;
}
@media only screen and (max-width: 768px) {
max-height: 100%;
max-height: 100vh;
}
}
// Bulma modals customized for Tainacan (custom-dialog.vue)
.dialog {
@ -89,12 +103,12 @@
margin-bottom: 12px;
}
.modal-card-body {
padding: 0px 0px 0px 16px;
padding: 0px 0px 12px 20px;
width: 50%;
}
.modal-card-foot {
justify-content: space-between;
padding: 24px 0px 0px 0px;
padding: 12px 0px 0px 0px;
width: 100%;
.button {

View File

@ -18,19 +18,29 @@
background-color: $blue5 !important;
color: white !important;
}
.has-text-primary, .has-text-primary:hover, .is-has-text-primary:focus {
color: $blue4 !important;
.dropdown .dropdown-menu .dropdown-content a.dropdown-item:hover {
color: black !important;
}
.has-text-primary,
.has-text-primary:hover,
.is-has-text-primary:focus,
a:not(.has-text-danger):not(.disabled),
a:hover:not(.has-text-danger):not(.disabled),
.has-text-secondary,
.has-text-secondary:hover,
.is-has-text-secondary:focus {
color: $blue3 !important;
color: $blue4 !important;
}
a.button.is-secondary,
a.button.is-secondary:hover {
color: white !important;
}
.tainacan-page-title hr{
background-color: $blue3 !important;
}
button.link-style, button.link-style:focus button.link-style:active {
color: $blue4;
}
.button[disabled]:not(.is-white), .button:hover[disabled]:not(.is-white) {
border: none !important;
cursor: not-allowed !important;
@ -96,4 +106,16 @@
.active-metadatum-item.not-focusable-item>.handle>.metadatum-name {
color: $blue3 !important;
}
.metadata-type-preview {
background-color: $blue1 !important;
.metadata-type-label {
color: $blue4 !important;
}
.autocomplete>.control, .autocomplete>.control>input, .dropdown-content {
background-color: #f9fcff !important;
}
&::before {
border-color: transparent transparent transparent $blue1 !important;
}
}
}

View File

@ -197,7 +197,7 @@
}
a:hover {
text-decoration: none !important;
}
}
}
img.table-thumb {
max-height: 38px !important;

View File

@ -117,4 +117,25 @@
border-color: $gray2;
padding: 1.25rem;
}
.autocomplete {
.dropdown-item {
white-space: initial !important;
}
}
.form-hook-region {
background-color: $gray1;
padding: 1rem 1.875rem 2rem 1.875rem;
h4 {
font-weight: 600;
color: #298596;
margin-bottom: 6px;
}
hr {
margin-top: 8px;
height: 1px;
background-color: #298596;
}
}
}

View File

@ -1,5 +1,8 @@
// These tooltips are customized versions of V-Tooltip
// Tooltips:
.b-tooltip::after {
box-shadow: none;
}
.tooltip {
z-index: 999999999;
display: block !important;
@ -89,4 +92,73 @@
opacity: 1;
transition: opacity .15s;
}
// Metadata type Preview tooltips
&.metadata-type-preview-tooltip[x-placement^="bottom"] {
top: -19px !important;
}
&.metadata-type-preview-tooltip[x-placement^="bottom"] .tooltip-inner {
max-height: initial !important;
}
&.metadata-type-preview-tooltip[x-placement^="bottom"] .tooltip-arrow {
border-width: 8px 10px 0px 10px !important;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
border-top-color: $turquoise1 !important;
top: initial !important;
bottom: -5px !important;
}
.metadata-type-preview {
background: $turquoise1;
padding: 0px 8px;
border-radius: 3px;
width: 200px;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
cursor: none;
flex-wrap: wrap;
.metadata-type-label {
font-weight: 600;
color: $turquoise4;
width: 100%;
font-size: 1rem;
margin-bottom: 6px;
margin-left: -18px;
}
input, select, textarea,
.input, .tags, .tag {
pointer-events: none;
cursor: none;
background-color: rgba(255,255,255,0.60) !important;
}
.autocomplete>.control, .autocomplete>.control>input, .dropdown-content {
background-color: #f7fcfd !important;
}
.taginput {
margin-bottom: 100px;
}
input[type="checkbox"]:checked + .check {
background: rgba(255,255,255,0.60) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3Cpath style='fill:rgb(69,70,71)' d='M 0.04038059,0.6267767 0.14644661,0.52071068 0.42928932,0.80355339 0.3232233,0.90961941 z M 0.21715729,0.80355339 0.85355339,0.16715729 0.95961941,0.2732233 0.3232233,0.90961941 z'%3E%3C/path%3E%3C/svg%3E") no-repeat center center !important
}
textarea {
min-height: 70px;
}
.field {
width: 100%;
.label {
color: $gray4;
}
}
.add-new-term {
font-size: 0.75rem;
text-decoration: underline;
margin: 0.875rem 1.5rem;
}
}
}

View File

@ -33,7 +33,7 @@ $gray2: #dbdbdb;
$gray2-invert: findColorInvert($gray2);
$gray3: #cbcbcb;
$gray3-invert: findColorInvert($gray3);
$gray4: #898d8f;
$gray4: #555758;//#555758;
$gray4-invert: findColorInvert($gray4);
$gray5: #454647;
$gray5-invert: findColorInvert($gray5);
@ -154,6 +154,18 @@ $family-sans-serif: 'Roboto', sans-serif;
// Bulma's modal (needs to be greather than tainacan-admin-app)
$modal-z: 9999999;
// A copy of bootstrap's screen reader only class to be used for accessibility.
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
// Animations for Slide Menu
@keyframes slide-menu-in {
from {

View File

@ -16,6 +16,7 @@
.tainacan-grid-item {
max-width: 255px;
min-height: 300px;
max-height: 300px;
flex-basis: 0;
margin: 15px;
text-align: center;

View File

@ -58,7 +58,7 @@
}
}
.thumbnail {
.tainacan-masonry-item-thumbnail {
background-size: cover;
background-color: #f6f6f6;
background-blend-mode: multiply;
@ -83,6 +83,7 @@
// background-blend-mode
.skeleton {
background: #fff;
color: transparent !important;
}
}

View File

@ -69,7 +69,7 @@
opacity: 0;
visibility: hidden;
}
.thumbnail {
.tainacan-record-thumbnail {
float: right;
margin: 0 0 25px 25px;
}

View File

@ -51,6 +51,9 @@ html {
}
// Tainacan Loading
.tainacan-icon {
opacity: 0; // Will make it 1 once window.load is done;
}
.loading-overlay {
z-index: 9999999999;
}

View File

@ -0,0 +1,105 @@
<style>
.tainacan-system-check .error {
border-left: 5px solid red;
margin-right: 10px;
}
.tainacan-system-check .warning {
border-left: 5px solid orange;
margin-right: 10px;
}
.tainacan-system-check .good {
border-left: 5px solid green;
margin-right: 10px;
}
</style>
<div class="wrap">
<h1><?php _e('Tainacan System Check', 'tainacan'); ?></h1>
<p><?php _e('This page checks your system against the Tainacan requirements. It helps you to find out whether your server is properly configured.', 'tainacan'); ?></p>
<p><?php printf( __('If you want to have a more complete diagnosis of your current WordPress instance, we recommend you to install the %1$sHealth Check & Troubleshooting%2$s plugin.', 'tainacan'), '<a href="https://wordpress.org/plugins/health-check/" target="_blank">', '</a>' ); ?></p>
<table class="form-table tainacan-system-check">
<tbody>
<tr>
<th scope="row"><?php _e('WordPress version', 'tainacan'); ?></th>
<td>
<?php $this->test_wordpress_version(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('PHP version', 'tainacan'); ?></th>
<td>
<?php $this->test_php_version(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Database version', 'tainacan'); ?></th>
<td>
<?php $this->test_sql_server(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('PHP Modules', 'tainacan'); ?></th>
<td>
<?php $this->test_php_extensions(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('PHP Maximum execution time', 'tainacan'); ?></th>
<td>
<?php $this->check_php_timeout(); ?>
<p class="description">
<?php _e('Some Tainacan features, such as import processes, may need a little extra time to run. It is a good idea to set the PHP maximum execution time to a bigger value than the default, although this is not mandatory. If you see a "Maximum execution time of XX seconds exceeded" in any error log, then you shoud definitely do it.', 'tainacan'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Permalinks Structure', 'tainacan'); ?></th>
<td>
<?php $this->check_permalink_settings(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Upload Folder', 'tainacan'); ?></th>
<td>
<?php $this->check_upload_permission(); ?>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Max Upload File size', 'tainacan'); ?></th>
<td>
<?php $this->check_max_upload_size(); ?>
<p class="description">
<?php _e('This is the maximum size of each individual upload to your site. You should increase it depending on your needs.', 'tainacan'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Cron', 'tainacan'); ?></th>
<td>
<?php _e('It is strongly recommended that you configure a cron job in your server as described <a href="https://developer.wordpress.org/plugins/cron/hooking-into-the-system-task-scheduler/">here</a>.', 'tainacan'); ?>
<p class="description">
<?php _e("We can't test whether there is a cronjob set or not, so ignore this if you already configured it.", 'tainacan'); ?>
</p>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,513 @@
<?php
namespace Tainacan;
class System_Check {
private $min_php_version = '5.6';
private $mysql_min_version_check;
private $mysql_rec_version_check;
public $mariadb = false;
private $mysql_server_version = null;
private $health_check_mysql_rec_version = '8.0';
private $health_check_mysql_min_version = '5.0';
public function __construct() {
$this->init();
}
public function init() {
$this->prepare_sql_data();
}
public function admin_page() {
include('admin-page.php');
}
public function test_php_version() {
$testphpmin = version_compare( $this->min_php_version, PHP_VERSION, '<=' );
$testphprec = version_compare( 7, PHP_VERSION, '<=' );
if ($testphprec) {
$class = 'good';
$text = PHP_VERSION;
} elseif ($testphpmin) {
$class = 'warning';
$text = PHP_VERSION . ' - ' . __('Version supported, but you should consider upgrade to PHP 7', 'tainacan') . ': ';
} else {
$class = 'error';
$text = PHP_VERSION . ' - ' . __('This PHP Version is not supported. Please upgrade to PHP 5.6 or higher!', 'tainacan');
}
printf( '<span class="%1$s"></span> %2$s', esc_attr( $class ), esc_html( $text ) );
}
private function prepare_sql_data() {
global $wpdb;
if ( method_exists( $wpdb, 'db_version' ) ) {
if ( $wpdb->use_mysqli ) {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
$mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
} else {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info
$mysql_server_type = mysql_get_server_info( $wpdb->dbh );
}
$this->mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );
}
if ( stristr( $mysql_server_type, 'mariadb' ) ) {
$this->mariadb = true;
$this->health_check_mysql_rec_version = '10.2.2';
$this->health_check_mysql_min_version = '10.0';
}
$this->mysql_min_version_check = version_compare( $this->health_check_mysql_min_version, $this->mysql_server_version, '<=' );
$this->mysql_rec_version_check = version_compare( $this->health_check_mysql_rec_version, $this->mysql_server_version, '<=' );
}
public function check_permalink_settings() {
$settings = get_option( 'permalink_structure' );
if ( empty($settings) ) {
$class = 'error';
$text = sprintf(
__('Tainacan requires your Permalink settings to be configured. Please visit %1$sPermalink settings%2$s and configure it.', 'tainacan'),
'<a href="'.admin_url('options-permalink.php').'">',
'</a>'
);
} else {
$class = 'good';
$text = 'Ok';
}
printf( '<span class="%1$s"></span> %2$s', esc_attr( $class ), $text );
}
public function check_php_timeout() {
$time = ini_get('max_execution_time');
$min = 30;
$rec = 240;
if ( $time < $min ) {
$class = 'error';
$text = sprintf(
__('Your current configuratino is %ds. This is too little. Please increase it to at least 30s', 'tainacan'),
$time
);
} elseif ( $time < $rec ) {
$class = 'warning';
$text = sprintf(
__('Your current configuration is %d seconds. This is fine, but you should consider increase it to at least 240 seconds if possible', 'tainacan'),
$time
);
} else {
$class = 'good';
$text = sprintf(
__('Your current configuratino is %ds. This is excellent.', 'tainacan'),
$time
);
}
printf( '<span class="%1$s"></span> %2$s', esc_attr( $class ), $text );
}
public function check_upload_permission() {
$upload_dir = wp_upload_dir();
$writable = is_writable($upload_dir['basedir']);
if ( ! $writable ) {
$class = 'error';
$text = sprintf(
__('Your upload folder is not writable by the server. You must fix your folder permissions.', 'tainacan')
);
} else {
$class = 'good';
$text = sprintf(
__('Your upload folder is writable!', 'tainacan')
);
}
printf( '<span class="%1$s"></span> %2$s', esc_attr( $class ), $text );
}
public function check_max_upload_size() {
$upload_max_size = ini_get('upload_max_filesize');
echo $upload_max_size;
}
/**
* Tests for WordPress version and outputs it.
*
* @return void It is an AJAX call.
*/
public function test_wordpress_version() {
$core_current_version = get_bloginfo( 'version' );
$core_updates = get_core_updates();
// Prepare for a class and text for later use.
$text = '';
$class = '';
if ( version_compare($core_current_version, '4.8') < 0 ) {
$class = 'error';
$text = sprintf(
__('Tainacan requires WordPress 4.8 or newer! Your version is %s. Please upgrade.'),
$core_current_version
);
} elseif ( ! is_array( $core_updates ) ) {
$class = 'warning';
$text = sprintf(
// translators: %s: Your current version of WordPress.
__( '%s - We were unable to check if any new versions are available.', 'health-check' ),
$core_current_version
);
} else {
foreach ( $core_updates as $core => $update ) {
if ( 'upgrade' === $update->response ) {
$current_version = explode( '.', $core_current_version );
$new_version = explode( '.', $update->version );
$current_major = $current_version[0] . '.' . $current_version[1];
$new_major = $new_version[0] . '.' . $new_version[1];
if ( $current_major !== $new_major ) {
// This is a major version mismatch.
$class = 'warning';
$text = sprintf(
// translators: %1$s: Your current version of WordPress. %2$s The latest version of WordPress available.
__( 'You are running WordPress %1$s. This version is supported, but you should always keep you WordPress installation updated. ( Latest version is %2$s )', 'tainacan' ),
$core_current_version,
$update->version
);
} else {
// This is a minor version, sometimes considered more critical.
$class = 'error';
$text = sprintf(
// translators: %1$s: Your current version of WordPress. %2$s The latest version of WordPress available.
__( 'You are running WordPress %1$s. ( Latest version is %2$s ) - We strongly urge you to update, as minor updates are often security related.', 'tainacan' ),
$core_current_version,
$update->version
);
}
} else {
$class = 'good';
$text = $core_current_version;
}
}
}
printf( '<span class="%1$s"></span> %2$s', esc_attr( $class ), esc_html( $text ) );
}
public function child_test_php_extension_availability( $extension = null, $function = null ) {
// If no extension or function is passed, claim to fail testing, as we have nothing to test against.
if ( null === $extension && null === $function ) {
return false;
}
$available = true;
if ( null !== $extension && ! extension_loaded( $extension ) ) {
$available = false;
}
if ( null !== $function && ! function_exists( $function ) ) {
$available = false;
}
return $available;
}
public function test_php_extensions() {
/*
* An array representing all the modules we wish to test for.
*
* array $modules {
* An associated array of modules to test for.
*
* array $module {
* An associated array of module properties used during testing.
* One of either `$function` or `$extension` must be provided, or they will fail by default.
*
* string $function Optional. A function name to test for the existence of.
* string $extension Optional. An extension to check if is loaded in PHP.
* bool $required Is this a required feature or not.
* string $fallback_for Optional. The module this module replaces as a fallback.
* }
* }
*/
$modules = array(
// 'bcmath' => array(
// 'function' => 'bcadd',
// 'required' => false,
// ),
'curl' => array(
'function' => 'curl_version',
'required' => false,
),
// 'exif' => array(
// 'function' => 'exif_read_data',
// 'required' => false,
// ),
// 'filter' => array(
// 'function' => 'filter_list',
// 'required' => false,
// ),
// 'fileinfo' => array(
// 'function' => 'finfo_file',
// 'required' => false,
// ),
// 'mod_xml' => array(
// 'extension' => 'libxml',
// 'required' => false,
// ),
// 'mysqli' => array(
// 'function' => 'mysqli_connect',
// 'required' => false,
// ),
// 'libsodium' => array(
// 'function' => 'sodium_compare',
// 'required' => false,
// ),
// 'openssl' => array(
// 'function' => 'openssl_encrypt',
// 'required' => false,
// ),
// 'pcre' => array(
// 'function' => 'preg_match',
// 'required' => false,
// ),
'imagick' => array(
'extension' => 'imagick',
'required' => false,
'message' => __('This is used, among other things, to automatically extract the first page of PDFs to use as a thumbnail.', 'tainacan')
),
'gd' => array(
'extension' => 'gd',
'required' => false,
'fallback_for' => 'imagick',
'message' => __('This is used for image processing, such as resizing and cropping images.', 'tainacan')
),
// 'mcrypt' => array(
// 'extension' => 'mcrypt',
// 'required' => false,
// 'fallback_for' => 'libsodium',
// ),
// 'xmlreader' => array(
// 'extension' => 'xmlreader',
// 'required' => false,
// 'fallback_for' => 'xml',
// ),
'zlib' => array(
'extension' => 'zlib',
'required' => false,
'fallback_for' => 'zip',
),
);
$failures = array();
foreach ( $modules as $library => $module ) {
$extension = ( isset( $module['extension'] ) ? $module['extension'] : null );
$function = ( isset( $module['function'] ) ? $module['function'] : null );
// If this module is a fallback for another function, check if that other function passed.
if ( isset( $module['fallback_for'] ) ) {
/*
* If that other function has a failure, mark this module as required for normal operations.
* If that other function hasn't failed, skip this test as it's only a fallback.
*/
if ( isset( $failures[ $module['fallback_for'] ] ) ) {
$module['required'] = true;
} else {
continue;
}
}
if ( ! $this->child_test_php_extension_availability( $extension, $function ) ) {
$failures[ $library ] = sprintf(
'<span class="%s"></span> %s',
( $module['required'] ? 'error' : 'warning' ),
sprintf(
// translators: %1$2: If a module is required or recommended. %2$s: The module name.
__( 'The %1$s module %2$s is not installed, or has been disabled.', 'tainacan' ),
( $module['required'] ? __( 'required', 'health-check' ) : __( 'optional', 'health-check' ) ),
$library
)
);
if ( isset($module['message']) ) {
$failures[ $library ] .= ' ' . $module['message'];
}
}
}
if ( ! empty( $failures ) ) {
echo '<ul>';
foreach ( $failures as $failure ) {
printf(
'<li>%s</li>',
$failure
);
}
echo '</ul>';
} else {
printf(
'<span class="good"></span> %s',
__( 'All required and recommended modules are installed.', 'health-check' )
);
}
}
public function test_sql_server() {
$status = 'good';
$notice = array();
$db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );
if ( ! $this->mysql_rec_version_check ) {
$status = 'warning';
$notice[] = sprintf(
// translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server recommended version number.
esc_html__( 'We strongly recommend running %1$s version %2$s or higher. Future features may depend on this versions.', 'tainacan' ),
( $this->mariadb ? 'MariaDB' : 'MySQL' ),
$this->health_check_mysql_rec_version
);
}
if ( ! $this->mysql_min_version_check ) {
$status = 'error';
$notice[] = sprintf(
// translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server minimum version number.
esc_html__( 'Tainacan requires %1$s version %2$s or higher.', 'tainacan' ),
( $this->mariadb ? 'MariaDB' : 'MySQL' ),
$this->health_check_mysql_min_version
);
}
if ( $db_dropin ) {
// translators: %s: The database engine in use (MySQL or MariaDB).
$notice[] = wp_kses(
sprintf(
// translators: %s: The name of the database engine being used.
__( 'You are using a <code>wp-content/db.php</code> drop-in which might mean that a %s database is not being used.', 'tainacan' ),
( $this->mariadb ? 'MariaDB' : 'MySQL' )
),
array(
'code' => true,
)
);
}
printf(
'<span class="%s"></span> %s',
esc_attr( $status ),
sprintf(
'%s%s',
esc_html( $this->mysql_server_version ),
( ! empty( $notice ) ? '<br> - ' . implode( '<br>', $notice ) : '' )
)
);
}
public function test_utf8mb4_support() {
global $wpdb;
if ( ! $this->mariadb ) {
if ( version_compare( $this->mysql_server_version, '5.5.3', '<' ) ) {
printf(
'<span class="warning"></span> %s',
sprintf(
/* translators: %s: Number of version. */
esc_html__( 'WordPress\' utf8mb4 support requires MySQL version %s or greater', 'health-check' ),
'5.5.3'
)
);
} else {
printf(
'<span class="good"></span> %s',
esc_html__( 'Your MySQL version supports utf8mb4', 'health-check' )
);
}
} else { // MariaDB introduced utf8mb4 support in 5.5.0
if ( version_compare( $this->mysql_server_version, '5.5.0', '<' ) ) {
printf(
'<span class="warning"></span> %s',
sprintf(
/* translators: %s: Number of version. */
esc_html__( 'WordPress\' utf8mb4 support requires MariaDB version %s or greater', 'health-check' ),
'5.5.0'
)
);
} else {
printf(
'<span class="good"></span> %s',
esc_html__( 'Your MariaDB version supports utf8mb4', 'health-check' )
);
}
}
if ( $wpdb->use_mysqli ) {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
$mysql_client_version = mysqli_get_client_info();
} else {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
$mysql_client_version = mysql_get_client_info();
}
/*
* libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
* mysqlnd has supported utf8mb4 since 5.0.9.
*/
if ( false !== strpos( $mysql_client_version, 'mysqlnd' ) ) {
$mysql_client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $mysql_client_version );
if ( version_compare( $mysql_client_version, '5.0.9', '<' ) ) {
printf(
'<br><span class="warning"></span> %s',
sprintf(
/* translators: %1$s: Name of the library, %2$s: Number of version. */
__( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
'mysqlnd',
'5.0.9'
)
);
}
} else {
if ( version_compare( $mysql_client_version, '5.5.3', '<' ) ) {
printf(
'<br><span class="warning"></span> %s',
sprintf(
/* translators: %1$s: Name of the library, %2$s: Number of version. */
__( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
'libmysql',
'5.5.3'
)
);
}
}
}
}
?>

View File

@ -6,7 +6,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'is_equal_to' => __( 'Equal', 'tainacan' ),
'is_not_equal_to' => __( 'Not equal', 'tainacan' ),
'contains' => __( 'Contains', 'tainacan' ),
'not_contains' => __( 'Not contains', 'tainacan' ),
'not_contains' => __( 'Do not contain', 'tainacan' ),
'greater_than' => __( 'Greater than', 'tainacan' ),
'less_than' => __( 'Less than', 'tainacan' ),
'greater_than_or_equal_to' => __( 'Greater than or equal to', 'tainacan' ),
@ -129,6 +129,7 @@ return apply_filters( 'tainacan-admin-i18n', [
// Labels (used mainly on Aria Labels and Inputs)
'label_clean' => __( 'Clear', 'tainacan' ),
'label_clear_filters' => __( 'Clear filters', 'tainacan' ),
'label_and' => __( 'and', 'tainacan' ),
'label_selected' => __( 'Selected', 'tainacan' ),
'label_relationship_new_search' => __( 'New Search', 'tainacan' ),
'label_relationship_items_found' => __( 'Items found', 'tainacan' ),
@ -145,6 +146,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_image' => __( 'Image', 'tainacan' ),
'label_thumbnail' => __( 'Thumbnail', 'tainacan' ),
'label_empty_thumbnail' => __( 'Empty Thumbnail', 'tainacan' ),
'label_empty_term_image' => __( 'Empty Term Image', 'tainacan' ),
'label_moderators' => __( 'Moderators', 'tainacan' ),
'label_parent_collection' => __( 'Parent collection', 'tainacan' ),
'label_no_parent_collection' => __( 'No parent collection', 'tainacan' ),
@ -261,6 +263,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_warning' => __( 'Warning', 'tainacan' ),
'label_error' => __( 'Error', 'tainacan' ),
'label_thumbnails' => __( 'Thumbnails', 'tainacan' ),
'label_grid' => __( 'Thumbnails', 'tainacan' ),
'label_table' => __( 'Table', 'tainacan' ),
'label_cards' => __( 'Cards', 'tainacan' ),
'label_records' => __( 'Records', 'tainacan' ),
@ -320,7 +323,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_show_filters' => __( 'Show filters menu', 'tainacan' ),
'label_select_all_items' => __( 'Select all items', 'tainacan' ),
'label_select_all' => __( 'Select all', 'tainacan' ),
'label_untrash_selected_items' => __( 'Recover from trash', 'tainacan' ),
'label_untrash_selected_items' => __( 'Restore from trash', 'tainacan' ),
'label_value_not_informed' => __( 'Value not informed.', 'tainacan' ),
'label_description_not_informed' => __( 'Description not informed.', 'tainacan' ),
'label_save_goto_metadata' => __( 'Save and Go to Metadata', 'tainacan' ),
@ -335,8 +338,8 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_selected_terms' => __( 'Selected terms', 'tainacan' ),
'label_editing_item_number' => __( 'Editing item n.', 'tainacan' ),
'label_sequence_editing_item' => __( 'Sequence editing: Item', 'tainacan' ),
'label_files_remaining' => __( 'files remaining.', 'tainacan' ),
'label_file_remaining' => __( 'file remaining.', 'tainacan' ),
'label_%s_files_remaining' => __( '%s files remaining.', 'tainacan' ),
'label_one_file_remaining' => __( 'One file remaining.', 'tainacan' ),
'label_upload_file_prepare_items' => __( 'Uploading files and preparing items', 'tainacan' ),
'label_bulk_edit_items' => __( 'Bulk edit items', 'tainacan' ),
'label_sequence_edit_items' => __( 'Sequence edit items', 'tainacan' ),
@ -366,6 +369,19 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_list_pagination' => __( 'List pagination', 'tainacan' ),
'label_sort_visualization' => __( 'Sorting and visualization control', 'tainacan' ),
'label_tainacan_api' => __( 'Tainacan API', 'tainacan' ),
'label_filter_type_preview' => __( 'Filter type preview', 'tainacan' ),
'label_metadatum_type_preview' => __( 'Metadatum type preview', 'tainacan' ),
'label_open_item_new_tab' => __( 'Open item in a new tab', 'tainacan' ),
'label_open_collection_new_tab' => __( 'Open collection in a new tab', 'tainacan' ),
'label_select_item' => __( 'Select item', 'tainacan' ),
'label_unselect_item' => __( 'Unselect item', 'tainacan' ),
'label_select_collection' => __( 'Select collection', 'tainacan' ),
'label_unselect_collection' => __( 'Unselect collection', 'tainacan' ),
'label_delete_item' => __( 'Delete item', 'tainacan' ),
'label_delete_collection' => __( 'Delete collection', 'tainacan' ),
'label_no_collections_using_taxonomy' => __( 'There is no collection using this taxonomy', 'tainacan' ),
'label_collections_using' => __( 'Collections using', 'tainacan' ),
'label_select_all_%s_items' => __( 'Select all %s items', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -374,7 +390,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_image_upload_box' => __( 'Drop an image here or click to upload.', 'tainacan' ),
'instruction_select_a_status' => __( 'Select a status:', 'tainacan' ),
'instruction_select_a_status2' => __( 'Select a status', 'tainacan' ),
'instruction_select_a_filter_type' => __( 'Select a filter type:', 'tainacan' ),
'instruction_click_to_select_a_filter_type' => __( 'Click to select a filter type:', 'tainacan' ),
'instruction_select_a_parent_term' => __( 'Select a parent term:', 'tainacan' ),
'instruction_select_a_metadatum' => __( 'Select a metadatum', 'tainacan' ),
'instruction_cover_page' => __( 'Type to search a Page to choose.', 'tainacan' ),
@ -395,15 +411,17 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_select_an_importer_type' => __( 'Select an importer from the options below:', 'tainacan' ),
'instruction_drop_file_or_click_to_upload' => __( 'Drop your source file or click here to upload.', 'tainacan' ),
'instruction_select_metadatum_type' => __( 'Select a metadatum type', 'tainacan' ),
'instruction_configure_new_metadatum' => __( 'Configure new metadatum.', 'tainacan' ),
'instruction_configure_new_metadatum' => __( 'Configure new metadatum', 'tainacan' ),
'instruction_insert_mapper_metadatum_info' => __( 'Insert the new mapper\'s metadatum info', 'tainacan' ),
'instruction_select_max_options_to_show' => __( 'Select max options to show', 'tainacan' ),
'instruction_select_collection_fetch_items' => __( 'Select a collection to fetch items', 'tainacan' ),
'instruction_select_a_action' => __( 'Select a action', 'tainacan' ),
'instruction_select_a_action' => __( 'Select an action', 'tainacan' ),
'instruction_parent_term' => __( 'Type to search a Parent Term to choose.', 'tainacan' ),
'instruction_type_existing_term' => __( 'Type to add an existing term...', 'tainacan' ),
'instruction_select_an_exporter_type' => __( 'Select an exporter from the options below:', 'tainacan'),
'instruction_select_a_collection' => __( 'Select a collection', 'tainacan' ),
'instruction_hover_a_filter_type_to_preview' => __( 'Hover a filter type to preview', 'tainacan' ),
'instruction_never_show_message_again' => __( 'Never show me this message again', 'tainacan' ),
// Info. Other feedback to user.
'info_error_invalid_date' => __( 'Invalid date', 'tainacan' ),
@ -519,15 +537,13 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_no_options_avialable_filtering' => __( 'No options for this filtering.', 'tainacan' ),
'info_no_options_found' => __( 'No options found.', 'tainacan' ),
'info_all_files_uploaded' => __( 'All files uploaded.', 'tainacan' ),
'info_there_are' => __( 'There are', 'tainacan' ),
'info_items_being_edited' => __( 'items being edited', 'tainacan' ),
'info_there_is' => __( 'There is', 'tainacan' ),
'info_there_are_%s_items_being_edited' => __( 'There are %s items being edited', 'tainacan' ),
'info_there_is_one_item_being_edited' => __( 'There is one item being edited', 'tainacan' ),
'info_item_being_edited' => __( 'item being edited', 'tainacan' ),
'info_no_preview_found' => __( 'No preview was found.', 'tainacan' ),
'info_leaving_bulk_edition' => __( 'You are leaving the bulk edition now.', 'tainacan' ),
'info_current_view_mode_metadata_not_allowed' => __( 'Current view mode does not allow displayed metadata selection.', 'tainacan' ),
'info_cant_select_metadata_without_items' => __( 'Can not select displayed metadata without items on list.', 'tainacan' ),
'info_available_exporters_helper' => __( '?', 'tainacan' ),
'info_process_status_finished' => __('Finished', 'tainacan'),
'info_process_status_finished_errors' => __('Finished with errors', 'tainacan'),
'info_process_status_errored' => __('Failed', 'tainacan'),
@ -538,8 +554,9 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_empty' => __( 'empty', 'tainacan' ),
'info_url_copied' => __( 'URL link copied', 'tainacan' ),
'info_other_item_listing_options' => __('Other items listing options: ', 'tainacan'),
'info_send_email' => __('The exporter may take a while depending on the size of your collection. Check this option to receive an e-mail when the process is done. You can also check the process status visiting the', 'tainacan'),
'info_send_email' => __('The exporter may take a while. Check this option to receive an e-mail when the process is done. You can also check the process status visiting the', 'tainacan'),
'info_tainacan_api' => __('Tainacan API on JSON format.', 'tainacan'),
'info_items_hidden_due_sorting' => __('When ordering by metadata value, items that have no value for the chosen metadata will not be listed. This list may have less elements than the total existing for current search criteria.', 'tainacan'),
// Tainacan Metadatum Types
'tainacan-text' => __( 'Text', 'tainacan' ),

View File

@ -67,6 +67,10 @@ export default {
display: flex;
-webkit-overflow-scrolling: touch;
.tainacan-icon {
opacity: 0; // Will make it 1 once window.load is done;
}
a, a:not([href]){ color: $secondary }
a:hover, a:hover:not([href]) {
cursor: pointer;

View File

@ -58,7 +58,7 @@ class REST_Background_Processes_Controller extends REST_Controller {
],
'recent' => [
'type' => 'bool',
'description' => __( 'Return only processes created or updated recently', 'tainacan' ),
'description' => __( 'Returns only processes created or updated recently', 'tainacan' ),
],
],
),

View File

@ -181,6 +181,7 @@ class REST_Collections_Controller extends REST_Controller {
$item_arr['moderators'] = $moderators;
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
unset($item_arr['moderators_ids']);
@ -200,6 +201,7 @@ class REST_Collections_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
$item_arr['url'] = get_permalink( $item_arr['id'] );

View File

@ -23,7 +23,7 @@ class REST_Filter_Types_Controller extends REST_Controller {
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => [
'filter-type' => [
'description' => __('The structure of objects returned.'),
'description' => __('Returns the structure of the objects.'),
'items' => [
'className' => [
'type' => 'string'

View File

@ -326,6 +326,7 @@ class REST_Filters_Controller extends REST_Controller {
if($request['context'] === 'edit'){
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
$item_arr['enabled'] = $item->get_enabled_for_collection();
}

View File

@ -100,6 +100,7 @@ class REST_Item_Metadata_Controller extends REST_Controller {
if($request['context'] === 'edit'){
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
return $item_arr;

View File

@ -161,6 +161,7 @@ class REST_Items_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
$img_size = 'large';
@ -206,6 +207,7 @@ class REST_Items_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
$item_arr['url'] = get_permalink( $item_arr['id'] );
@ -405,19 +407,20 @@ class REST_Items_Controller extends REST_Controller {
* @throws \Exception
*/
public function prepare_item_for_database( $request ) {
$item = new Entities\Item();
$item_as_array = $request[0];
foreach ($item_as_array as $key => $value){
$set_ = 'set_' . $key;
$this->item->$set_($value);
$item->set($key, $value);
}
$collection = $this->collections_repository->fetch($request[1]);
$this->item->set_collection($collection);
$item->set_collection($collection);
return $this->item;
return $item;
}
/**
@ -438,13 +441,13 @@ class REST_Items_Controller extends REST_Controller {
}
try {
$this->prepare_item_for_database( [ $item, $collection_id ] );
$item_obj = $this->prepare_item_for_database( [ $item, $collection_id ] );
} catch (\Exception $exception){
return new \WP_REST_Response($exception->getMessage(), 400);
}
if($this->item->validate()) {
$item = $this->items_repository->insert($this->item );
$item = $this->items_repository->insert( $item_obj );
return new \WP_REST_Response($this->prepare_item_for_response($item, $request), 201 );
}

View File

@ -295,6 +295,7 @@ class REST_Metadata_Controller extends REST_Controller {
if($request['context'] === 'edit'){
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
ob_start();
$item->get_metadata_type_object()->form();
$form = ob_get_clean();

View File

@ -23,7 +23,7 @@ class REST_Metadata_Types_Controller extends REST_Controller {
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => [
'metadata-type' => [
'description' => __('The structure of objects returned.'),
'description' => __('Returns the structure of the objects.'),
'items' => [
'errors' => [
'type' => 'string'

View File

@ -0,0 +1,127 @@
<?php
namespace Tainacan\API\EndPoints;
use Tainacan\OAIPMHExpose;
use \Tainacan\API\REST_Controller;
class REST_Oaipmh_Expose_Controller extends REST_Controller {
/**
* REST_Facets_Controller constructor.
*/
public function __construct() {
$this->rest_base = 'oai';
parent::__construct();
add_action('init', array(&$this, 'init_objects'), 11);
}
/**
* Initialize objects after post_type register
*/
public function init_objects() {
$this->controller_oai = new \Tainacan\OAIPMHExpose\OAIPMH_Expose();
$this->list_sets = new \Tainacan\OAIPMHExpose\OAIPMH_List_Sets();
$this->list_metadata_formats = new \Tainacan\OAIPMHExpose\OAIPMH_List_Metadata_Formats();
$this->list_records = new \Tainacan\OAIPMHExpose\OAIPMH_List_Records();
$this->get_record = new \Tainacan\OAIPMHExpose\OAIPMH_Get_Record();
$this->identify = new \Tainacan\OAIPMHExpose\OAIPMH_Identify();
$this->identifiers = new \Tainacan\OAIPMHExpose\OAIPMH_List_Identifiers();
}
public function register_routes() {
register_rest_route($this->namespace, '/' . $this->rest_base, array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_verb'),
'permission_callback' => array($this, 'get_verb_permissions_check')
)
));
}
/**
* @param \WP_REST_Request $request
*
* @return bool|\WP_Error
*/
public function get_verb_permissions_check( $request ) {
return true;
}
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
* @throws \Exception
*/
public function get_verb( $request ){
$request['verb'] = ( isset($request['verb']) ) ? $request['verb'] : 'Identify';
switch ($request['verb']){
case 'ListSets':
$allowed_arguments = array('verb','resumptionToken');
foreach ($request as $key => $value) {
if(!in_array($key, $allowed_arguments)){
$this->list_sets->config();
$this->list_sets->errors[] = $this->list_sets->oai_error('badArgument');
$this->list_sets->oai_exit($request, $this->list_sets->errors);
}
}
$this->list_sets->list_sets($request);
break;
case 'ListRecords':
if ( !isset($request['metadataPrefix']) && !isset($request['resumptionToken']) ) {
$this->list_records->config();
$this->list_records->errors[] = $this->list_records->oai_error('missingArgument','metadataPrefix');
$this->list_records->oai_exit($request, $this->list_records->errors);
}
$this->list_records->list_records($request);
break;
case 'ListIdentifiers':
if ( !isset($request['metadataPrefix']) && !isset($request['resumptionToken']) ) {
$this->identifiers->config();
$this->identifiers->errors[] = $this->list_records->oai_error('missingArgument','metadataPrefix');
$this->identifiers->oai_exit($request, $this->list_records->errors);
}
$this->identifiers->list_identifiers($request);
break;
case 'GetRecord':
if ( !isset($request['metadataPrefix']) ) {
$this->get_record->config();
$this->get_record->errors[] = $this->get_record->oai_error('missingArgument','metadataPrefix');
$this->get_record->oai_exit( $request, $this->get_record->errors );
}
if( !isset($request['identifier']) ){
$this->get_record->config();
$this->get_record->errors[] = $this->get_record->oai_error('missingArgument','identifier');
$this->get_record->oai_exit( $request, $this->get_record->errors );
}
$this->get_record->get_record( $request );
break;
case 'ListMetadataFormats':
$this->list_metadata_formats->list_metadata_formats($request);
break;
case 'Identify':
$this->identify->identify($request);
break;
default:
$this->controller_oai->config();
$this->controller_oai->errors[] = $this->controller_oai->oai_error('noVerb');
$this->controller_oai->oai_exit( $request, $this->controller_oai->errors);
break;
}
die;
}
}

View File

@ -25,6 +25,7 @@ class REST_Taxonomies_Controller extends REST_Controller {
public function init_objects() {
$this->taxonomy = new Entities\Taxonomy();
$this->taxonomy_repository = Repositories\Taxonomies::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
}
public function register_routes() {
@ -99,6 +100,16 @@ class REST_Taxonomies_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
$item_arr['collections'] = [];
if ( is_array($tax_collections = $item->get_collections()) ) {
foreach ($tax_collections as $tax_collection) {
if ( $tax_collection instanceof \Tainacan\Entities\Collection ) {
$item_arr['collections'][] = $tax_collection->_toArray();
}
}
}
}
} else {
$attributes_to_filter = $request['fetch_only'];

View File

@ -261,6 +261,7 @@ class REST_Terms_Controller extends REST_Controller {
if ( $request['context'] === 'edit' ) {
$item_arr['current_user_can_edit'] = $item->can_edit();
$item_arr['current_user_can_delete'] = $item->can_delete();
}
$children = get_terms([

View File

@ -21,6 +21,7 @@ $rest_exposers_controller = new \Tainacan\API\EndPoints\REST_Exposers_Control
new \Tainacan\API\EndPoints\REST_Export_Controller();
new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller();
$rest_facets_controller = new \Tainacan\API\EndPoints\REST_Facets_Controller();
$rest_oaipmh_expose_controller = new \Tainacan\API\EndPoints\REST_Oaipmh_Expose_Controller();
// Add here other endpoints imports
?>

View File

@ -2,8 +2,8 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20170910 at Thu Dec 20 15:06:27 2018
By Jimmy Wärting
Created by FontForge 20161003 at Thu Feb 7 11:51:11 2019
By www-data
</metadata>
<defs>
<font id="TainacanIcons" horiz-adv-x="1000" >
@ -45,25 +45,25 @@ d="M583 254v-328q3 -21 -12 -35q-12 -12 -29 -12t-30 12l-83 84q-15 15 -12 35v244h-
<glyph glyph-name="importers" unicode="importers"
d="M417 84v124h-332v84h332v124l167 -166zM833 0q0 -34 -24 -58.5t-59 -24.5h-499q-35 0 -59 24.5t-24 58.5v125h83v-125h499v500h-499v-125h-83v125q0 34 24 58.5t59 24.5h499q35 0 59 -24t24 -59v-500z" />
<glyph glyph-name="settings" unicode="settings"
d="M817 163q12 -9 4 -22l-66 -115q-7 -12 -21 -7l-82 33q-14 -10 -27.5 -18t-29.5 -15l-12 -88q-2 -14 -16 -14h-134q-14 0 -16 14l-13 88q-15 7 -28.5 15t-27.5 18l-83 -33q-5 -2 -11 0t-9 7l-67 115q-7 13 4 22l71 55q-3 15 -3 32t3 32l-70 55q-12 9 -4 22l66 115
q7 12 21 7l82 -33q14 10 27.5 18t29.5 15l12 88q2 14 16 14h134q14 0 16 -14l13 -88q15 -7 28.5 -15t27.5 -18l83 33q5 2 11 0t9 -7l67 -115q7 -13 -4 -22l-71 -55q3 -15 3 -32q0 -8 -0.5 -16t-1.5 -16zM500 125q26 0 48.5 10t39.5 27t27 39.5t10 48.5t-10 48.5t-27 39.5
t-39.5 27t-48.5 10t-48.5 -10t-39.5 -27t-27 -39.5t-10 -48.5t10 -48.5t27 -39.5t39.5 -27t48.5 -10z" />
d="M817 163q12 -9 4 -22l-66 -115q-7 -12 -21 -7l-82 33q-14 -10 -27.5 -18t-29.5 -15l-12 -88q-2 -14 -16 -14h-134q-14 0 -16 14l-13 88q-27 12 -56 33l-83 -33q-13 -6 -20 7l-67 115q-7 13 4 22l71 55q-3 15 -3 32t3 32l-70 55q-12 9 -4 22l66 115q7 12 21 7l82 -33
q14 10 27.5 18t29.5 15l12 88q2 14 16 14h134q14 0 16 -14l13 -88q27 -12 56 -33l83 33q13 6 20 -7l67 -115q7 -13 -4 -22l-71 -55q3 -15 3 -32q0 -8 -0.5 -16t-1.5 -16zM500 125q26 0 48.5 10t39.5 27t27 39.5t10 48.5t-10 48.5t-27 39.5t-39.5 27t-48.5 10t-48.5 -10
t-39.5 -27t-27 -39.5t-10 -48.5t10 -48.5t27 -39.5t39.5 -27t48.5 -10z" />
<glyph glyph-name="uni21B8" unicode="home"
d="M208 -125v333h-125l417 375l417 -375h-125v-333h-209v250h-166v-250h-209z" />
<glyph glyph-name="tour" unicode="tour"
d="M792 668q35 0 59 -24.5t24 -59.5v-583q0 -35 -24 -59.5t-59 -24.5h-167l-125 -125l-125 125h-167q-35 0 -59 24.5t-24 59.5v583q0 35 24 59.5t59 24.5h584zM542 84h-84v-83h84v83zM628 324q18 18 28.5 42t10.5 52q0 35 -13 65t-36 52.5t-53 35.5t-65 13q-34 0 -64.5 -13
t-53.5 -35.5t-36 -52.5t-13 -65h84q0 34 24 58.5t59 24.5t59 -24.5t24 -58.5q0 -35 -24 -59l-52 -53q-23 -23 -36 -53t-13 -65v-20h84q0 23 3.5 40t9.5 30.5t15 24.5t20 22z" />
t-53.5 -35.5t-36 -52.5t-13 -65h84q0 34 24 58.5t59 24.5t59 -24.5t24 -58.5q0 -35 -24 -59l-52 -53q-23 -23 -36 -53t-13 -65v-20h84q0 47 12.5 70.5t35.5 46.5z" />
<glyph glyph-name="processes" unicode="processes"
d="M542 458h-126v-291h-83v291h-125l167 167zM792 42l-167 -167l-167 167h126v291h83v-291h125z" />
d="M375 625l167 -167h-126v-291h-83v291h-125zM667 42h125l-167 -167l-167 167h126v291h83v-291z" />
<glyph glyph-name="help" unicode="help"
d="M458 83h84v-83h-84v83zM500 666q86 0 162 -32.5t132.5 -89t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89t162 32.5zM500 -84q69 0 129.5 26.5t106 71.5t71.5 106t26 130
t-26 129.5t-71.5 105.5t-106 71.5t-129.5 26.5t-129.5 -26.5t-106 -71.5t-71.5 -105.5t-26 -129.5t26 -130t71.5 -106t106 -71.5t129.5 -26.5zM500 500q35 0 65 -13t53 -36t36 -53t13 -65q0 -39 -19.5 -63.5t-43 -45t-43 -42.5t-19.5 -57h-84q0 34 9.5 56.5t23 39t30 28
t30 23.5t23 26t9.5 35q0 35 -24 59t-59 24t-59 -24t-24 -59h-84q0 35 13 65t36 53t53.5 36t64.5 13z" />
t-26 129.5t-71.5 105.5t-106 71.5t-129.5 26.5t-129.5 -26.5t-106 -71.5t-71.5 -105.5t-26 -129.5t26 -130t71.5 -106t106 -71.5t129.5 -26.5zM500 500q35 0 65 -13t53 -36t36 -53t13 -65q0 -39 -19.5 -63.5t-43 -45t-43 -42.5t-19.5 -57h-84q0 51 19.5 78t43 45.5t43 36
t19.5 48.5q0 35 -24 59t-59 24t-59 -24t-24 -59h-84q0 35 13 65t36 53t53.5 36t64.5 13z" />
<glyph glyph-name="share" unicode="share"
d="M750 76q25 0 47.5 -9.5t39 -26t26 -39t9.5 -47.5t-9.5 -47t-26 -38.5t-39 -26t-47.5 -9.5t-47.5 9.5t-39 26t-26 38.5t-9.5 47q0 7 1 14t3 13l-297 174q-17 -16 -38.5 -25t-46.5 -9q-26 0 -48.5 10t-39.5 27t-27 39.5t-10 48.5t10 48.5t27 39.5t39.5 27t48.5 10
q25 0 46.5 -9t38.5 -25l294 172q-2 7 -3 14t-1 15q0 26 10 48.5t27 39.5t39.5 27t48.5 10t48.5 -10t39.5 -27t27 -39.5t10 -48.5t-10 -48.5t-27 -39.5t-39.5 -27t-48.5 -10q-25 0 -46.5 9t-38.5 24l-294 -171q2 -7 3 -14t1 -15t-1 -15t-3 -14l297 -173q35 32 82 32z" />
d="M668 44q35 32 82 32q51 0 86.5 -35.5t35.5 -86.5t-35.5 -86t-86.5 -35t-86.5 35t-35.5 86q0 7 1 14t3 13l-297 174q-17 -16 -38.5 -25t-46.5 -9q-26 0 -48.5 10t-39.5 27t-27 39.5t-10 48.5t10 48.5t27 39.5t39.5 27t48.5 10q25 0 46.5 -9t38.5 -25l294 172q-2 7 -3 14
t-1 15q0 26 10 48.5t27 39.5t39.5 27t48.5 10t48.5 -10t39.5 -27t27 -39.5t10 -48.5t-10 -48.5t-27 -39.5t-39.5 -27t-48.5 -10q-25 0 -46.5 9t-38.5 24l-294 -171q2 -7 3 -14t1 -15t-1 -15t-3 -14z" />
<glyph glyph-name="export" unicode="export"
d="M958 242l-166 166v-124h-292v-84h292v-124zM84 -9v501q0 18 6.5 33t18 26.5t26.5 18t32 6.5h460q35 0 59 -24.5t24 -59.5v-125h-83v125h-460v-501h460v126h83v-126q0 -35 -24 -59.5t-59 -24.5h-460q-35 0 -59 24.5t-24 59.5z" />
d="M958 242l-166 166v-124h-292v-84h292v-124zM84 -9v501q0 35 24 59.5t59 24.5h460q35 0 59 -24.5t24 -59.5v-125h-83v125h-460v-501h460v126h83v-126q0 -35 -24 -59.5t-59 -24.5h-460q-35 0 -59 24.5t-24 59.5z" />
<glyph glyph-name="url" unicode="url"
d="M162 251q0 -27 10 -50.5t28 -41t41.5 -27.5t50.5 -10h166v-79h-166q-43 0 -81.5 16.5t-66.5 44.5t-44.5 66t-16.5 81t16.5 81t44.5 66.5t66.5 45t81.5 16.5h166v-80h-166q-27 0 -50.5 -10t-41.5 -27.5t-28 -41t-10 -50.5zM333 293h334v-84h-334v84zM709 460
q43 0 81 -16.5t66 -45t44.5 -66.5t16.5 -81t-16.5 -81t-44.5 -66.5t-66 -45t-81 -16.5h-167v80h167q27 0 50.5 10t41 27.5t27.5 41t10 50.5t-10 50.5t-27.5 41t-41 27.5t-50.5 10h-167v80h167z" />
@ -73,7 +73,7 @@ t139 24t97 57.5t61 69t31 57.5q-9 22 -31 57.5t-61 69t-97 58t-139 24.5zM500 543q63
q28 82 83 146q24 27 55.5 53.5t72.5 47t92 33t114 12.5v0z" />
<glyph glyph-name="search" unicode="search"
d="M207 337q0 -42 16 -79.5t44 -65.5t65.5 -44t80.5 -16q42 0 79.5 16t65.5 44t44 65.5t16 79.5q0 43 -16 80.5t-44 65.5t-65.5 44t-79.5 16q-43 0 -80.5 -16t-65.5 -44t-44 -65.5t-16 -80.5zM125 337q0 60 22.5 112.5t61.5 91.5t91.5 61.5t112.5 22.5t112.5 -22.5
t91.5 -61.5t61.5 -91.5t22.5 -112.5q0 -38 -9 -72t-26 -65l209 -209q-3 -31 -17 -56q-11 -21 -34.5 -39.5t-64.5 -20.5l-209 209q-31 -17 -65 -26t-72 -9q-60 0 -112.5 22.5t-91.5 61.5t-61.5 91.5t-22.5 112.5z" />
t91.5 -61.5t61.5 -91.5t22.5 -112.5q0 -38 -9 -72t-26 -65l209 -209q-3 -31 -17 -56q-11 -21 -34 -39.5t-65 -20.5l-209 209q-31 -17 -65 -26t-72 -9q-60 0 -112.5 22.5t-91.5 61.5t-61.5 91.5t-22.5 112.5z" />
<glyph glyph-name="edit" unicode="edit"
d="M595 519l174 -174l-512 -512h-174v174zM819 395l-174 174l85 84q14 14 32.5 14t32.5 -14l108 -108q14 -14 14 -32.5t-14 -32.5z" />
<glyph glyph-name="uni2421" unicode="delete"
@ -81,7 +81,7 @@ d="M250 458h500v-500q0 -35 -24 -59t-59 -24h-334q-34 0 -58.5 24t-24.5 59v500zM792
<glyph glyph-name="deleteforever" unicode="deleteforever"
d="M250 458h500v-500q0 -35 -24 -59t-59 -24h-334q-34 0 -58.5 24t-24.5 59v500zM458 167l-104 -105l42 -41l104 104l104 -104l42 42l-104 104l104 104l-42 42l-104 -105l-104 105l-42 -42zM792 583v-83h-584v83h146l42 42h208l42 -42h146z" />
<glyph glyph-name="undo" unicode="undo"
d="M417 375q109 -16 188.5 -60t134 -106.5t87 -138t48.5 -153.5q-78 110 -189.5 161t-268.5 51v-171l-292 292l292 292v-167z" />
d="M125 250l292 292v-167q109 -16 188.5 -60t134 -106.5t87 -138t48.5 -153.5q-78 110 -189.5 161t-268.5 51v-171z" />
<glyph glyph-name="add" unicode="add"
d="M500 666q86 0 162 -33t132.5 -89.5t89.5 -132t33 -161.5t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89 132.5t-32.5 162t32.5 161.5t89 132t132.5 89.5t162 33zM750 312h-188v187h-124v-187h-188v-125h188v-187h124v187h188v125z" />
<glyph glyph-name="public" unicode="public"
@ -90,14 +90,14 @@ q-4 -18 -6.5 -36.5t-2.5 -38.5q0 -64 22.5 -120.5t62 -101t93 -73t114.5 -36.5v81zM5
" />
<glyph glyph-name="private" unicode="private"
d="M750 416q35 0 59 -24t24 -59v-417q0 -35 -24 -59t-59 -24h-500q-35 0 -59 24.5t-24 58.5v417q0 35 24 59t59 24h42v84q0 43 16.5 81t44.5 66t66 44.5t81 16.5t81 -16.5t66 -44.5t44.5 -66t16.5 -81v-84h42zM500 41q35 0 59 24.5t24 59.5t-24 59t-59 24t-59 -24t-24 -59
t24 -59.5t59 -24.5zM625 500q0 27 -9.5 49.5t-26.5 39.5t-39.5 26.5t-49.5 9.5t-49.5 -9.5t-39.5 -26.5t-26.5 -39.5t-9.5 -49.5v-84h250v84z" />
t24 -59.5t59 -24.5zM625 500q0 54 -35.5 89.5t-89.5 35.5t-89.5 -35.5t-35.5 -89.5v-84h250v84z" />
<glyph glyph-name="draft" unicode="draft"
d="M709 417h-417v-84h417v84zM709 250h-417v-83h417v83zM583 83h-291v-83h291v83zM500 584q-17 0 -29.5 -12.5t-12.5 -29.5t12.5 -29.5t29.5 -12.5t29.5 12.5t12.5 29.5t-12.5 29.5t-29.5 12.5zM792 584q35 0 59 -24.5t24 -59.5v-584q0 -35 -24 -59t-59 -24h-584
q-35 0 -59 24t-24 59v584q0 35 24 59.5t59 24.5h174q14 36 45.5 59.5t72.5 23.5t72.5 -23.5t45.5 -59.5h174z" />
<glyph glyph-name="download" unicode="download"
d="M208 1h584v-84h-584v84zM500 84l-292 292h167v250h250v-250h167z" />
d="M375 376v250h250v-250h167l-292 -292l-292 292h167zM208 1h584v-84h-584v84z" />
<glyph glyph-name="upload" unicode="upload"
d="M792 500h-584v84h584v-84zM500 417l292 -292h-167v-250h-250v250h-167z" />
d="M208 125l292 292l292 -292h-167v-250h-250v250h-167zM208 500v84h584v-84h-584z" />
<glyph glyph-name="playfill" unicode="playfill"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM667 250l-250 188v-376z" />
<glyph glyph-name="play" unicode="play"
@ -121,7 +121,7 @@ t129.5 26q49 0 94 -13.5t83 -38.5l-60 -60q-26 14 -55.5 21.5t-61.5 7.5q-52 0 -97.5
<glyph glyph-name="approvedcircle" unicode="approvedcircle"
d="M501 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM793 417l-59 59l-316 -316l-150 149l-59 -59l209 -208z" />
<glyph glyph-name="approved" unicode="approved"
d="M817 516l58 -59l-498 -498l-232 232l59 59l173 -174z" />
d="M145 191l59 59l173 -174l440 440l58 -59l-498 -498z" />
<glyph glyph-name="alertcircle" unicode="alertcircle"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM542 125h-84v-83h84v83zM542 459h-84v-251h84v251z" />
<glyph glyph-name="alert" unicode="alert"
@ -130,26 +130,28 @@ d="M542 0h-84v84h84v-84zM542 500v-334h-84v334h84z" />
d="M500 667q87 0 163 -32.5t132.5 -89t89 -132.5t32.5 -163t-32.5 -163t-89 -132.5t-132.5 -89t-163 -32.5t-163 32.5t-132.5 89t-89 132.5t-32.5 163t32.5 163t89 132.5t132.5 89t163 32.5zM559 250l150 150l-59 59l-150 -150l-150 150l-59 -59l150 -150l-150 -150l59 -59
l150 150l150 -150l59 59z" />
<glyph glyph-name="repproved" unicode="repproved"
d="M559 251l233 -233l-59 -59l-233 233l-233 -233l-59 59l233 233l-233 233l59 59l233 -233l233 233l59 -59z" />
<glyph glyph-name="arrowleft" unicode="arrowleft"
d="M584 42l-209 209l209 209v-418z" />
<glyph glyph-name="arrowright" unicode="arrowright"
d="M441 251l-233 233l59 59l233 -233l233 233l59 -59l-233 -233l233 -233l-59 -59l-233 233l-233 -233l-59 59z" />
<glyph glyph-name="uni2190" unicode="arrowleft"
d="M584 460v-418l-209 209z" />
<glyph glyph-name="uni2192" unicode="arrowright"
d="M417 460l208 -209l-208 -209v418z" />
<glyph glyph-name="arrowup" unicode="arrowup"
<glyph glyph-name="uni2191" unicode="arrowup"
d="M291 167l209 208l208 -208h-417z" />
<glyph glyph-name="arrowdown" unicode="arrowdown"
d="M709 334l-209 -209l-209 209h418z" />
<glyph glyph-name="uni2193" unicode="arrowdown"
d="M291 334h418l-209 -209z" />
<glyph glyph-name="next" unicode="next"
d="M379 -5l255 256l-255 256l78 78l334 -334l-334 -334z" />
<glyph glyph-name="previous" unicode="previous"
d="M625 507l-255 -256l255 -256l-78 -78l-334 334l334 334z" />
<glyph glyph-name="pointer" unicode="pointer"
d="M125 334h458v209l292 -292l-292 -292v209h-458v166z" />
<glyph glyph-name="video" unicode="video"
d="M875 479v-458l-167 166v-145q0 -17 -12 -29.5t-29 -12.5h-500q-17 0 -29.5 12.5t-12.5 29.5v416q0 17 12.5 29.5t29.5 12.5h500q17 0 29 -12.5t12 -29.5v-145z" />
<glyph glyph-name="uni202C" unicode="pdf"
d="M542 375h229l-229 229v-229zM250 667h333l251 -250v-501q0 -35 -24.5 -59t-59.5 -24h-500q-35 0 -59.5 24.5t-24.5 58.5v668q0 35 24.5 59t59.5 24zM455 232q26 -58 64 -90l17 -13q-27 -5 -63 -14.5t-76 -24.5v0l-5 -2l21 44q29 55 42 100zM726 73q5 5 7.5 12t3.5 15
q1 13 -5 23q-17 29 -95 29l-54 -3l-36 24q-20 17 -37 44.5t-30 62.5l2 6q5 21 9.5 43t5.5 42t-2 37.5t-14 27.5q-9 10 -25 10h-10q-12 0 -21 -10t-12 -22q-6 -21 -7 -38t0.5 -32.5t5.5 -31t10 -34.5v-1q-8 -28 -18.5 -59t-26.5 -63l-40 -75l-37 -21q-38 -23 -56.5 -47
t-22.5 -41q-1 -12 3 -22l1 -3l20 -13l18 -4q26 0 55.5 31t68.5 97l7 3q32 11 73.5 18t95.5 13q32 -16 66.5 -23.5t58.5 -7.5q25 0 38 13zM709 102l3 -4q0 -5 -4 -6h-1h-8q-14 0 -35 5t-44 16q3 4 9 4q44 0 60 -5.5t20 -9.5zM326 42q-20 -38 -38 -58.5t-32 -25.5
q2 12 14.5 31t35.5 40zM452 330q-8 28 -8 50t5 35l3 5l6 -2q10 -14 4 -46l-1 -6l-7 -35z" />
d="M542 375h229l-229 229v-229zM250 667h333l251 -250v-501q0 -35 -24.5 -59t-59.5 -24h-500q-35 0 -59.5 24.5t-24.5 58.5v668q0 35 24.5 59t59.5 24zM455 232q26 -58 64 -90l17 -13q-27 -5 -63 -14.5t-76 -24.5v0l-5 -2l21 44q29 55 42 100zM726 73q9 9 11 27q1 13 -5 23
q-17 29 -95 29l-54 -3l-36 24q-41 35 -67 107l2 6q5 21 9.5 43t5.5 42t-2 37.5t-14 27.5q-9 10 -25 10h-10q-12 0 -21 -10t-12 -22q-6 -21 -7 -38t0.5 -32.5t5.5 -31t10 -34.5v-1q-8 -28 -18.5 -59t-26.5 -63l-40 -75l-37 -21q-38 -23 -56.5 -47t-22.5 -41q-1 -12 3 -22
l1 -3l20 -13l18 -4q26 0 55.5 31t68.5 97l7 3q32 11 73.5 18t95.5 13q32 -16 66.5 -23.5t58.5 -7.5q25 0 38 13zM709 102l3 -4q0 -5 -4 -6h-1h-8q-14 0 -35 5t-44 16q3 4 9 4q45 0 60.5 -5.5t19.5 -9.5zM326 42q-40 -74 -70 -84q2 12 14.5 31t35.5 40zM452 330q-8 28 -8 50
t5 35l3 5l6 -2q10 -14 4 -46l-1 -6l-7 -35z" />
<glyph glyph-name="text" unicode="text"
d="M625 42h-500v83h500v-83zM625 375h-500v83h500v-83zM125 292h750v-84h-750v84zM125 -42h750v-83h-750v83zM875 625v-83h-750v83h750z" />
<glyph glyph-name="audio" unicode="audio"
@ -160,9 +162,8 @@ d="M875 -42q0 -35 -24.5 -59t-58.5 -24h-584q-34 0 -58.5 24.5t-24.5 58.5v584q0 35
<glyph glyph-name="gallery" unicode="gallery"
d="M917 83q0 -35 -24.5 -59t-58.5 -24h-501q-35 0 -59 24t-24 59v501q0 34 24 58.5t59 24.5h501q34 0 58.5 -24.5t24.5 -58.5v-501zM333 83h501l-167 209l-124 -155l-85 113zM166 500v-584h584v-83h-584q-34 0 -58.5 24.5t-24.5 58.5v584h83z" />
<glyph glyph-name="user" unicode="user"
d="M500 185q30 0 67.5 -5t77 -14.5t77 -24.5t67 -34.5t47.5 -44.5t18 -54v-133h-708v133q0 30 18 54.5t47.5 44t67 34.5t77 24.5t77 14.5t67.5 5zM500 583q37 0 69 -14t56 -38t38 -56t14 -69t-14 -69t-38 -56t-56 -38t-69 -14t-69 14t-56 38t-38 56t-14 69t14 69t38 56
t56 38t69 14zM500 101q-50 0 -98.5 -10.5t-86.5 -25.5t-61.5 -30.5t-23.5 -26.5v-49h540v49q0 11 -24 26.5t-62 30.5t-86.5 25.5t-97.5 10.5zM500 499q-19 0 -36 -7.5t-29.5 -20t-20 -29.5t-7.5 -36v0q0 -19 7.5 -36t20 -29.5t29.5 -20t36 -7.5v0q19 0 36 7.5t29.5 20
t20 29.5t7.5 36v0q0 19 -7.5 36t-20 29.5t-29.5 20t-36 7.5v0z" />
d="M500 185q44 0 105 -11t116.5 -33t94 -55.5t38.5 -77.5v-133h-708v133q0 44 38.5 77.5t94 55.5t116.5 33t105 11zM500 583q37 0 69 -14t56 -38t38 -56t14 -69t-14 -69t-38 -56t-56 -38t-69 -14t-69 14t-56 38t-38 56t-14 69t14 69t38 56t56 38t69 14zM500 101
q-50 0 -98.5 -10.5t-86.5 -25.5t-61.5 -30.5t-23.5 -26.5v-49h540v49q0 11 -24 26.5t-62 30.5t-86.5 25.5t-97.5 10.5zM500 499q-38 0 -65.5 -27.5t-27.5 -65.5v0q0 -38 27.5 -65.5t65.5 -27.5v0q38 0 65.5 27.5t27.5 65.5v0q0 38 -27.5 65.5t-65.5 27.5v0z" />
<glyph glyph-name="notifications" unicode="notifications"
d="M500 -167q-35 0 -59 24.5t-24 58.5h166q0 -34 -24 -58.5t-59 -24.5zM833 0v-42h-666v42l83 83v208q0 48 12.5 91t36.5 78t59 59.5t80 34.5v28q0 26 18 44.5t44 18.5t44 -18.5t18 -44.5v-28q45 -10 80 -34.5t59 -59.5t36.5 -78t12.5 -91v-208zM667 291q0 39 -11.5 73
t-33 59.5t-52.5 40t-70 14.5t-70 -14.5t-52 -40t-32.5 -59.5t-11.5 -73v-250h333v250z" />
@ -171,10 +172,10 @@ d="M792 209h-250v-250h-84v250h-250v84h250v250h84v-250h250v-84z" />
<glyph glyph-name="menu" unicode="menu"
d="M125 83h750v-83h-750v83zM125 292h750v-84h-750v84zM875 500v-83h-750v83h750z" />
<glyph glyph-name="heartfill" unicode="heartfill"
d="M500 -140l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73t73 48.5t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5
t-146.5 -135.5z" />
d="M83 396q0 48 18 90t49 73t73 48.5t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112
t-25.5 114z" />
<glyph glyph-name="uni22C6" unicode="star"
d="M243 -125l67 293l-227 197l300 26l117 276l117 -276l300 -26l-228 -197l69 -293l-258 155z" />
d="M83 365l300 26l117 276l117 -276l300 -26l-228 -197l69 -293l-258 155l-257 -155l67 293z" />
<glyph glyph-name="viewtable" unicode="viewtable"
d="M249 501h-125v-125h125v125zM916 376h-583v125h583v-125zM249 167h-125v126h125v-126zM916 167h-583v126h583v-126zM249 -41h-125v125h125v-125zM916 -41h-583v125h583v-125z" />
<glyph glyph-name="viewcards" unicode="viewcards"
@ -192,27 +193,25 @@ d="M667 416h-167v84h167v-84zM792 166h-292v84h292v-84zM917 -84h-417v83h417v-83zM2
<glyph glyph-name="viewrecords" unicode="viewrecords"
d="M333 543h-208v-584h208v584zM625 -41h-208v584h208v-584zM917 -41h-208v584h208v-584z" />
<glyph glyph-name="close" unicode="close"
d="M559 251l233 -233l-59 -59l-233 233l-233 -233l-59 59l233 233l-233 233l59 59l233 -233l233 233l59 -59z" />
d="M441 251l-233 233l59 59l233 -233l233 233l59 -59l-233 -233l233 -233l-59 -59l-233 233l-233 -233l-59 59z" />
<glyph glyph-name="heartoutline" unicode="heartoutline"
d="M504 -23q75 68 135.5 124.5t103.5 107t66.5 96.5t23.5 91q0 31 -11 58t-30.5 46.5t-46 30.5t-57.5 11q-24 0 -47.5 -7.5t-43 -20.5t-35 -31.5t-23.5 -39.5h-78q-8 21 -23.5 39.5t-35 31.5t-42.5 20.5t-47 7.5q-31 0 -58 -11t-46.5 -30.5t-30.5 -46.5t-11 -58
q0 -45 23.5 -91t66.5 -96.5t103.5 -107t134.5 -124.5l5 -4zM688 625q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73t73 48.5
t90 17.5q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5z" />
d="M313 625q54 0 103.5 -23.5t83.5 -63.5q34 40 83.5 63.5t104.5 23.5q48 0 90 -17.5t72.5 -48.5t48.5 -73t18 -90q0 -59 -25.5 -114t-72.5 -112t-112.5 -119.5t-146.5 -135.5l-60 -55l-60 55q-81 73 -146.5 135.5t-112.5 119.5t-72.5 112t-25.5 114q0 48 18 90t49 73
t73 48.5t90 17.5zM461 443q-17 43 -58.5 71t-89.5 28q-31 0 -58 -11t-46.5 -30.5t-30.5 -46.5t-11 -58q0 -45 23.5 -91t66.5 -96.5t103.5 -107t134.5 -124.5l5 -4l4 4q75 68 135.5 124.5t103.5 107t66.5 96.5t23.5 91q0 63 -41 104.5t-104 41.5q-49 0 -90.5 -28t-58.5 -71
h-78z" />
<glyph glyph-name="wordpress" unicode="wordpress"
d="M500 669q-86 0 -162 -33t-132.5 -89t-89.5 -131.5t-33 -161.5t32.5 -162t89 -133t131.5 -90t160 -34q87 -1 163 31.5t133 89t90.5 132.5t34.5 161t-31 161t-88 133.5t-132.5 91.5t-165.5 34zM898 251q0 -82 -32 -154.5t-86.5 -126.5t-127.5 -85.5t-156 -30.5
q-81 1 -153 32.5t-126 86.5t-84.5 128t-29.5 157q1 81 33 153t86.5 125.5t127.5 84t156 29.5q82 -1 153.5 -33.5t124.5 -86.5t83.5 -126t30.5 -153zM682 45q-1 -2 -1.5 -4t-2.5 -5q-32 97 -64.5 192t-64.5 191q11 1 20.5 2t18.5 2q16 2 16 15q-2 15 -18 14l-42 -2t-42 -1
q-21 -1 -42 0t-41 2q-5 0 -10.5 0.5t-10.5 0.5q-13 0 -15 -14q0 -13 14 -15q8 -1 15.5 -1.5t15.5 -1.5q6 0 8 -6q13 -35 26 -71l26 -72q2 -4 0 -8q-19 -57 -37.5 -113t-37.5 -113q0 -1 -0.5 -1.5t-1.5 -2.5q-33 97 -65.5 193t-64.5 193q10 1 19.5 2t18.5 2q18 2 16 16
q0 15 -17 13q-22 -1 -43.5 -2t-43.5 -2h-30q44 63 101 102t131 53q88 16 164 -6t145 -81q-43 0 -60 -38q-12 -28 1 -56q10 -23 26 -47q15 -25 24 -51.5t8 -55.5q0 -20 -5 -40t-11 -40q-11 -35 -21.5 -71t-21.5 -72zM505 218h2q28 -76 55.5 -151.5t55.5 -152.5
q-109 -36 -219 -5q27 78 53.5 154.5t52.5 154.5zM166 123q-50 136 7 275q44 -118 86 -233.5t85 -232.5q-21 5 -47.5 24t-51.5 46t-46 58.5t-33 62.5zM847 167q-36 -145 -166 -222q5 14 9.5 28t9.5 28q22 64 43.5 127.5t44.5 127.5q8 23 16 46.5t10 48.5q2 17 2 34t1 34
q63 -122 30 -252z" />
q0 15 -17 13q-22 -1 -43.5 -2t-43.5 -2h-30q44 63 101 102t131 53q171 31 309 -87q-43 0 -60 -38q-12 -28 1 -56q10 -23 26 -47q15 -25 24 -51.5t8 -55.5q0 -20 -5 -40t-11 -40q-11 -35 -21.5 -71t-21.5 -72zM505 218h2q28 -76 55.5 -151.5t55.5 -152.5q-109 -36 -219 -5
q27 78 53.5 154.5t52.5 154.5zM166 123q-50 136 7 275q44 -118 86 -233.5t85 -232.5q-21 5 -47.5 24t-51.5 46t-46 58.5t-33 62.5zM847 167q-36 -145 -166 -222q5 14 9.5 28t9.5 28q22 64 43.5 127.5t44.5 127.5q8 23 16 46.5t10 48.5q2 17 2 34t1 34q63 -122 30 -252z" />
<glyph glyph-name="drag" unicode="drag"
d="M292 543q0 35 -24 59t-59 24q-18 0 -33 -6.5t-26.5 -17.5t-18 -26.5t-6.5 -32.5q0 -35 24.5 -59.5t59.5 -24.5q17 0 32.5 6.5t26.5 18t17.5 26.5t6.5 33zM500 626q35 0 59 -24t24 -59q0 -18 -6.5 -33t-17.5 -26.5t-26.5 -18t-32.5 -6.5q-35 0 -59.5 24.5t-24.5 59.5
q0 17 6.5 32.5t18 26.5t26.5 17.5t33 6.5zM792 626q35 0 59 -24t24 -59q0 -18 -6.5 -33t-17.5 -26.5t-26.5 -18t-32.5 -6.5q-35 0 -59.5 24.5t-24.5 59.5q0 17 6.5 32.5t18 26.5t26.5 17.5t33 6.5zM209 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18
t-18 26.5t-6.5 32t6.5 32.5t18 27t26.5 18t33 6.5zM500 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18t-18 26.5t-6.5 32t6.5 32.5t18 27t26.5 18t33 6.5zM792 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24q-18 0 -33 6.5t-26.5 18t-18 26.5t-6.5 32
t6.5 32.5t18 27t26.5 18t33 6.5zM209 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5zM500 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24
q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5zM792 42q17 0 32.5 -6.5t26.5 -18t17.5 -26.5t6.5 -33q0 -35 -24 -59t-59 -24q-18 0 -33 6.5t-26.5 17.5t-18 26.5t-6.5 32.5q0 35 24.5 59.5t59.5 24.5z" />
d="M292 543q0 35 -24 59t-59 24t-59.5 -24t-24.5 -59t24.5 -59.5t59.5 -24.5t59 24.5t24 59.5zM500 626q35 0 59 -24t24 -59t-24 -59.5t-59 -24.5t-59.5 24.5t-24.5 59.5t24.5 59t59.5 24zM792 626q35 0 59 -24t24 -59t-24 -59.5t-59 -24.5t-59.5 24.5t-24.5 59.5t24.5 59
t59.5 24zM209 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM500 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM792 335q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59
t24.5 59.5t59.5 24.5zM209 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM500 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24t-24.5 59t24.5 59.5t59.5 24.5zM792 42q35 0 59 -24.5t24 -59.5t-24 -59t-59 -24t-59.5 24
t-24.5 59t24.5 59.5t59.5 24.5z" />
<glyph glyph-name="addcollection" unicode="addcollection"
d="M620 -22q-8 27 -10 60h-467v418h-60v-418q0 -25 17.5 -42.5t42.5 -17.5h477zM740 516q25 0 42.5 -17.5t17.5 -42.5v-227q-31 0 -60 -10t-52.5 -27.5t-41 -41.5t-26.5 -53h-358q-25 0 -42 17.5t-17 42.5v359q0 25 17 42t42 17h180l59 -59h239zM917 39q0 24 -9 45.5
t-25 37.5t-37.5 25t-45.5 9t-45.5 -9t-37 -25t-25 -37.5t-9.5 -45.5t9.5 -45.5t25 -37t37 -25t45.5 -9.5t45.5 9.5t37.5 25t25 37t9 45.5zM870 22h-52v-53h-35v53h-53v35h53v52h35v-52h52v-35z" />
d="M620 -22q-8 27 -10 60h-467v418h-60v-418q0 -25 17.5 -42.5t42.5 -17.5h477zM740 516q25 0 42.5 -17.5t17.5 -42.5v-227q-63 0 -112.5 -37t-67.5 -95h-358q-25 0 -42 17.5t-17 42.5v359q0 25 17 42t42 17h180l59 -59h239zM917 39q0 49 -34 83t-83 34q-24 0 -45.5 -9
t-37 -25t-25 -37.5t-9.5 -45.5t9.5 -45.5t25 -37t37 -25t45.5 -9.5t45.5 9.5t37.5 25t25 37t9 45.5zM870 22h-52v-53h-35v53h-53v35h53v52h35v-52h52v-35z" />
<glyph glyph-name="stop" unicode="stop"
d="M500 667q86 0 162 -33t132.5 -89.5t89.5 -132.5t33 -162t-33 -162t-89.5 -132.5t-132.5 -89.5t-162 -33t-162 33t-132.5 89.5t-89.5 132.5t-33 162t33 162t89.5 132.5t132.5 89.5t162 33zM500 -83q69 0 129.5 26t106 71.5t71.5 106t26 129.5t-26 129.5t-71.5 106
t-106 71.5t-129.5 26t-129.5 -26t-106 -71.5t-71.5 -106t-26 -129.5t26 -129.5t71.5 -106t106 -71.5t129.5 -26zM667 417h-334v-334h334v334z" />
@ -241,56 +240,54 @@ t-106 71.5t-130 26.5t-130 -26.5t-106 -71.5t-71.5 -106t-26.5 -130t26.5 -130t71.5
/>
<glyph glyph-name="uni000D" unicode="&#xd;" horiz-adv-x="250"
/>
<glyph glyph-name="space" unicode=" " horiz-adv-x="250"
<glyph glyph-name="uni0020" unicode=" " horiz-adv-x="250"
/>
<glyph glyph-name="r" unicode="r" horiz-adv-x="308"
<glyph glyph-name="uni0072" unicode="r" horiz-adv-x="308"
/>
<glyph glyph-name="e" unicode="e" horiz-adv-x="512"
<glyph glyph-name="uni0065" unicode="e" horiz-adv-x="512"
/>
<glyph glyph-name="p" unicode="p" horiz-adv-x="549"
<glyph glyph-name="uni0070" unicode="p" horiz-adv-x="549"
/>
<glyph glyph-name="o" unicode="o" horiz-adv-x="531"
<glyph glyph-name="uni006F" unicode="o" horiz-adv-x="531"
/>
<glyph glyph-name="s" unicode="s" horiz-adv-x="465"
<glyph glyph-name="uni0073" unicode="s" horiz-adv-x="465"
/>
<glyph glyph-name="i" unicode="i" horiz-adv-x="204"
<glyph glyph-name="uni0069" unicode="i" horiz-adv-x="204"
/>
<glyph glyph-name="t" unicode="t" horiz-adv-x="301"
<glyph glyph-name="uni0074" unicode="t" horiz-adv-x="301"
/>
<glyph glyph-name="y" unicode="y" horiz-adv-x="486"
<glyph glyph-name="uni0079" unicode="y" horiz-adv-x="486"
/>
<glyph glyph-name="c" unicode="c" horiz-adv-x="501"
<glyph glyph-name="uni0063" unicode="c" horiz-adv-x="501"
/>
<glyph glyph-name="l" unicode="l" horiz-adv-x="204"
<glyph glyph-name="uni006C" unicode="l" horiz-adv-x="204"
/>
<glyph glyph-name="n" unicode="n" horiz-adv-x="527"
<glyph glyph-name="uni006E" unicode="n" horiz-adv-x="527"
/>
<glyph glyph-name="question" unicode="?"
<glyph glyph-name="uni003F" unicode="?"
d="M460 81h81v-81h-81v81zM514 540q54 -2 92 -28t55 -64t11.5 -83t-37.5 -86q-17 -20 -39.5 -35t-36.5 -32t-16 -37t-2 -40h-81q0 34 2 62t16 48t36.5 33.5t39.5 27.5q25 23 34 48.5t4 48t-25 38t-53 18.5q-34 0 -57.5 -23.5t-23.5 -57.5h-81q0 34 12.5 63.5t34.5 51.5
t51.5 34.5t63.5 12.5z" />
<glyph glyph-name="video"
d="M875 479v-458l-167 166v-145q0 -17 -12 -29.5t-29 -12.5h-500q-17 0 -29.5 12.5t-12.5 29.5v416q0 17 12.5 29.5t29.5 12.5h500q17 0 29 -12.5t12 -29.5v-145z" />
<glyph glyph-name="m" unicode="m" horiz-adv-x="803"
<glyph glyph-name="uni006D" unicode="m" horiz-adv-x="803"
/>
<glyph glyph-name="a" unicode="a" horiz-adv-x="502"
<glyph glyph-name="uni0061" unicode="a" horiz-adv-x="502"
/>
<glyph glyph-name="d" unicode="d" horiz-adv-x="554"
<glyph glyph-name="uni0064" unicode="d" horiz-adv-x="554"
/>
<glyph glyph-name="x" unicode="x" horiz-adv-x="469"
<glyph glyph-name="uni0078" unicode="x" horiz-adv-x="469"
/>
<glyph glyph-name="v" unicode="v" horiz-adv-x="483"
<glyph glyph-name="uni0076" unicode="v" horiz-adv-x="483"
/>
<glyph glyph-name="f" unicode="f" horiz-adv-x="304"
<glyph glyph-name="uni0066" unicode="f" horiz-adv-x="304"
/>
<glyph glyph-name="w" unicode="w" horiz-adv-x="715"
<glyph glyph-name="uni0077" unicode="w" horiz-adv-x="715"
/>
<glyph glyph-name="u" unicode="u" horiz-adv-x="527"
<glyph glyph-name="uni0075" unicode="u" horiz-adv-x="527"
/>
<glyph glyph-name="g" unicode="g" horiz-adv-x="549"
<glyph glyph-name="uni0067" unicode="g" horiz-adv-x="549"
/>
<glyph glyph-name="h" unicode="h" horiz-adv-x="539"
<glyph glyph-name="uni0068" unicode="h" horiz-adv-x="539"
/>
<glyph glyph-name="b" unicode="b" horiz-adv-x="554"
<glyph glyph-name="uni0062" unicode="b" horiz-adv-x="554"
/>
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -90,6 +90,9 @@
.tainacan-icon-audio:before {
content: "audio";
}
.tainacan-icon-video:before {
content: "video";
}
.tainacan-icon-close:before {
content: "close";
}

View File

@ -1,3 +1,497 @@
.wp-block-tainacan-terms-list {
margin: 2rem 0px; }
.wp-block-tainacan-terms-list .components-spinner {
position: absolute;
right: 0; }
.wp-block-tainacan-terms-list .block-control {
display: flex;
flex-direction: row;
justify-content: center;
padding: 12px; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid {
padding: 0;
display: -ms-grid;
display: grid;
grid-template-columns: repeat(auto-fill, 220px);
grid-gap: 0px;
justify-content: space-evenly;
list-style-type: none; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item {
position: relative;
display: block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
width: 185px; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item a,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item a {
color: #454647;
font-weight: bold; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item img,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item img {
height: auto;
width: 185px;
min-width: 185px;
padding: 0px;
margin-bottom: 10px; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item a.term-without-name span,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item a.term-without-name span {
display: none; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item:hover a,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item:hover a {
color: #454647;
text-decoration: none; }
.wp-block-tainacan-terms-list ul.terms-list-edit li.term-list-item {
display: flex;
align-items: flex-start; }
.wp-block-tainacan-terms-list ul.terms-list-edit li.term-list-item button {
position: absolute !important;
background-color: rgba(255, 255, 255, 0.75);
color: #454647;
padding: 2px;
margin-left: 5px;
min-width: 14px;
visibility: hidden;
position: relative;
opacity: 0;
right: -14px;
top: 0px;
justify-content: center;
z-index: 999; }
.wp-block-tainacan-terms-list ul.terms-list-edit li.term-list-item:hover button {
visibility: visible;
background-color: white !important;
opacity: 1;
right: -8px;
top: -8px;
border: 1px solid #cbcbcb;
border-radius: 12px;
transition: opacity linear 0.15s, right linear 0.15s; }
.wp-block-tainacan-terms-list ul.terms-list-edit li.term-list-item:hover button:hover {
background-color: white !important;
border: 1px solid #cbcbcb !important; }
@media only screen and (max-width: 498px) {
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid {
grid-template-columns: repeat(auto-fill, 100%); }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item {
width: 100%; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-grid li.term-list-item img,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-grid li.term-list-item img {
width: 100%; } }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list {
padding: 0;
display: block;
list-style-type: none; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item {
position: relative;
display: inline-block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
min-height: 54px;
min-width: 22%;
width: 22%; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item a,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item a {
color: #454647;
display: flex;
align-items: center;
height: 54px; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item img,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item img {
height: auto;
width: 54px;
min-width: 54px;
padding: 0px;
margin-right: 20px; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item a.term-without-image img,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item a.term-without-image img {
display: none; }
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item:hover a,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item:hover a {
color: #454647;
text-decoration: none; }
@media only screen and (max-width: 1600px) {
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item {
min-width: 30%;
width: 30%; } }
@media only screen and (max-width: 1024px) {
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item {
min-width: 45%;
width: 45%; } }
@media only screen and (max-width: 768px) {
.wp-block-tainacan-terms-list ul.terms-list.terms-layout-list li.term-list-item,
.wp-block-tainacan-terms-list ul.terms-list-edit.terms-layout-list li.term-list-item {
min-width: 100%;
width: 100%; } }
.wp-block-tainacan-items-list {
margin: 2rem 0px; }
.wp-block-tainacan-items-list .components-spinner {
position: absolute;
right: 0; }
.wp-block-tainacan-items-list .block-control {
display: flex;
flex-direction: row;
justify-content: center;
padding: 12px; }
.wp-block-tainacan-items-list ul.items-list.items-list-without-margin,
.wp-block-tainacan-items-list ul.items-list-edit.items-list-without-margin {
grid-template-columns: repeat(auto-fill, 185px);
justify-content: center !important;
grid-template-rows: auto !important; }
.wp-block-tainacan-items-list ul.items-list.items-list-without-margin li,
.wp-block-tainacan-items-list ul.items-list-edit.items-list-without-margin li {
margin-top: 0 !important;
margin-right: 0 !important;
margin-left: 0 !important;
height: 185px !important; }
.wp-block-tainacan-items-list ul.items-list.items-list-without-margin li img,
.wp-block-tainacan-items-list ul.items-list-edit.items-list-without-margin li img {
height: 185px !important;
margin-bottom: 0px !important; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid {
padding: 0;
display: -ms-grid;
display: grid;
grid-template-columns: repeat(auto-fill, 220px);
grid-gap: 0px;
justify-content: space-evenly;
list-style-type: none; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item {
position: relative;
display: block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
width: 185px; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item a,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item a {
color: #454647;
font-weight: bold;
line-height: 2rem; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item img,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item img {
height: auto;
width: 185px;
min-width: 185px;
padding: 0px; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item a.item-without-title span,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item a.item-without-title span {
display: none; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item:hover a,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item:hover a {
color: #454647;
text-decoration: none; }
.wp-block-tainacan-items-list ul.items-list-edit li.item-list-item {
display: flex;
align-items: flex-start; }
.wp-block-tainacan-items-list ul.items-list-edit li.item-list-item button {
position: absolute !important;
background-color: rgba(255, 255, 255, 0.75);
color: #454647;
padding: 2px;
margin-left: 5px;
min-width: 14px;
visibility: hidden;
position: relative;
opacity: 0;
right: -14px;
top: 0px;
justify-content: center;
z-index: 999; }
.wp-block-tainacan-items-list ul.items-list-edit li.item-list-item:hover button {
visibility: visible;
background-color: white !important;
opacity: 1;
right: -8px;
top: -8px;
border: 1px solid #cbcbcb;
border-radius: 12px;
transition: opacity linear 0.15s, right linear 0.15s; }
.wp-block-tainacan-items-list ul.items-list-edit li.item-list-item:hover button:hover {
background-color: white !important;
border: 1px solid #cbcbcb !important; }
@media only screen and (max-width: 498px) {
.wp-block-tainacan-items-list ul.items-list.items-layout-grid,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid {
grid-template-columns: repeat(auto-fill, 100%); }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item {
width: 100%; }
.wp-block-tainacan-items-list ul.items-list.items-layout-grid li.item-list-item img,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-grid li.item-list-item img {
width: 100%; } }
.wp-block-tainacan-items-list ul.items-list.items-layout-list,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list {
padding: 0;
display: block;
list-style-type: none; }
.wp-block-tainacan-items-list ul.items-list.items-layout-list li.item-list-item,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list li.item-list-item {
position: relative;
display: inline-block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
min-height: 54px;
min-width: 22%;
width: 22%; }
.wp-block-tainacan-items-list ul.items-list.items-layout-list li.item-list-item a,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list li.item-list-item a {
color: #454647;
display: flex;
align-items: center;
height: 54px; }
.wp-block-tainacan-items-list ul.items-list.items-layout-list li.item-list-item img,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list li.item-list-item img {
height: auto;
width: 54px;
min-width: 54px;
padding: 0px;
margin-right: 20px; }
.wp-block-tainacan-items-list ul.items-list.items-layout-list li.item-list-item a.item-without-image img,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list li.item-list-item a.item-without-image img {
display: none; }
.wp-block-tainacan-items-list ul.items-list.items-layout-list li.item-list-item:hover a,
.wp-block-tainacan-items-list ul.items-list-edit.items-layout-list li.item-list-item:hover a {
color: #454647;
text-decoration: none; }
.wp-block-tainacan-collections-list {
margin: 2rem 0px; }
.wp-block-tainacan-collections-list .components-spinner {
position: absolute;
right: 0; }
.wp-block-tainacan-collections-list .block-control {
display: flex;
flex-direction: row;
justify-content: center;
padding: 12px; }
.wp-block-tainacan-collections-list ul.collections-list.collections-list-without-margin,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-list-without-margin {
grid-template-columns: repeat(auto-fill, 185px);
justify-content: center !important;
grid-template-rows: auto !important; }
.wp-block-tainacan-collections-list ul.collections-list.collections-list-without-margin li,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-list-without-margin li {
margin-top: 0 !important;
margin-right: 0 !important;
margin-left: 0 !important;
height: 185px !important; }
.wp-block-tainacan-collections-list ul.collections-list.collections-list-without-margin li img,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-list-without-margin li img {
height: 185px !important;
margin-bottom: 0px !important; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid {
padding: 0;
display: -ms-grid;
display: grid;
grid-template-columns: repeat(auto-fill, 220px);
grid-gap: 0px;
justify-content: space-evenly;
list-style-type: none; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item {
position: relative;
display: block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
width: 185px; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item a,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item a {
color: #454647;
font-weight: bold;
line-height: 2rem; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item img,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item img {
height: auto;
width: 185px;
min-width: 185px;
padding: 0px; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item a.collection-without-name span,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item a.collection-without-name span {
display: none; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item:hover a,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item:hover a {
color: #454647;
text-decoration: none; }
.wp-block-tainacan-collections-list ul.collections-list-edit li.collection-list-item {
display: flex;
align-items: flex-start; }
.wp-block-tainacan-collections-list ul.collections-list-edit li.collection-list-item button {
position: absolute !important;
background-color: rgba(255, 255, 255, 0.75);
color: #454647;
padding: 2px;
margin-left: 5px;
min-width: 14px;
visibility: hidden;
position: relative;
opacity: 0;
right: -14px;
top: 0px;
justify-content: center;
z-index: 999; }
.wp-block-tainacan-collections-list ul.collections-list-edit li.collection-list-item:hover button {
visibility: visible;
background-color: white !important;
opacity: 1;
right: -8px;
top: -8px;
border: 1px solid #cbcbcb;
border-radius: 12px;
transition: opacity linear 0.15s, right linear 0.15s; }
.wp-block-tainacan-collections-list ul.collections-list-edit li.collection-list-item:hover button:hover {
background-color: white !important;
border: 1px solid #cbcbcb !important; }
@media only screen and (max-width: 498px) {
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid {
grid-template-columns: repeat(auto-fill, 100%); }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item {
width: 100%; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-grid li.collection-list-item img,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-grid li.collection-list-item img {
width: 100%; } }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list {
padding: 0;
display: block;
list-style-type: none; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item {
position: relative;
display: inline-block;
margin: 12px 12px 24px 12px;
margin-bottom: 12px;
min-height: 54px;
min-width: 22%;
width: 22%; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item a,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item a {
color: #454647;
display: flex;
align-items: center;
height: 54px; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item img,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item img {
height: auto;
width: 54px;
min-width: 54px;
padding: 0px;
margin-right: 20px; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item a.collection-without-image img,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item a.collection-without-image img {
display: none; }
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item:hover a,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item:hover a {
color: #454647;
text-decoration: none; }
@media only screen and (max-width: 1600px) {
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item {
min-width: 30%;
width: 30%; } }
@media only screen and (max-width: 1024px) {
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item {
min-width: 45%;
width: 45%; } }
@media only screen and (max-width: 768px) {
.wp-block-tainacan-collections-list ul.collections-list.collections-layout-list li.collection-list-item,
.wp-block-tainacan-collections-list ul.collections-list-edit.collections-layout-list li.collection-list-item {
min-width: 100%;
width: 100%; } }
.wp-block-tainacan-modal {
width: 50%; }
@media only screen and (max-width: 1024px) {
.wp-block-tainacan-modal {
width: 75%; } }
@media only screen and (max-width: 768px) {
.wp-block-tainacan-modal {
width: 100%; } }
.wp-block-tainacan-modal .components-spinner {
position: absolute;
right: 5%;
bottom: 84px; }
.wp-block-tainacan-modal .modal-search-area {
display: flex;
justify-content: center;
margin-bottom: 24px; }
.wp-block-tainacan-modal .modal-search-area .components-base-control {
width: 60%; }
@media only screen and (max-width: 1024px) {
.wp-block-tainacan-modal .modal-search-area .components-base-control {
width: 95%; } }
.wp-block-tainacan-modal .modal-search-area .components-base-control label {
text-align: center; }
.wp-block-tainacan-modal .modal-checkbox-list,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field {
padding: 0;
display: -ms-grid;
display: grid;
grid-template-columns: repeat(auto-fill, 250px);
grid-gap: 0px;
justify-content: space-evenly;
list-style-type: none;
margin: 12px;
max-height: 50vh;
overflow-y: auto; }
.wp-block-tainacan-modal .modal-checkbox-list .components-base-control,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .components-base-control {
overflow: hidden; }
.wp-block-tainacan-modal .modal-checkbox-list .modal-checkbox-list-item,
.wp-block-tainacan-modal .modal-checkbox-list .components-radio-control__option,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .modal-checkbox-list-item,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .components-radio-control__option {
display: flex;
justify-content: flex-start; }
.wp-block-tainacan-modal .modal-checkbox-list .modal-checkbox-list-item img,
.wp-block-tainacan-modal .modal-checkbox-list .components-radio-control__option img,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .modal-checkbox-list-item img,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .components-radio-control__option img {
width: 24px;
height: 24px;
margin-right: 10px; }
.wp-block-tainacan-modal .modal-checkbox-list .modal-checkbox-list-item label,
.wp-block-tainacan-modal .modal-checkbox-list .components-radio-control__option label,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .modal-checkbox-list-item label,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .components-radio-control__option label {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
display: inline-block;
max-width: 85%; }
@media only screen and (max-width: 768px) {
.wp-block-tainacan-modal .modal-checkbox-list .modal-checkbox-list-item label,
.wp-block-tainacan-modal .modal-checkbox-list .components-radio-control__option label,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .modal-checkbox-list-item label,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field .components-radio-control__option label {
max-width: 80%; } }
.wp-block-tainacan-modal .modal-loadmore-section {
display: flex;
align-items: baseline;
justify-content: center; }
.wp-block-tainacan-modal .modal-loadmore-section p {
color: #555758;
margin-right: 12px;
margin-top: 2px; }
.wp-block-tainacan-modal .modal-footer-area {
border-top: 1px solid #e2e4e7;
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 16px 16px 0 16px;
margin: 0 -16px; }
/*# sourceMappingURL=tainacan-gutenberg-blocks-style.css.map */

File diff suppressed because one or more lines are too long

View File

@ -465,6 +465,16 @@ class Capabilities {
$role->add_cap($collection_items_caps->$cap);
$this->check_dependencies($role, 'tainacan-items', $cap);
}
// Tainacan relative role
$role = get_role('tainacan-' . $role_name);
if (\is_object($role)) {
foreach ($caps as $cap) {
$role->add_cap($collection_items_caps->$cap);
$this->check_dependencies($role, 'tainacan-items', $cap);
}
}
}
// Refresh roles capabilities for current user to have instant effect

View File

@ -34,7 +34,7 @@ class Media {
$http = new \WP_Http();
$response = $http->request( $url );
$response = $http->request( $url, ['sslverify' => false] );
if( !is_array($response) || !isset($response['response']) || $response['response']['code'] != 200 ) {
return false;

View File

@ -67,12 +67,17 @@ class Taxonomy extends Entity {
'new_item_name' => __( 'New Genre term', 'tainacan' ),
'menu_name' => $this->get_name(),
);
$enabled_post_types = $this->get_enabled_post_types();
$enabled_post_types = sizeof($enabled_post_types) ? $enabled_post_types : null;
$show_ui = is_array($enabled_post_types) ? true : false;
$args = array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => tnc_enable_dev_wp_interface(),
'show_admin_column' => tnc_enable_dev_wp_interface(),
'show_ui' => $show_ui,
'show_in_rest' => $show_ui,
'show_admin_column' => false,
'rewrite' => [
'slug' => $this->get_slug()
],
@ -82,9 +87,11 @@ class Taxonomy extends Entity {
unregister_taxonomy($this->get_db_identifier());
}
register_taxonomy(
$this->get_db_identifier(),
null,
$enabled_post_types,
$args
);
@ -129,6 +136,15 @@ class Taxonomy extends Entity {
return $this->get_mapped_property('slug');
}
/**
* Return the enabled post types
*
* @return array
*/
function get_enabled_post_types() {
return $this->get_mapped_property('enabled_post_types');
}
// special Getters
/**
@ -178,6 +194,15 @@ class Taxonomy extends Entity {
function set_allow_insert($value) {
$this->set_mapped_property('allow_insert', $value);
}
/**
* Sets enabled post types
*
* @param array $value array of post types slugs
*/
function set_enabled_post_types($value) {
$this->set_mapped_property('enabled_post_types', $value);
}
/**
* Validate Taxonomy

View File

@ -11,6 +11,32 @@ class Autocomplete extends Filter_Type {
function __construct(){
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-autocomplete');
$this->set_preview_template('
<div>
<div class="taginput control is-expanded has-selected">
<div class="taginput-container is-focusable">
<div class="autocomplete control">
<div class="control has-icon-right is-loading is-clearfix">
<input type="text" class="input" value="'. __('Item') . ' 9" >
</div>
<div class="dropdown-menu" style="">
<div class="dropdown-content">
<a class="dropdown-item is-hovered">
<span>'. __('Collection') . ' 2 <strong>'._('item') . ' 9</strong>9</span>
</a>
<a class="dropdown-item">
<span>'. __('Collection') . ' 3 <strong>'._('item') . ' 9</strong>9</span>
</a>
<a class="dropdown-item">
<span>'. __('Collection') . ' 3 <strong>'._('item') . ' 9</strong>8</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
');
}
/**

View File

@ -269,7 +269,7 @@
.no-options-placeholder {
margin-left: 0.5rem;
font-size: 0.75rem;
color: #898d8f;
color: #555758;
}
.b-checkbox .control-label {

View File

@ -11,6 +11,50 @@ class Checkbox extends Filter_Type {
function __construct(){
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-checkbox');
$this->set_preview_template('
<div>
<div>
<p class="has-text-gray">'. __('Selected values') . ': </p>
<div class="field selected-tags is-grouped-multiline is-grouped">
<div>
<div class="tags has-addons">
<span class="tag"><span>'. __('Value') . ' 2</span></span>
<a class="tag is-delete"></a>
</div>
</div>
<div>
<div class="tags has-addons">
<span class="tag"><span>'. __('Value') . ' 3</span></span>
<a class="tag is-delete"></a>
</div>
</div>
</div>
<div>
<label class="b-checkbox checkbox" border="" style="padding-left: 8px;">
<input type="checkbox" value="option1">
<span class="check"></span>
<span class="control-label">'. __('Value') . ' 1</span>
</label>
<br>
</div>
<div>
<label class="b-checkbox checkbox" border="" style="padding-left: 8px;">
<input type="checkbox" checked value="option2">
<span class="check"></span>
<span class="control-label">'. __('Value') . ' 2</span>
</label>
</div>
<div>
<label class="b-checkbox checkbox" border="" style="padding-left: 8px;">
<input type="checkbox" checked value="option3">
<span class="check"></span>
<span class="control-label">'. __('Value') . ' 3</span>
</label>
</div>
</div>
<a class="add-new-term">'. __('View all') . '</a>
</div>
');
}
/**

View File

@ -12,6 +12,17 @@ class Custom_Interval extends Filter_Type {
function __construct(){
$this->set_supported_types(['float','date']);
$this->set_component('tainacan-filter-custom-interval');
$this->set_preview_template('
<div>
<div class="control is-small is-clearfix">
<input type="number" step="any" value="6" class="input is-small">
</div>
<p class="is-size-7 has-text-centered is-marginless">until</p>
<div class="control is-small is-clearfix">
<input type="number" step="any" value="10" class="input is-small">
</div>
</div>
');
}
/**

View File

@ -10,6 +10,7 @@ abstract class Filter_Type {
private $supported_types = [];
private $options = [];
private $component;
private $preview_template = '';
public function __construct(){
add_action('register_filter_types', array(&$this, 'register_filter_type'));
@ -47,6 +48,23 @@ abstract class Filter_Type {
return $this->component;
}
/**
* specifies the preview template for the filter type
*
* @param string $preview_template for the filter type
*/
public function set_preview_template($preview_template){
$this->preview_template = $preview_template;
}
/**
* @return string
*/
public function get_preview_template() {
return $this->preview_template;
}
/**
* @return array
*/
@ -56,6 +74,7 @@ abstract class Filter_Type {
$attributes['className'] = get_class($this);
$attributes['component'] = $this->get_component();
$attributes['supported_types'] = $this->get_supported_types();
$attributes['preview_template'] = $this->get_preview_template();
return $attributes;
}

View File

@ -11,6 +11,17 @@ class Selectbox extends Filter_Type {
function __construct(){
$this->set_supported_types(['string', 'long_string']);
$this->set_component('tainacan-filter-selectbox');
$this->set_preview_template('
<div>
<div class="control is-expanded">
<span class="select is-fullwidth">
<select>
<option value="someValue">' . __('Select here...') . '</option>
</select>
</span>
</div>
</div>
');
}
/**

View File

@ -11,6 +11,47 @@ class Taginput extends Filter_Type {
function __construct(){
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-taginput');
$this->set_preview_template('
<div>
<p class="has-text-gray">'. __('Selected values') . ': </p>
<div class="field selected-tags is-grouped-multiline is-grouped">
<div>
<div class="tags has-addons">
<span class="tag"><span>'. __('Collection') . ' 2 '._('item') . ' 13</span></span>
<a class="tag is-delete"></a>
</div>
</div>
<div>
<div class="tags has-addons">
<span class="tag"><span>'. __('Collection') . ' 3 '._('item') . ' 2</span></span>
<a class="tag is-delete"></a>
</div>
</div>
</div>
<div class="taginput control is-expanded has-selected">
<div class="taginput-container is-focusable">
<div class="autocomplete control">
<div class="control has-icon-right is-loading is-clearfix">
<input type="text" class="input" value="'. __('Item') . ' 9" >
</div>
<div class="dropdown-menu" style="">
<div class="dropdown-content">
<a class="dropdown-item is-hovered">
<span>'. __('Collection') . ' 2 <strong>'._('item') . ' 9</strong>9</span>
</a>
<a class="dropdown-item">
<span>'. __('Collection') . ' 3 <strong>'._('item') . ' 9</strong>9</span>
</a>
<a class="dropdown-item">
<span>'. __('Collection') . ' 3 <strong>'._('item') . ' 9</strong>8</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
');
}
/**

View File

@ -315,7 +315,7 @@
.no-options-placeholder {
margin-left: 0.5rem;
font-size: 0.75rem;
color: #898d8f;
color: #555758;
}
.b-checkbox .control-label {

Some files were not shown because too many files have changed in this diff Show More