Merge branch 'develop' into feature/compount-metadata-type-refactor

This commit is contained in:
vnmedeiros 2020-03-02 17:04:06 -03:00
commit f35a3d4b76
51 changed files with 3611 additions and 253 deletions

View File

@ -33,5 +33,7 @@ sass -E 'UTF-8' --cache-location .tmp/sass-cache-11 src/views/gutenberg-blocks/t
sass -E 'UTF-8' --cache-location .tmp/sass-cache-12 src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css sass -E 'UTF-8' --cache-location .tmp/sass-cache-12 src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-13 src/views/gutenberg-blocks/tainacan-facets/faceted-search/faceted-search.scss:src/assets/css/tainacan-gutenberg-block-faceted-search.css
echo "Compilação do Sass Concluído!" echo "Compilação do Sass Concluído!"
exit 0 exit 0

View File

@ -0,0 +1,452 @@
[data-align='full'] .block-control {
width: calc(100% + 14px); }
.block-control {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 5px;
position: relative;
top: -14px;
left: -14px;
width: calc(100% + 28px);
background: #f2f2f2; }
.block-control p {
font-size: 0.875em !important;
margin: 12px 1.5em 16px 0;
fill: #555758; }
.block-control p svg {
top: 4px;
margin-right: 0.75em;
position: relative;
fill: #555758; }
.components-placeholder {
margin-bottom: 0;
background: #f6f6f6; }
.components-placeholder .components-placeholder__label {
margin-bottom: 0; }
.components-placeholder .components-placeholder__fieldset p {
font-size: 1em !important;
margin: 12px 0;
color: #454647;
fill: #555758; }
.components-placeholder .components-placeholder__fieldset p svg {
margin-right: 1em;
top: 4px;
position: relative;
fill: #555758; }
.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.dynamic-modal {
width: 90%;
height: 90%;
width: 80vw;
height: 80vh; }
.wp-block-tainacan-modal.dynamic-modal iframe {
width: calc(100% + 32px);
height: calc(100% - 128px);
margin-left: -16px; }
.wp-block-tainacan-modal.dynamic-modal .modal-footer-area {
height: 68px;
width: calc(100% + 32px);
margin-left: -16px !important;
padding: 1.2em 1.2em !important;
border-top: 1px solid #cbcbcb; }
.wp-block-tainacan-modal .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: #555758; }
.wp-block-tainacan-modal .spinner-container .components-spineer {
margin: 8px; }
.wp-block-tainacan-modal .components-modal__header .components-icon-button {
padding-right: 0; }
.wp-block-tainacan-modal hr {
margin: 5px 0.75em; }
.wp-block-tainacan-modal .modal-search-area {
display: flex;
justify-content: center;
margin-bottom: 14px; }
.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:nth-child(2) {
flex-shrink: 2; }
.wp-block-tainacan-modal .modal-search-area .components-base-control .components-base-control__field {
flex-wrap: wrap; }
.wp-block-tainacan-modal .modal-search-area .components-base-control label.components-base-control__label {
font-weight: 500;
color: #454647;
font-size: 1em;
text-align: center; }
.wp-block-tainacan-modal .modal-search-area .components-base-control input.components-text-control__input {
padding: 5px 8px;
height: 28px; }
.wp-block-tainacan-modal .modal-radio-area-label {
font-weight: 500;
margin-left: 1.75em; }
.wp-block-tainacan-modal .modal-checkbox-list,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field {
padding: 0;
flex-wrap: wrap;
display: flex;
display: -ms-grid;
display: grid;
-ms-grid-columns: 250px 250px;
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;
overflow-x: hidden; }
.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 svg.dashicon.components-checkbox-control__checked,
.wp-block-tainacan-modal .modal-radio-list .components-base-control__field svg.dashicon.components-checkbox-control__checked {
fill: black; }
.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; }
.wp-block-tainacan-modal .modal-footer-area p {
padding: 0 12px;
color: #454647; }
.wp-block-tainacan-faceted-search {
margin: 2em auto; }
.wp-block-tainacan-faceted-search .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: #555758; }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-faceted-search .skeleton {
border-radius: 2px;
background: #f2f2f2;
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-faceted-search .preview-warning {
width: 100%;
font-size: 0.875em;
font-style: italic;
color: #898d8f;
text-align: center;
margin: 4px auto; }
.wp-block-tainacan-faceted-search .items-list-placeholder {
font-size: 1.125em;
min-height: 400px;
width: 100%;
display: flex;
flex-wrap: nowrap;
flex-direction: column;
border-radius: 4px;
border: 1px solid rgba(200, 200, 200, 0.3);
overflow: hidden; }
.wp-block-tainacan-faceted-search .items-list-placeholder .search-control,
.wp-block-tainacan-faceted-search .items-list-placeholder .filters,
.wp-block-tainacan-faceted-search .items-list-placeholder .items,
.wp-block-tainacan-faceted-search .items-list-placeholder .pagination {
background-color: var(--tainacan-background-color, white);
border: 1px solid rgba(200, 200, 200, 0.3);
padding: 12px;
margin: 0px;
border-radius: 1px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .search-control {
flex: 0 0 15%;
display: flex;
justify-content: space-between;
align-items: center; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control {
position: relative;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
flex: 1 0 auto; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters {
flex: 0 1 var(--tainacan-filter-menu-width-theme, 20%);
display: flex;
flex-direction: column;
padding: 40px 20px 60px 15px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter {
display: flex;
flex-direction: column;
width: 80%;
margin: 4% 12%; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-text {
margin: 4px 0;
width: 35%;
background-color: var(--tainacan-label-color, rgba(200, 200, 200, 0.2)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-searchbar {
width: 100%; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-checkbox-list > div {
width: 100%;
display: flex;
align-items: center; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-checkbox-list > div:nth-child(odd) .fake-text {
width: 60%; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-checkbox-list .fake-checkbox {
display: block;
width: 0.4em;
height: 0.4em;
min-width: 0.4em;
min-height: 0.4em;
max-width: 0.4em;
max-height: 0.4em;
border: 2px solid var(--tainacan-input-border-color, rgba(200, 200, 200, 0.3));
border-radius: 2px;
margin-right: 4px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-checkbox-list .fake-text {
background-color: var(--tainacan-input-color, rgba(200, 200, 200, 0.3));
width: 54%; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filter .fake-checkbox-list .fake-link {
width: 25%;
margin: 3px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .filters .fake-filters-heading {
position: relative;
top: -1.3em;
left: -0.3em;
background-color: var(--tainacan-heading-color, rgba(200, 200, 200, 0.3));
height: 0.2em;
width: 28%;
border-radius: 2px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .aside-filters {
display: flex;
flex-wrap: nowrap;
flex-direction: column;
flex: 1 1 auto; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .aside-filters .items {
flex: 1 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-content: flex-start; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .aside-filters .pagination {
flex: 0 1 5%;
display: flex;
justify-content: space-between;
align-items: center; }
.wp-block-tainacan-faceted-search .items-list-placeholder .below-search-control .aside-filters .pagination > .fake-text {
background-color: var(--tainacan-info-color, rgba(200, 200, 200, 0.2)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-text {
background-color: var(--tainacan-input-color, rgba(200, 200, 200, 0.3));
height: 0.2em;
width: 24%;
min-width: 1.25em;
border-radius: 2px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-link {
background-color: var(--tainacan-secondary, rgba(200, 200, 200, 0.3));
height: 0.2em;
width: 10%;
border-radius: 2px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-icon {
background-color: var(--tainacan-info-color, rgba(200, 200, 200, 0.3));
height: 0.3em;
width: 0.3em;
min-height: 0.3em;
min-width: 0.3em;
max-height: 0.3em;
max-width: 0.3em;
border-radius: 5px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-tooltip {
background-color: var(--tainacan-primary, rgba(200, 200, 200, 0.1));
position: absolute;
height: 0.75em;
width: 4em;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
top: -0.75em;
left: 1em; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-tooltip .fake-link {
width: 100%;
margin: 0 4px 0 8px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-tooltip:before {
content: "";
display: block;
position: absolute;
left: 12px;
width: 0;
height: 0;
border-style: solid; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-tooltip:before {
border-color: var(--tainacan-primary) transparent transparent transparent;
border-right-width: 7px;
border-top-width: 6px;
border-left-width: 7px;
bottom: -8px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-searchbar {
background-color: var(--tainacan-input-background-color, rgba(200, 200, 200, 0.3));
height: 0.8em;
width: 18%;
border: 2px solid var(--tainacan-input-border-color, rgba(200, 200, 200, 0.3));
border-radius: 3px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-searchbar .fake-advanced-searchbar {
display: block;
background-color: var(--tainacan-secondary, rgba(200, 200, 200, 0.3));
height: 0.2em;
border-radius: 3px;
width: 70%;
position: relative;
bottom: -0.85em; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-hide-button {
display: flex;
justify-content: center;
align-items: center;
background-color: var(--tainacan-primary, rgba(200, 200, 200, 0.1));
height: 0.9em;
width: 0.9em;
font-size: 0.75em;
border-radius: 3px;
position: absolute;
left: 0px;
top: 42px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-hide-button .fake-icon {
background-color: var(--tainacan-secondary, rgba(200, 200, 200, 0.3)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-button {
background-color: var(--tainacan-background-color, white);
height: 0.8em;
width: 10%;
max-width: 3.25em;
min-width: 1em;
margin-left: 6px;
border-radius: 3px;
display: flex;
align-items: center; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-button .fake-text {
background-color: var(--tainacan-input-color, rgba(200, 200, 200, 0.3));
width: 95%;
margin: 0 2px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-button .fake-icon {
flex: 1 0 auto;
margin: 0 2px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-buttons-group {
flex: 0 0 15%;
display: flex;
justify-content: space-evenly; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item {
background-color: var(--tainacan-item-background-color, white);
flex: 1 0 180px;
margin: 12px;
height: 78px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item.fake-item-hovered, .wp-block-tainacan-faceted-search .items-list-placeholder .fake-item:hover {
background-color: var(--tainacan-item-hover-background-color, rgba(200, 200, 200, 0.2)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item.fake-item-hovered .fake-item-header, .wp-block-tainacan-faceted-search .items-list-placeholder .fake-item:hover .fake-item-header {
background-color: var(--tainacan-item-heading-hover-background-color, rgba(200, 200, 200, 0.3)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item .fake-item-header {
height: 20px;
width: 100%;
position: relative;
top: 0;
display: flex;
align-items: center;
padding: 6px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item .fake-item-header .fake-text {
background-color: var(--tainacan-heading-color, rgba(200, 200, 200, 0.35)); }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item .fake-item-thumb {
background-size: cover;
background-color: var(--tainacan-input-border-color, rgba(200, 200, 200, 0.1));
height: 58px;
width: 58px;
float: left; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item .fake-item-description {
background-color: var(--tainacan-info-color, rgba(200, 200, 200, 0.15));
height: 0.18em;
width: 60%;
border-radius: 2px;
margin: 8px 6px 2px 6px;
position: relative;
left: 62px; }
.wp-block-tainacan-faceted-search .items-list-placeholder .fake-item .fake-item-description:nth-child(odd) {
width: 50%; }
.wp-block-tainacan-faceted-search .theme-items-list {
max-width: 100% !important; }
/*# sourceMappingURL=tainacan-gutenberg-block-faceted-search.css.map */

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -55,8 +55,7 @@ class REST_Filter_Types_Controller extends REST_Controller {
* @return mixed|\WP_Error|\WP_REST_Response * @return mixed|\WP_Error|\WP_REST_Response
*/ */
public function prepare_item_for_response( $item, $request ) { public function prepare_item_for_response( $item, $request ) {
$name = "\Tainacan\Filter_Types\\$item"; $filter_type = new $item();
$filter_type = new $name();
$filter_arr = $filter_type->_toArray(); $filter_arr = $filter_type->_toArray();
@ -71,7 +70,7 @@ class REST_Filter_Types_Controller extends REST_Controller {
public function get_items( $request ) { public function get_items( $request ) {
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance(); $Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
$filter_types = $Tainacan_Filters->fetch_filter_types('NAME'); $filter_types = $Tainacan_Filters->fetch_filter_types( );
$prepared = []; $prepared = [];
foreach ($filter_types as $filter_type){ foreach ($filter_types as $filter_type){

View File

@ -71,7 +71,7 @@ class REST_Metadata_Types_Controller extends REST_Controller {
*/ */
public function prepare_item_for_response( $item, $request ) { public function prepare_item_for_response( $item, $request ) {
$name = "\Tainacan\Metadata_Types\\$item"; $name = "\Tainacan\Metadata_Types\\$item";
$metadata_type = new $name(); $metadata_type = new $item();
$metadatum_arr = $metadata_type->_toArray(); $metadatum_arr = $metadata_type->_toArray();
@ -86,7 +86,7 @@ class REST_Metadata_Types_Controller extends REST_Controller {
public function get_items( $request ) { public function get_items( $request ) {
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
$metadata_types = $Tainacan_Metadata->fetch_metadata_types('NAME'); $metadata_types = $Tainacan_Metadata->fetch_metadata_types( );
$prepared = []; $prepared = [];
foreach ($metadata_types as $metadata_type){ foreach ($metadata_types as $metadata_type){

View File

@ -131,32 +131,9 @@ $Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance(); $Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); $Metadata_Type_Helper = \Tainacan\Metadata_Types\Metadata_Type_Helper::get_instance();
//register metadatum types $Filter_Type_Helper = \Tainacan\Filter_Types\Filter_Type_Helper::get_instance();
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Text');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Textarea');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Date');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Numeric');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Selectbox');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Relationship');
$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Taxonomy');
//$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Compound');
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
//register filter type
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Selectbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Autocomplete');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Taginput');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Checkbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date_Interval');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_Interval');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_List_Interval');
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance(); $Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
@ -179,6 +156,12 @@ require_once(__DIR__ . '/../views/class-tainacan-admin-hooks.php');
require_once(__DIR__ . '/../views/admin-hooks-functions.php'); require_once(__DIR__ . '/../views/admin-hooks-functions.php');
$Tainacan_Admin_Hooks = \Tainacan\Admin_Hooks::get_instance(); $Tainacan_Admin_Hooks = \Tainacan\Admin_Hooks::get_instance();
require_once(__DIR__ . '/../views/class-tainacan-component-hooks.php');
$Tainacan_Component_Hooks = \Tainacan\Component_Hooks::get_instance();
require_once(__DIR__ . '/../views/class-tainacan-plugin-hooks.php');
$Tainacan_Plugin_Hooks = \Tainacan\Plugin_Hooks::get_instance();
require_once(__DIR__ . '/theme-helper/class-tainacan-theme-helper.php'); require_once(__DIR__ . '/theme-helper/class-tainacan-theme-helper.php');
require_once(__DIR__ . '/theme-helper/template-tags.php'); require_once(__DIR__ . '/theme-helper/template-tags.php');
$Tainacan_Theme_Helper = \Tainacan\Theme_Helper::get_instance(); $Tainacan_Theme_Helper = \Tainacan\Theme_Helper::get_instance();

View File

@ -186,19 +186,20 @@ function tainacan_the_collection_description() {
* @param array $args { * @param array $args {
* Optional. Array of arguments. * Optional. Array of arguments.
* *
* @type bool $hide-filters Completely hide filter sidebar or modal * @type bool $hide-filters Completely hide filter sidebar or modal
* @type bool $hide-hide-filters-button Hides the button resonsible for collpasing filters sidebar on desktop * @type bool $hide-hide-filters-button Hides the button resonsible for collpasing filters sidebar on desktop
* @type bool $hide-search Hides the complete search bar, including advanced search link * @type bool $hide-search Hides the complete search bar, including advanced search link
* @type bool $hide-advanced-search Hides only the advanced search link * @type bool $hide-advanced-search Hides only the advanced search link
* @type bool $hide-sort-by-button Hides the button where user can select the metadata to sort by items (keeps the sort direction) * @type bool $hide-sort-by-button Hides the button where user can select the metadata to sort by items (keeps the sort direction)
* @type bool $hide-items-per-page-button Hides the button for selecting amount of items loaded per page * @type bool $hide-items-per-page-button Hides the button for selecting amount of items loaded per page
* @type bool $hide-go-to-page-button Hides the button for skiping to a specific page * @type bool $hide-go-to-page-button Hides the button for skiping to a specific page
* @type bool $start-with-filters-hidden Loads the filters list hidden from start * @type bool $show-filters-button-inside-search-control Display the "hide filters" button inside of the search control instead of floating
* @type bool $filters-as-modal Display the filters as a modal instead of a collapsable region on desktop * @type bool $start-with-filters-hidden Loads the filters list hidden from start
* @type bool $show-inline-view-mode-options Display view modes as inline icon buttons instead of the dropdown * @type bool $filters-as-modal Display the filters as a modal instead of a collapsable region on desktop
* @type bool $show-fullscreen-with-view-modes Lists fullscreen viewmodes alongside with other view modes istead of separatelly * @type bool $show-inline-view-mode-options Display view modes as inline icon buttons instead of the dropdown
* @type string $default-view-mode The default view mode * @type bool $show-fullscreen-with-view-modes Lists fullscreen viewmodes alongside with other view modes istead of separatelly
* @type string[] $enabled-view-modes The list os enable view modes to display * @type string $default-view-mode The default view mode
* @type string[] $enabled-view-modes The list os enable view modes to display
* @return string The HTML div to be used for rendering the items list vue component * @return string The HTML div to be used for rendering the items list vue component
*/ */
function tainacan_the_faceted_search($args = array()) { function tainacan_the_faceted_search($args = array()) {

View File

@ -120,10 +120,12 @@
v-model="coverPageTitle" v-model="coverPageTitle"
@select="onSelectCoverPage($event)" @select="onSelectCoverPage($event)"
:loading="isFetchingPages" :loading="isFetchingPages"
@input="fecthCoverPages($event)" @input="fecthCoverPages"
@focus="clearErrors('cover_page_id')" @focus="clearErrors('cover_page_id')"
v-if="coverPage == undefined || coverPage.title == undefined" v-if="coverPage == undefined || coverPage.title == undefined"
:disabled="form.enable_cover_page != 'yes'"> :disabled="form.enable_cover_page != 'yes'"
check-infinite-scroll
@infinite-scroll="fetchMoreCoverPages">
<template slot-scope="props"> <template slot-scope="props">
{{ props.option.title.rendered }} {{ props.option.title.rendered }}
</template> </template>
@ -533,6 +535,8 @@ export default {
cover: {}, cover: {},
isFetchingPages: false, isFetchingPages: false,
coverPages: [], coverPages: [],
coverPagesSearchQuery: '',
coverPagesSearchPage: 0,
coverPage: '', coverPage: '',
coverPageTitle: '', coverPageTitle: '',
coverPageEditPath: '', coverPageEditPath: '',
@ -819,18 +823,47 @@ export default {
let index = this.form.enabled_view_modes.findIndex(aViewMode => aViewMode == viewMode); let index = this.form.enabled_view_modes.findIndex(aViewMode => aViewMode == viewMode);
return index > -1; return index > -1;
}, },
fecthCoverPages(search) { fecthCoverPages: _.debounce(function(search) {
// String update
if (search != this.coverPagesSearchQuery) {
this.coverPagesSearchQuery = search;
this.coverPages = [];
this.coverPagesSearchPage = 1;
}
// String cleared
if (!search.length) {
this.coverPagesSearchQuery = search;
this.coverPages = [];
this.coverPagesSearchPage = 1;
}
// No need to load more
if (this.coverPagesSearchPage > 1 && this.coverPages.length > this.totalPages*12)
return;
this.isFetchingPages = true; this.isFetchingPages = true;
this.fetchPages(search) this.fetchPages({ search: this.coverPagesSearchQuery, page: this.coverPagesSearchPage })
.then((pages) => { .then((res) => {
this.coverPages = pages; if (res.pages) {
for (let page of res.pages)
this.coverPages.push(page);
}
if (res.totalPages)
this.totalPages = res.totalPages;
this.coverPagesSearchPage++;
this.isFetchingPages = false; this.isFetchingPages = false;
}) })
.catch((error) => { .catch((error) => {
this.$console.error(error); this.$console.error(error);
this.isFetchingPages = false; this.isFetchingPages = false;
}); });
}, }, 500),
fetchMoreCoverPages: _.debounce(function () {
this.fecthCoverPages(this.coverPagesSearchQuery)
}, 250),
onSelectCoverPage(selectedPage) { onSelectCoverPage(selectedPage) {
this.form.cover_page_id = selectedPage.id; this.form.cover_page_id = selectedPage.id;
this.coverPage = selectedPage; this.coverPage = selectedPage;

View File

@ -152,9 +152,11 @@
v-model="parentTermName" v-model="parentTermName"
@select="onSelectParentTerm($event)" @select="onSelectParentTerm($event)"
:loading="isFetchingParentTerms" :loading="isFetchingParentTerms"
@input="fecthParentTerms($event)" @input="fetchParentTerms"
@focus="clearErrors('parent');" @focus="clearErrors('parent');"
:disabled="!hasParent"> :disabled="!hasParent"
check-infinite-scroll
@infinite-scroll="fetchMoreParentTerms">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div <div
@ -239,6 +241,8 @@
initialParentId: undefined, initialParentId: undefined,
entityName: 'term', entityName: 'term',
isLoading: false, isLoading: false,
parentTermSearchQuery: '',
parentTermSearchOffset: 0
} }
}, },
mounted() { mounted() {
@ -385,22 +389,50 @@
this.formErrors[attributes] = undefined; this.formErrors[attributes] = undefined;
} }
}, },
fecthParentTerms(search) { fetchParentTerms: _.debounce(function(search) {
// String update
if (search != this.parentTermSearchQuery) {
this.parentTermSearchQuery = search;
this.parentTerms = [];
this.parentTermSearchOffset = 0;
}
// String cleared
if (!search.length) {
this.parentTermSearchQuery = search;
this.parentTerms = [];
this.parentTermSearchOffset = 0;
}
// No need to load more
if (this.parentTermSearchOffset > 0 && this.parentTerms.length >= this.totalTerms)
return
this.isFetchingParentTerms = true; this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({ this.fetchPossibleParentTerms({
taxonomyId: this.taxonomyId, taxonomyId: this.taxonomyId,
termId: this.editForm.id, termId: this.editForm.id,
search: search }) search: this.parentTermSearchQuery,
.then((parentTerms) => { offset: this.parentTermSearchOffset })
this.parentTerms = parentTerms; .then((res) => {
for (let term of res.parentTerms)
this.parentTerms.push(term);
this.parentTermSearchOffset += 12;
this.totalTerms = res.totalTerms;
this.isFetchingParentTerms = false; this.isFetchingParentTerms = false;
}) })
.catch((error) => { .catch((error) => {
this.$console.error(error); this.$console.error(error);
this.isFetchingParentTerms = false; this.isFetchingParentTerms = false;
}); });
}, }, 500),
fetchMoreParentTerms: _.debounce(function () {
this.fetchParentTerms(this.parentTermSearchQuery)
}, 250),
onToggleSwitch() { onToggleSwitch() {
if (this.editForm.parent == 0) { if (this.editForm.parent == 0) {

View File

@ -12,7 +12,9 @@
field="label" field="label"
@select="onSelect" @select="onSelect"
clearable clearable
:placeholder="(metadatumType === 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_search_items') : $i18n.get('info_type_to_search_metadata')"> :placeholder="(metadatumType === 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_search_items') : $i18n.get('info_type_to_search_metadata')"
check-infinite-scroll
@infinite-scroll="searchMore">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div <div
@ -52,7 +54,11 @@
return { return {
selected:'', selected:'',
options: [], options: [],
label: '' label: '',
searchQuery: '',
searchOffset: 0,
searchNumber: 12,
totalFacets: 0
} }
}, },
watch: { watch: {
@ -84,24 +90,48 @@
}, },
search: _.debounce( function(query) { search: _.debounce( function(query) {
if (query != '') { // String update
let promise = null; if (query != this.searchQuery) {
this.searchQuery = query;
this.options = []; this.options = [];
this.searchOffset = 0;
}
// String cleared
if (!query.length) {
this.searchQuery = query;
this.options = [];
this.searchOffset = 0;
}
// No need to load more
if (this.searchOffset > 0 && this.options.length >= this.totalFacets)
return;
if (this.searchQuery != '') {
let promise = null;
// Cancels previous Request // Cancels previous Request
if (this.getOptionsValuesCancel != undefined) if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.'); this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' ) if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( query, this.isRepositoryLevel ); promise = this.getValuesRelationship( this.searchQuery, this.isRepositoryLevel, [], this.searchOffset, this.searchNumber );
else else
promise = this.getValuesPlainText( this.metadatumId, query, this.isRepositoryLevel ); promise = this.getValuesPlainText( this.metadatumId, this.searchQuery, this.isRepositoryLevel, [], this.searchOffset, this.searchNumber );
promise.request.catch( error => { promise.request
if (isCancel(error)) .then( res => {
this.$console.log('Request canceled: ' + error.message); this.totalFacets = res.headers['x-wp-total'];
else this.searchOffset += this.searchNumber;
this.$console.error( error ); })
}); .catch( error => {
if (isCancel(error))
this.$console.log('Request canceled: ' + error.message);
else
this.$console.error( error );
});
// Search Request Token for cancelling // Search Request Token for cancelling
this.getOptionsValuesCancel = promise.source; this.getOptionsValuesCancel = promise.source;
@ -117,6 +147,10 @@
}); });
} }
}, 500), }, 500),
searchMore: _.debounce(function () {
this.shouldAddOptions = true;
this.search(this.searchQuery);
}, 250),
updateSelectedValues(){ updateSelectedValues(){
if (!this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery )) if (!this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ))

View File

@ -0,0 +1,102 @@
<?php
namespace Tainacan\Filter_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class FilterTypeHelper
*/
class Filter_Type_Helper {
private static $instance = null;
/**
* Stores external filter type available to be used in Tainacan
*/
private $registered_filter_type;
private $Tainacan_Filters;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->registered_filter_type = [];
$this->Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
$this->init();
}
private function init() {
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Taginput');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Checkbox');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Selectbox');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Autocomplete');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date_Interval');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_Interval');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox');
$this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_List_Interval');
// the priority should see less than on function
// `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php
add_action( 'admin_enqueue_scripts', array( &$this, 'register_filter_type_compoment' ), 80 );
do_action('tainacan-register-filter-type', $this);
}
public function register_filter_type_compoment() {
foreach($this->registered_filter_type as $handle => $component) {
wp_enqueue_script($handle, $component['script_path']);
}
}
/**
* Register a new Filter Type
*
* @param string $handle name of the component. Should be unique.
* @param string $class a class name of the filter type
* @param array|string $args
*/
public function register_filter_type($handle, $class_name, $script_path, $args = []) {
global $TAINACAN_EXTRA_SCRIPTS;
$this->Tainacan_Filters->register_filter_type($class_name);
if ( ! in_array( $handle, $this->registered_filter_type ) ) {
$TAINACAN_EXTRA_SCRIPTS[] = $handle;
$this->registered_filter_type[$handle] = [
'handle' => $handle,
'class_name' => $class_name,
'script_path' => $script_path,
'args' => $args
];
}
}
/**
* Get a list of all registered filter type
*
* @return array The list of registered filter type
*/
public function get_registered_filter_type() {
return $this->registered_filter_type;
}
/**
* Get one specific filter type by its slug
*
* @param string $handle Name of the component
*
* @return array|false The filter type definition or false if it is not found
*/
public function get_filter_type($handle) {
return isset($this->registered_filter_type[$handle]) ? $this->registered_filter_type[$handle] : false;
}
}

View File

@ -36,6 +36,12 @@ abstract class Filter_Type {
*/ */
private $component; private $component;
/**
* The content of the js script associated to the vue component for extra filters
* @var string
*/
private $script = '';
/** /**
* The name of the web component used by the Form * The name of the web component used by the Form
* @var bool | string * @var bool | string
@ -125,6 +131,7 @@ abstract class Filter_Type {
$attributes['className'] = get_class($this); $attributes['className'] = get_class($this);
$attributes['name'] = $this->get_name(); $attributes['name'] = $this->get_name();
$attributes['component'] = $this->get_component(); $attributes['component'] = $this->get_component();
$attributes['script'] = $this->get_script();
$attributes['options'] = $this->get_options(); $attributes['options'] = $this->get_options();
$attributes['supported_types'] = $this->get_supported_types(); $attributes['supported_types'] = $this->get_supported_types();
$attributes['preview_template'] = $this->get_preview_template(); $attributes['preview_template'] = $this->get_preview_template();
@ -176,6 +183,13 @@ abstract class Filter_Type {
*/ */
public function set_component( $component ) { public function set_component( $component ) {
$this->component = $component; $this->component = $component;
}
/**
* @param string $script
*/
public function set_script( $script ) {
$this->script= $script;
} }
/** /**
@ -222,6 +236,13 @@ abstract class Filter_Type {
return $this->form_component; return $this->form_component;
} }
/**
* @return string
*/
public function get_script() {
return $this->script;
}
/** /**
* @param $form_component The web component that will render the filter options form * @param $form_component The web component that will render the filter options form
*/ */

View File

@ -70,12 +70,10 @@
</template> </template>
<script> <script>
import { wpAjax } from '../../../js/mixins';
import { filterTypeMixin } from '../../../js/filter-types-mixin'; import { filterTypeMixin } from '../../../js/filter-types-mixin';
export default { export default {
mixins: [ mixins: [
wpAjax,
filterTypeMixin filterTypeMixin
], ],
data(){ data(){

View File

@ -15,7 +15,9 @@
@typing="search" @typing="search"
:aria-close-label="$i18n.get('remove_value')" :aria-close-label="$i18n.get('remove_value')"
:aria-labelledby="'filter-label-id-' + filter.id" :aria-labelledby="'filter-label-id-' + filter.id"
:placeholder="(metadatumType == 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_add_items') : $i18n.get('info_type_to_add_metadata')"> :placeholder="(metadatumType == 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_add_items') : $i18n.get('info_type_to_add_metadata')"
check-infinite-scroll
@infinite-scroll="searchMore">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div <div
@ -55,7 +57,11 @@
results:'', results:'',
selected:[], selected:[],
options: [], options: [],
relatedCollectionId: '' relatedCollectionId: '',
searchQuery: '',
searchOffset: 0,
searchNumber: 12,
totalFacets: 0
} }
}, },
watch: { watch: {
@ -80,11 +86,29 @@
}, },
methods: { methods: {
search: _.debounce( function(query) { search: _.debounce( function(query) {
// String update
if (query != this.searchQuery) {
this.searchQuery = query;
this.options = [];
this.searchOffset = 0;
}
// String cleared
if (!query.length) {
this.searchQuery = query;
this.options = [];
this.searchOffset = 0;
}
// No need to load more
if (this.searchOffset > 0 && this.options.length >= this.totalFacets)
return;
let promise = null; let promise = null;
this.options = [];
let valuesToIgnore = []; let valuesToIgnore = [];
for(let val of this.selected) for (let val of this.selected)
valuesToIgnore.push( val.value ); valuesToIgnore.push( val.value );
// Cancels previous Request // Cancels previous Request
@ -92,11 +116,15 @@
this.getOptionsValuesCancel.cancel('Facet search Canceled.'); this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' ) if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( query, this.isRepositoryLevel, valuesToIgnore ); promise = this.getValuesRelationship( this.searchQuery, this.isRepositoryLevel, valuesToIgnore, this.searchOffset, this.searchNumber );
else else
promise = this.getValuesPlainText( this.metadatumId, query, this.isRepositoryLevel, valuesToIgnore ); promise = this.getValuesPlainText( this.metadatumId, this.searchQuery, this.isRepositoryLevel, valuesToIgnore, this.searchOffset, this.searchNumber );
promise.request promise.request
.then( res => {
this.totalFacets = res.headers['x-wp-total'];
this.searchOffset += this.searchNumber;
})
.catch( error => { .catch( error => {
if (isCancel(error)) if (isCancel(error))
this.$console.log('Request canceled: ' + error.message); this.$console.log('Request canceled: ' + error.message);
@ -108,6 +136,10 @@
this.getOptionsValuesCancel = promise.source; this.getOptionsValuesCancel = promise.source;
}, 500), }, 500),
searchMore: _.debounce(function () {
this.shouldAddOptions = true;
this.search(this.searchQuery);
}, 250),
updateSelectedValues() { updateSelectedValues() {
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) ) if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )

View File

@ -50,19 +50,25 @@
import { tainacan as axios, CancelToken, isCancel } from '../../../js/axios'; import { tainacan as axios, CancelToken, isCancel } from '../../../js/axios';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import CheckboxRadioModal from '../../../components/modals/checkbox-radio-modal.vue'; import CheckboxRadioModal from '../../../components/modals/checkbox-radio-modal.vue';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../../../js/filter-types-mixin'; import { filterTypeMixin } from '../../../js/filter-types-mixin';
export default { export default {
mixins: [ filterTypeMixin, dynamicFilterTypeMixin ], mixins: [ filterTypeMixin ],
data(){ data(){
return { return {
isLoadingOptions: true, isLoadingOptions: true,
getOptionsValuesCancel: undefined,
options: [], options: [],
selected: [], selected: [],
taxonomy: '', taxonomy: '',
taxonomyId: '' taxonomyId: ''
} }
}, },
computed: {
facetsFromItemSearch() {
return this.getFacets();
}
},
watch: { watch: {
selected(newVal, oldVal) { selected(newVal, oldVal) {
const isEqual = (newVal.length == oldVal.length) && newVal.every((element, index) => { const isEqual = (newVal.length == oldVal.length) && newVal.every((element, index) => {
@ -76,6 +82,9 @@
if (this.isUsingElasticSearch) if (this.isUsingElasticSearch)
this.loadOptions(); this.loadOptions();
}, },
isLoadingItems() {
this.isLoadingOptions = this.isLoadingItems;
},
'query.metaquery'() { 'query.metaquery'() {
this.loadOptions(); this.loadOptions();
}, },

View File

@ -16,7 +16,9 @@
:class="{'has-selected': selected != undefined && selected != []}" :class="{'has-selected': selected != undefined && selected != []}"
@typing="search" @typing="search"
@input="onSelect" @input="onSelect"
:placeholder="$i18n.get('info_type_to_add_terms')"> :placeholder="$i18n.get('info_type_to_add_terms')"
check-infinite-scroll
@infinite-scroll="searchMore">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div class="media-content"> <div class="media-content">
@ -39,20 +41,27 @@
<script> <script>
import qs from 'qs'; import qs from 'qs';
import { tainacan as axios } from '../../../js/axios'; import { tainacan as axios } from '../../../js/axios';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../../../js/filter-types-mixin'; import { filterTypeMixin } from '../../../js/filter-types-mixin';
export default { export default {
mixins: [ filterTypeMixin, dynamicFilterTypeMixin ], mixins: [ filterTypeMixin ],
data(){ data(){
return { return {
isLoadingOptions: false,
results:'', results:'',
selected:[], selected:[],
options: [], options: [],
taxonomy: '', taxonomy: '',
taxonomyId: '' taxonomyId: '',
searchQuery: '',
totalFacets: 0,
offset: 0
} }
}, },
watch: { watch: {
isLoadingItems() {
this.isLoadingOptions = this.isLoadingItems;
},
'query.taxquery'() { 'query.taxquery'() {
this.updateSelectedValues(); this.updateSelectedValues();
}, },
@ -75,12 +84,32 @@
}, },
methods: { methods: {
search: _.debounce( function(query) { search: _.debounce( function(query) {
// String update
if (query != this.searchQuery) {
this.searchQuery = query;
this.options = [];
this.offset = 0;
}
// String cleared
if (!query.length) {
this.searchQuery = query;
this.options = [];
this.offset = 0;
}
// No need to load more
if (this.offset > 0 && this.options.length >= this.totalFacets)
return
this.isLoadingOptions = true; this.isLoadingOptions = true;
this.options = [];
let query_items = { let query_items = {
'current_query': this.query, 'current_query': this.query,
'search': query 'search': this.searchQuery,
'offset': this.offset,
'number': 12
}; };
let endpoint = this.isRepositoryLevel ? '/facets/' + this.metadatumId : '/collection/'+ this.collectionId +'/facets/' + this.metadatumId; let endpoint = this.isRepositoryLevel ? '/facets/' + this.metadatumId : '/collection/'+ this.collectionId +'/facets/' + this.metadatumId;
@ -88,7 +117,8 @@
endpoint += '?order=asc&' + qs.stringify(query_items); endpoint += '?order=asc&' + qs.stringify(query_items);
let valuesToIgnore = []; let valuesToIgnore = [];
for(let val of this.selected)
for (let val of this.selected)
valuesToIgnore.push( val.value ); valuesToIgnore.push( val.value );
return axios.get(endpoint).then( res => { return axios.get(endpoint).then( res => {
@ -97,7 +127,7 @@
if (valuesToIgnore != undefined && valuesToIgnore.length > 0) { if (valuesToIgnore != undefined && valuesToIgnore.length > 0) {
let indexToIgnore = valuesToIgnore.findIndex(value => value == term.value); let indexToIgnore = valuesToIgnore.findIndex(value => value == term.value);
if (indexToIgnore < 0) { if (indexToIgnore < 0) {
if( term.label.toLowerCase().indexOf( query.toLowerCase() ) >= 0 ){ if (term.label.toLowerCase().indexOf( query.toLowerCase() ) >= 0){
this.options.push({ this.options.push({
label: term.label, label: term.label,
value: term.value, value: term.value,
@ -106,15 +136,19 @@
} }
} }
} else { } else {
if( term.label.toLowerCase().indexOf( query.toLowerCase() ) >= 0 ){ if (term.label.toLowerCase().indexOf( query.toLowerCase() ) >= 0){
this.options.push({ this.options.push({
label: term.label, label: term.label,
value: term.value, value: term.value,
total_items: term.total_items total_items: term.total_items
}); });
} }
} }
} }
this.totalFacets = res.headers['x-wp-total'];
this.offset += 12;
this.isLoadingOptions = false; this.isLoadingOptions = false;
}) })
.catch(error => { .catch(error => {
@ -122,6 +156,9 @@
this.$console.log(error); this.$console.log(error);
}); });
}, 500), }, 500),
searchMore: _.debounce(function () {
this.search(this.searchQuery)
}, 250),
updateSelectedValues(){ updateSelectedValues(){
if ( !this.query || !this.query.taxquery || !Array.isArray( this.query.taxquery ) ) if ( !this.query || !this.query.taxquery || !Array.isArray( this.query.taxquery ) )
return false; return false;

View File

@ -148,7 +148,6 @@ export default {
// Term Item // Term Item
.term-item { .term-item {
font-size: 0.875em;
padding: 0 0 0 1.75em; padding: 0 0 0 1.75em;
min-height: 40px; min-height: 40px;
display: flex; display: flex;

View File

@ -327,7 +327,6 @@ export default {
// Term Item // Term Item
.term-item { .term-item {
font-size: 0.875em;
padding: 0 0 0 1.75em; padding: 0 0 0 1.75em;
min-height: 40px; min-height: 40px;
display: flex; display: flex;

View File

@ -26,7 +26,7 @@
<span class="icon is-small gray-icon"> <span class="icon is-small gray-icon">
<i <i
:class="order == 'desc' ? 'tainacan-icon-sortdescending' : 'tainacan-icon-sortascending'" :class="order == 'desc' ? 'tainacan-icon-sortdescending' : 'tainacan-icon-sortascending'"
class="tainacan-icon"/> class="tainacan-icon tainacan-icon-1-25em"/>
</span> </span>
<span class="icon"> <span class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-arrowdown" /> <i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-arrowdown" />
@ -40,7 +40,7 @@
aria-role="listitem" aria-role="listitem"
style="padding-bottom: 0.45em"> style="padding-bottom: 0.45em">
<span class="icon is-small gray-icon"> <span class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-sortdescending"/> <i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-sortdescending"/>
</span> </span>
{{ $i18n.get('label_descending') }} {{ $i18n.get('label_descending') }}
</b-dropdown-item> </b-dropdown-item>
@ -52,7 +52,7 @@
aria-role="listitem" aria-role="listitem"
style="padding-bottom: 0.45em"> style="padding-bottom: 0.45em">
<span class="icon is-small gray-icon"> <span class="icon is-small gray-icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-sortascending"/> <i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-sortascending"/>
</span> </span>
{{ $i18n.get('label_ascending') }} {{ $i18n.get('label_ascending') }}
</b-dropdown-item> </b-dropdown-item>
@ -79,6 +79,7 @@
:active.sync="isLoadingTerms" :active.sync="isLoadingTerms"
:can-cancel="false"/> :can-cancel="false"/>
<div <div
style="font-size: 0.875em;"
:class="{ 'is-12': !isEditingTerm, 'is-8-fullhd is-7-fullscreen is-6-desktop is-5-tablet': isEditingTerm }" :class="{ 'is-12': !isEditingTerm, 'is-8-fullhd is-7-fullscreen is-6-desktop is-5-tablet': isEditingTerm }"
class="column"> class="column">
<br> <br>

View File

@ -0,0 +1,100 @@
<?php
namespace Tainacan\Metadata_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class MetadataTypeHelper
*/
class Metadata_Type_Helper {
private static $instance = null;
/**
* Stores external metadata type available to be used in Tainacan
*/
private $registered_metadata_type;
private $Tainacan_Metadata;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->registered_metadata_type = [];
$this->Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();;
$this->init();
}
private function init() {
//register metadatum types
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Text');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Textarea');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Date');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Numeric');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Selectbox');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Relationship');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Taxonomy');
//$Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Compound');
// the priority should see less than on function
// `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php
add_action( 'admin_enqueue_scripts', array( &$this, 'register_metadata_type_compoment' ), 80 );
do_action('tainacan-register-metadata-type', $this);
}
public function register_metadata_type_compoment() {
foreach($this->registered_metadata_type as $handle => $component) {
wp_enqueue_script($handle, $component['script_path']);
}
}
/**
* Register a new Metadata Type
*
* @param string $handle name of the component. Should be unique.
* @param string $class a class name of the metadata type
* @param array|string $args
*/
public function register_metadata_type($handle, $class_name, $script_path, $args = []) {
global $TAINACAN_EXTRA_SCRIPTS;
$this->Tainacan_Metadata->register_metadata_type($class_name);
if ( ! in_array( $handle, $this->registered_metadata_type ) ) {
$TAINACAN_EXTRA_SCRIPTS[] = $handle;
$this->registered_metadata_type[$handle] = [
'handle' => $handle,
'class_name' => $class_name,
'script_path' => $script_path,
'args' => $args
];
}
}
/**
* Get a list of all registered metadata type
*
* @return array The list of registered metadata type
*/
public function get_registered_metadata_type() {
return $this->registered_metadata_type;
}
/**
* Get one specific metadata type by its slug
*
* @param string $handle Name of the component
*
* @return array|false The metadata type definition or false if it is not found
*/
public function get_metadata_type($handle) {
return isset($this->registered_metadata_type[$handle]) ? $this->registered_metadata_type[$handle] : false;
}
}

View File

@ -13,12 +13,14 @@
:maxtags="maxtags != undefined ? maxtags : (metadatum.metadatum.multiple == 'yes' || allowNew === true ? 100 : 1)" :maxtags="maxtags != undefined ? maxtags : (metadatum.metadatum.multiple == 'yes' || allowNew === true ? 100 : 1)"
autocomplete autocomplete
attached attached
:placeholder="$i18n.get('instruction_type_existing_term')" :placeholder="$i18n.get('instruction_type_existing_item')"
:loading="isLoading" :loading="isLoading"
:aria-close-label="$i18n.get('remove_value')" :aria-close-label="$i18n.get('remove_value')"
:class="{'has-selected': selected != undefined && selected != []}" :class="{'has-selected': selected != undefined && selected != []}"
field="label" field="label"
@typing="(query) => { options = []; search(query); }"> @typing="search"
check-infinite-scroll
@infinite-scroll="searchMore">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div <div
@ -62,7 +64,10 @@
collectionId: '', collectionId: '',
inputValue: null, inputValue: null,
queryObject: {}, queryObject: {},
itemsFound: [] itemsFound: [],
searchQuery: '',
totalItems: 0,
page: 1
} }
}, },
created() { created() {
@ -100,16 +105,34 @@
this.$emit('blur'); this.$emit('blur');
}, },
search: _.debounce(function(query) { search: _.debounce(function(query) {
if ( this.selected.length > 0 && this.metadatum.metadatum.multiple === 'no')
return '';
if (query !== '') { // String update
if (query != this.searchQuery) {
this.searchQuery = query;
this.options = [];
this.page = 1;
}
// String cleared
if (!query.length) {
this.searchQuery = query;
this.options = [];
this.page = 1;
}
// No need to load more
if (this.page > 1 && this.options.length > this.totalItems*12)
return;
// There is already one value set and is not multiple
if (this.selected.length > 0 && this.metadatum.metadatum.multiple === 'no')
return;
if (this.searchQuery !== '') {
this.isLoading = true; this.isLoading = true;
axios.get('/collection/' + this.collectionId + '/items?' + this.getQueryString(query)) axios.get('/collection/' + this.collectionId + '/items?' + this.getQueryString(this.searchQuery))
.then( res => { .then( res => {
this.isLoading = false;
this.options = [];
if (res.data.items) { if (res.data.items) {
for (let item of res.data.items) for (let item of res.data.items)
@ -119,13 +142,23 @@
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : '' img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : ''
}) })
} }
if (res.headers['x-wp-total'])
this.totalItems = res.headers['x-wp-total'];
this.page++;
this.isLoading = false;
}) })
.catch(error => { .catch(error => {
this.isLoading = false;
this.$console.log(error); this.$console.log(error);
}); });
} }
}, 500), }, 500),
searchMore: _.debounce(function () {
this.search(this.searchQuery)
}, 250),
getItemLabel(item) { getItemLabel(item) {
let label = ''; let label = '';
for (let m in item.metadata) { for (let m in item.metadata) {
@ -158,6 +191,8 @@
} }
query['fetch_only'] = 'title,thumbnail'; query['fetch_only'] = 'title,thumbnail';
query['fetch_only_meta'] = this.metadatum.metadatum.metadata_type_options.search; query['fetch_only_meta'] = this.metadatum.metadatum.metadata_type_options.search;
query['perpage'] = 12;
query['paged'] = this.page;
return qs.stringify(query); return qs.stringify(query);
} }

View File

@ -56,9 +56,11 @@
clearable clearable
@select="onSelectParentTerm($event)" @select="onSelectParentTerm($event)"
:loading="isFetchingParentTerms" :loading="isFetchingParentTerms"
@input="fecthParentTerms($event)" @input="fetchParentTerms"
@focus="clearErrors('parent');" @focus="clearErrors('parent');"
:disabled="!hasParent"> :disabled="!hasParent"
check-infinite-scroll
@infinite-scroll="fetchMoreParentTerms">
<template slot-scope="props"> <template slot-scope="props">
{{ props.option.name }} {{ props.option.name }}
</template> </template>
@ -117,7 +119,9 @@
isFetchingParentTerms: false, isFetchingParentTerms: false,
metadatumId: this.metadatum.metadatum.id, metadatumId: this.metadatum.metadatum.id,
itemId: this.metadatum.item.id, itemId: this.metadatum.item.id,
formErrors: {} formErrors: {},
parentTermSearchQuery: '',
parentTermSearchOffset: 0
} }
}, },
mounted() { mounted() {
@ -139,22 +143,50 @@
this.formErrors = {}; this.formErrors = {};
this.showForm = !this.showForm; this.showForm = !this.showForm;
}, },
fecthParentTerms(search) { fetchParentTerms: _.debounce(function(search) {
// String update
if (search != this.parentTermSearchQuery) {
this.parentTermSearchQuery = search;
this.parentTerms = [];
this.parentTermSearchOffset = 0;
}
// String cleared
if (!search.length) {
this.parentTermSearchQuery = search;
this.parentTerms = [];
this.parentTermSearchOffset = 0;
}
// No need to load more
if (this.parentTermSearchOffset > 0 && this.parentTerms.length >= this.totalTerms)
return
this.isFetchingParentTerms = true; this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({ this.fetchPossibleParentTerms({
taxonomyId: this.taxonomyId, taxonomyId: this.taxonomyId,
termId: 'new', termId: 'new',
search: search }) search: this.parentTermSearchQuery,
.then((parentTerms) => { offset: this.parentTermSearchOffset })
this.parentTerms = parentTerms; .then((res) => {
for (let term of res.parentTerms)
this.parentTerms.push(term);
this.parentTermSearchOffset += 12;
this.totalTerms = res.totalTerms;
this.isFetchingParentTerms = false; this.isFetchingParentTerms = false;
}) })
.catch((error) => { .catch((error) => {
this.$console.error(error); this.$console.error(error);
this.isFetchingParentTerms = false; this.isFetchingParentTerms = false;
}); });
}, }, 500),
fetchMoreParentTerms: _.debounce(function () {
this.fetchParentTerms(this.parentTermSearchQuery)
}, 250),
onToggleSwitch() { onToggleSwitch() {
this.clearErrors('parent'); this.clearErrors('parent');
}, },

View File

@ -18,9 +18,11 @@
:aria-close-label="$i18n.get('remove_value')" :aria-close-label="$i18n.get('remove_value')"
:placeholder="$i18n.get('instruction_type_existing_term')" :placeholder="$i18n.get('instruction_type_existing_term')"
:loading="isFetching" :loading="isFetching"
:class="{'has-selected': selected != undefined && selected != []}" :class="{ 'has-selected': selected != undefined && selected != [] }"
autocomplete autocomplete
@typing="autoCompleteTerm"> @typing="loadTerms"
check-infinite-scroll
@infinite-scroll="loadMoreTerms">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div class="media-content"> <div class="media-content">
@ -50,11 +52,14 @@
allowSelectToCreate: false, allowSelectToCreate: false,
maxtags: '', maxtags: '',
}, },
data(){ data() {
return { return {
selected: [], selected: [],
labels: [], labels: [],
isFetching: false, isFetching: false,
offset: 0,
searchName: '',
totalTerms: 0
} }
}, },
watch: { watch: {
@ -77,8 +82,26 @@
...mapGetters('taxonomy', [ ...mapGetters('taxonomy', [
'getTerms' 'getTerms'
]), ]),
autoCompleteTerm: _.debounce( function(value) { loadTerms: _.debounce( function(value) {
this.labels = [];
// String update
if (value != this.searchName) {
this.searchName = value;
this.labels = [];
this.offset = 0;
}
// String cleared
if (!value.length) {
this.searchName = value;
this.labels = [];
this.offset = 0;
}
// No need to load more
if (this.offset > 0 && this.labels.length >= this.totalTerms)
return
this.isFetching = true; this.isFetching = true;
this.fetchTerms({ this.fetchTerms({
@ -90,19 +113,22 @@
} }
}, },
search: { search: {
searchterm: value searchterm: this.searchName
}, },
all: true, all: true,
order: 'asc', order: 'asc',
offset: 0, offset: this.offset,
number: 12 number: 12
}).then((res) => { }).then((res) => {
for (let term of res.terms) for (let term of res.terms)
this.labels.push({label: term.name, value: term.id}); this.labels.push({ label: term.name, value: term.id });
if (res.terms.length <= 0 && this.allowSelectToCreate) if (res.terms.length <= 0 && this.allowSelectToCreate)
this.labels.push({label: `${value} (${this.$i18n.get('select_to_create')})`, value: value}) this.labels.push({ label: `${value} (${this.$i18n.get('select_to_create')})`, value: value })
this.offset += 12;
this.totalTerms = res.total;
this.isFetching = false; this.isFetching = false;
}).catch((error) => { }).catch((error) => {
@ -110,6 +136,9 @@
throw error; throw error;
}); });
}, 500), }, 500),
loadMoreTerms: _.debounce(function () {
this.loadTerms(this.searchName)
}, 250),
updateSelectedValues(){ updateSelectedValues(){
let selected = []; let selected = [];

View File

@ -462,13 +462,13 @@
promise = this.getValuesPlainText( this.metadatumId, this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true); promise = this.getValuesPlainText( this.metadatumId, this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true);
promise.request promise.request
.then((data) => { .then((res) => {
this.isCheckboxListLoading = false; this.isCheckboxListLoading = false;
this.isSearchingLoading = false; this.isSearchingLoading = false;
if (this.isUsingElasticSearch) { if (this.isUsingElasticSearch) {
this.checkboxListOffset = data.last_term; this.checkboxListOffset = res.data.last_term;
if (!this.lastTermOnFisrtPage || this.lastTermOnFisrtPage == this.checkboxListOffset) { if (!this.lastTermOnFisrtPage || this.lastTermOnFisrtPage == this.checkboxListOffset) {
this.lastTermOnFisrtPage = this.checkboxListOffset; this.lastTermOnFisrtPage = this.checkboxListOffset;

View File

@ -351,9 +351,6 @@ export default {
.icon { .icon {
margin: 0; margin: 0;
padding: 0; padding: 0;
i {
font-size: 1.125em !important;
}
svg { svg {
position: relative; position: relative;
top: 2px; top: 2px;

View File

@ -418,7 +418,7 @@
resp.request resp.request
.then(() => this.isLoadingFilters = false) .then(() => this.isLoadingFilters = false)
.catch(() => this.isLoadingFilters = false); .catch(() => this.isLoadingFilters = false);
// Search Request Token for cancelling // Search Request Token for cancelling
this.filtersSearchCancel = resp.source; this.filtersSearchCancel = resp.source;
}) })

View File

@ -4,13 +4,17 @@ export const tainacan = axios.create({
baseURL: tainacan_plugin.tainacan_api_url baseURL: tainacan_plugin.tainacan_api_url
}); });
tainacan.defaults.headers.common['X-WP-Nonce'] = tainacan_plugin.nonce; if (tainacan_plugin.nonce) {
tainacan.defaults.headers.common['X-WP-Nonce'] = tainacan_plugin.nonce;
}
export const wp = axios.create({ export const wp = axios.create({
baseURL: tainacan_plugin.wp_api_url baseURL: tainacan_plugin.wp_api_url
}); });
wp.defaults.headers.common['X-WP-Nonce'] = tainacan_plugin.nonce; if (tainacan_plugin.nonce) {
wp.defaults.headers.common['X-WP-Nonce'] = tainacan_plugin.nonce;
}
export const CancelToken = axios.CancelToken; export const CancelToken = axios.CancelToken;
export const isCancel = axios.isCancel; export const isCancel = axios.isCancel;

View File

@ -9,6 +9,7 @@ export const filterTypeMixin = {
metadatumId: '', metadatumId: '',
metadatumType: '', metadatumType: '',
filterTypeOptions: [], filterTypeOptions: [],
shouldAddOptions: false
} }
}, },
props: { props: {
@ -32,6 +33,7 @@ export const dynamicFilterTypeMixin = {
thumbPlaceholderPath: tainacan_plugin.base_url + '/assets/images/placeholder_square.png', thumbPlaceholderPath: tainacan_plugin.base_url + '/assets/images/placeholder_square.png',
getOptionsValuesCancel: undefined, getOptionsValuesCancel: undefined,
isLoadingOptions: false, isLoadingOptions: false,
facetSearchPage: 1
} }
}, },
computed: { computed: {
@ -65,6 +67,7 @@ export const dynamicFilterTypeMixin = {
let query_items = { 'current_query': currentQuery }; let query_items = { 'current_query': currentQuery };
let url = ''; let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'default') if (isRepositoryLevel || this.filter.collection_id == 'default')
url = `/facets/${metadatumId}?getSelected=${getSelected}&`; url = `/facets/${metadatumId}?getSelected=${getSelected}&`;
else else
@ -77,13 +80,12 @@ export const dynamicFilterTypeMixin = {
url += `last_term=${offset}&number=${number}&`; url += `last_term=${offset}&number=${number}&`;
} }
if(search && offset != undefined && number != undefined){ if (search && offset != undefined && number != undefined)
url += `search=${search}&` + qs.stringify(query_items); url += `search=${search}&` + qs.stringify(query_items);
} else if(search){ else if (search)
url += `search=${search}&` + qs.stringify(query_items); url += `search=${search}&` + qs.stringify(query_items);
} else { else
url += qs.stringify(query_items); url += qs.stringify(query_items);
}
this.isLoadingOptions = true; this.isLoadingOptions = true;
@ -99,7 +101,7 @@ export const dynamicFilterTypeMixin = {
else else
this.prepareOptionsForPlainText(res.data, search, valuesToIgnore, isInCheckboxModal); this.prepareOptionsForPlainText(res.data, search, valuesToIgnore, isInCheckboxModal);
resolve(res.data); resolve(res);
}) })
.catch((thrown) => { .catch((thrown) => {
if (axios.isCancel(thrown)) { if (axios.isCancel(thrown)) {
@ -143,20 +145,19 @@ export const dynamicFilterTypeMixin = {
let query_items = { 'current_query': currentQuery }; let query_items = { 'current_query': currentQuery };
let url = ''; let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'default') if (isRepositoryLevel || this.filter.collection_id == 'default')
url = '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`; url = '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;
else else
url = '/collection/' + this.filter.collection_id + '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`; url = '/collection/' + this.filter.collection_id + '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;
if(offset != undefined && number != undefined){ if (offset != undefined && number != undefined)
url += `offset=${offset}&number=${number}`; url += `offset=${offset}&number=${number}`;
} else { else
url += `nopaging=1` url += `nopaging=1`;
}
if(search){ if (search)
url += `&search=${search}`; url += `&search=${search}`;
}
this.isLoadingOptions = true; this.isLoadingOptions = true;
@ -165,6 +166,7 @@ export const dynamicFilterTypeMixin = {
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
axios.tainacan.get(url + '&fetch_only=thumbnail,title,id&' + qs.stringify(query_items)) axios.tainacan.get(url + '&fetch_only=thumbnail,title,id&' + qs.stringify(query_items))
.then(res => { .then(res => {
this.isLoadingOptions = false; this.isLoadingOptions = false;
if (res.data.values) if (res.data.values)
@ -172,7 +174,7 @@ export const dynamicFilterTypeMixin = {
else else
this.prepareOptionsForRelationship(res.data, search, valuesToIgnore, isInCheckboxModal); this.prepareOptionsForRelationship(res.data, search, valuesToIgnore, isInCheckboxModal);
resolve(res.data); resolve(res);
}) })
.catch((thrown) => { .catch((thrown) => {
if (axios.isCancel(thrown)) { if (axios.isCancel(thrown)) {
@ -240,15 +242,22 @@ export const dynamicFilterTypeMixin = {
} }
} }
} }
if (this.shouldAddOptions === true && this.searchResults && this.searchResults.length)
this.searchResults = this.searchResults.concat(sResults);
else
this.searchResults = sResults;
this.searchResults = sResults; if (opts.length) {
if (this.shouldAddOptions === true && this.options && this.options.length)
if (opts.length) this.options = this.options.concat(opts)
this.options = opts; else
this.options = opts;
}
else if(!search) else if(!search)
this.noMorePage = 1; this.noMorePage = 1;
if(this.options.length < this.maxNumOptionsCheckboxList && !search) if (this.options.length < this.maxNumOptionsCheckboxList && !search)
this.noMorePage = 1; this.noMorePage = 1;
if (this.filter.max_options && this.options.length >= this.filter.max_options) { if (this.filter.max_options && this.options.length >= this.filter.max_options) {
@ -305,14 +314,22 @@ export const dynamicFilterTypeMixin = {
} }
} }
} }
console.log(this.shouldAddOptions)
this.searchResults = sResults; if (this.shouldAddOptions === true && this.searchResults && this.searchResults.length)
this.searchResults = this.searchResults.concat(sResults);
if (opts.length)
this.options = opts;
else else
this.searchResults = sResults;
if (opts.length) {
if (this.shouldAddOptions === true && this.options && this.options.length)
this.options = this.options.concat(opts)
else
this.options = opts;
}
else if(!search)
this.noMorePage = 1; this.noMorePage = 1;
if (this.options.length < this.maxNumOptionsCheckboxList) if (this.options.length < this.maxNumOptionsCheckboxList)
this.noMorePage = 1; this.noMorePage = 1;

View File

@ -55,6 +55,12 @@ import eventBusSearch from './event-bus-search';
import eventBusTermsList from './event-bus-terms-list.js'; import eventBusTermsList from './event-bus-terms-list.js';
import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, UserCapabilitiesPlugin, StatusHelperPlugin, CommentsStatusHelperPlugin } from './utilities'; import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, UserCapabilitiesPlugin, StatusHelperPlugin, CommentsStatusHelperPlugin } from './utilities';
/* Registers Extra Vue Pluginss passed to the TainacanExtraVuePlugins */
if (typeof TainacanExtraVuePlugins != "undefined") {
for (let [extraVuePluginName, extraVuePluginObject] of Object.entries(TainacanExtraVuePlugin))
Vue.use(extraVuePluginObject);
}
// Configure and Register Plugins // Configure and Register Plugins
Vue.use(Buefy, { Vue.use(Buefy, {
defaultTooltipAnimated: true defaultTooltipAnimated: true
@ -70,6 +76,12 @@ Vue.use(ConsolePlugin, {visual: false});
Vue.use(VueTheMask); Vue.use(VueTheMask);
Vue.use(CommentsStatusHelperPlugin); Vue.use(CommentsStatusHelperPlugin);
/* Registers Extra Vue Components passed to the TainacanExtraVueComponents */
if (typeof TainacanExtraVueComponents != "undefined") {
for (let [extraVueComponentName, extraVueComponentObject] of Object.entries(TainacanExtraVueComponents))
Vue.component(extraVueComponentName, extraVueComponentObject);
}
/* Metadata */ /* Metadata */
Vue.component('tainacan-text', Text); Vue.component('tainacan-text', Text);
Vue.component('tainacan-textarea', Textarea); Vue.component('tainacan-textarea', Textarea);

View File

@ -166,11 +166,16 @@ export const notApprove = ({commit}, activityId) => {
}; };
// Users for filtering // Users for filtering
export const fetchUsers = ({ commit }, { search }) => { export const fetchUsers = ({ commit }, { search, page }) => {
let endpoint = '/users?search=' + search;
if (page)
endpoint += '&page=' + page;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.wp.get('/users?search=' + search) axios.wp.get(endpoint)
.then(res => { .then(res => {
resolve(res.data); resolve({ users: res.data, totalUsers: res.headers['x-wp-total'] } );
}) })
.catch(error => { .catch(error => {
reject(error); reject(error);

View File

@ -355,12 +355,13 @@ export const updateHeaderImage = ({ commit }, { collectionId, headerImageId }) =
}; };
// Collection Cover Page // Collection Cover Page
export const fetchPages = ({ commit }, search ) => { export const fetchPages = ({ commit }, { search, page } ) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.wp.get('/pages?search=' + search) axios.wp.get('/pages?search=' + search + '&page=' + page)
.then(res => { .then(res => {
let pages = res.data; const pages = res.data;
resolve( pages ); const totalPages = res.headers['x-wp-total'];
resolve( { pages, totalPages} );
}) })
.catch(error => { .catch(error => {
reject( error ); reject( error );

View File

@ -301,16 +301,25 @@ export const clearTerms = ({ commit }) => {
}; };
// Used only on Term Edition form, for autocomplete search for parents // Used only on Term Edition form, for autocomplete search for parents
export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, search } ) => { export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, search, offset } ) => {
let endpoint = '/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&exclude_tree=' + termId + "&hideempty=0&offset=0&number=20&order=asc";
if (offset)
endpoint += '&offset=' + offset;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&exclude_tree=' + termId + "&hideempty=0&offset=0&number=20&order=asc") axios.tainacan.get(endpoint)
.then(res => { .then(res => {
let parentTerms = res.data; let parentTerms = res.data;
const theParentIndex = parentTerms.findIndex((term) => term.id == termId); const theParentIndex = parentTerms.findIndex((term) => term.id == termId);
if (theParentIndex >= 0) if (theParentIndex >= 0)
parentTerms.splice(theParentIndex, 1); parentTerms.splice(theParentIndex, 1);
resolve( parentTerms ); const totalTerms = res.headers['x-wp-total'];
resolve( { parentTerms, totalTerms } );
}) })
.catch(error => { .catch(error => {
reject( error ); reject( error );

View File

@ -92,7 +92,9 @@
@select="filterActivitiesByUser" @select="filterActivitiesByUser"
:loading="isFetchingUsers" :loading="isFetchingUsers"
field="name" field="name"
icon="account"> icon="account"
check-infinite-scroll
@infinite-scroll="fetchMoreUsersForFiltering">
<template slot-scope="props"> <template slot-scope="props">
<div class="media"> <div class="media">
<div <div
@ -285,7 +287,10 @@
searchDates: [], searchDates: [],
users: [], users: [],
isFetchingUsers: false, isFetchingUsers: false,
userIdForFiltering: null userIdForFiltering: null,
usersForFilteringSearchQuery: '',
usersForFilteringSearchPage: 1,
totalUsers: 0
} }
}, },
computed: { computed: {
@ -504,18 +509,48 @@
}, },
fetchUsersForFiltering: _.debounce(function (search) { fetchUsersForFiltering: _.debounce(function (search) {
// String update
if (search != this.usersForFilteringSearchQuery) {
this.usersForFilteringSearchQuery = search;
this.users = [];
this.usersForFilteringSearchPage = 1;
}
// String cleared
if (!search.length) {
this.usersForFilteringSearchQuery = search;
this.users = [];
this.usersForFilteringSearchPage = 1;
}
// No need to load more
if (this.usersForFilteringSearchPage > 1 && this.users.length > this.totalPages*12)
return;
this.isFetchingUsers = true; this.isFetchingUsers = true;
this.fetchUsers({ search: search }) this.fetchUsers({ search: this.usersForFilteringSearchQuery, page: this.usersForFilteringSearchPage })
.then((users) => { .then((res) => {
this.users = users; if (res.users) {
for (let user of res.users)
this.users.push(user);
}
if (res.totalUsers)
this.totalUsers = res.totalUsers;
this.usersForFilteringSearchPage++;
this.isFetchingUsers = false; this.isFetchingUsers = false;
}) })
.catch((error) => { .catch((error) => {
this.$console.error(error); this.$console.error(error);
this.isFetchingPages = false; this.isFetchingPages = false;
}); });
}, 500) }, 500),
fetchMoreUsersForFiltering: _.debounce(function () {
this.fetchUsersForFiltering(this.usersForFilteringSearchQuery)
}, 250),
} }
} }
</script> </script>

View File

@ -1540,7 +1540,7 @@
animation-duration: 0.5s; animation-duration: 0.5s;
p { p {
margin: 0 auto; margin: 0 auto !important;
font-size: 0.885em; font-size: 0.885em;
} }

View File

@ -101,6 +101,7 @@
} }
.pagination-list { .pagination-list {
flex-wrap: nowrap; flex-wrap: nowrap;
font-size: 1em;
} }
.pagination-link, .pagination-previous, .pagination-next { .pagination-link, .pagination-previous, .pagination-next {
background-color: transparent; background-color: transparent;

View File

@ -162,8 +162,16 @@ class Admin {
function add_admin_js() { function add_admin_js() {
global $TAINACAN_BASE_URL; global $TAINACAN_BASE_URL;
global $TAINACAN_EXTRA_SCRIPTS;
wp_enqueue_script( 'tainacan-admin', $TAINACAN_BASE_URL . '/assets/js/admin.js', ['underscore', 'media-editor', 'media-views', 'customize-controls'], TAINACAN_VERSION, true ); $deps = ['underscore', 'media-editor', 'media-views', 'customize-controls'];
if ( !empty($TAINACAN_EXTRA_SCRIPTS) ) {
foreach($TAINACAN_EXTRA_SCRIPTS as $dep) {
$deps[] = $dep;
}
}
wp_enqueue_script( 'tainacan-admin', $TAINACAN_BASE_URL . '/assets/js/admin.js', $deps, TAINACAN_VERSION, true );
$settings = $this->get_admin_js_localization_params(); $settings = $this->get_admin_js_localization_params();
@ -215,7 +223,7 @@ class Admin {
'tainacan_api_url' => esc_url_raw( rest_url() ) . 'tainacan/v2', 'tainacan_api_url' => esc_url_raw( rest_url() ) . 'tainacan/v2',
'wp_api_url' => esc_url_raw( rest_url() ) . 'wp/v2/', 'wp_api_url' => esc_url_raw( rest_url() ) . 'wp/v2/',
'wp_ajax_url' => admin_url( 'admin-ajax.php' ), 'wp_ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'wp_rest' ), 'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : false,
'components' => $components, 'components' => $components,
'i18n' => $tainacan_admin_i18n, 'i18n' => $tainacan_admin_i18n,
'user_caps' => $user_caps, 'user_caps' => $user_caps,
@ -254,10 +262,10 @@ class Admin {
} }
$filter_types = $Tainacan_Filters->fetch_filter_types(); $filter_types = $Tainacan_Filters->fetch_filter_types();
foreach ( $filter_types as $index => $filter_type){ foreach ( $filter_types as $index => $filter_type){
$class = new $filter_type; $class = new $filter_type;
$settings['i18n']['helpers_label'][$class->get_component()] = $class->get_form_labels(); $settings['i18n']['helpers_label'][$class->get_component()] = $class->get_form_labels();
} }
$settings['form_hooks'] = Admin_Hooks::get_instance()->get_registered_hooks(); $settings['form_hooks'] = Admin_Hooks::get_instance()->get_registered_hooks();

View File

@ -0,0 +1,84 @@
<?php
namespace Tainacan;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class Components_Hooks
*/
class Component_Hooks {
private static $instance = null;
/**
* Stores external component type available to be used in Tainacan
*/
private $registered_component;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->registered_component = [];
$this->init();
}
private function init() {
// the priority should see less than on function
// `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php
add_action( 'admin_enqueue_scripts', array( &$this, 'register_component' ), 80 );
}
public function register_component() {
do_action('tainacan-register-vuejs-component', $this);
foreach($this->registered_component as $handle => $component) {
wp_enqueue_script($handle, $component['script_path']);
}
}
/**
* Register a new vuejs component
*
* @param string $handle name of the component. Should be unique.
* @param string $script_path path of file component
* @param array|string $args
*/
public function register_vuejs_component($handle, $script_path, $args = []) {
global $TAINACAN_EXTRA_SCRIPTS;
if ( ! in_array( $handle, $this->registered_component ) ) {
$TAINACAN_EXTRA_SCRIPTS[] = $handle;
$this->registered_component[$handle] = [
'handle' => $handle,
'script_path' => $script_path,
'args' => $args
];
}
}
/**
* Get a list of all registered component
*
* @return array The list of registered component
*/
public function get_registered_component() {
return $this->registered_component;
}
/**
* Get one specific component by its slug
*
* @param string $handle Name of the component
*
* @return array|false The component definition or false if it is not found
*/
public function get_component($handle) {
return isset($this->registered_component[$handle]) ? $this->registered_component[$handle] : false;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace Tainacan;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class Plugins_Hooks
*/
class Plugin_Hooks {
private static $instance = null;
/**
* Stores external vue plugin available to be used in Tainacan
*/
private $registered_plugin;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->registered_plugin = [];
$this->init();
}
private function init() {
// the priority should see less than on function
// `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php
add_action( 'admin_enqueue_scripts', array( &$this, 'register_plugin' ), 80 );
do_action('tainacan-register-vuejs-plugin', $this);
}
public function register_plugin() {
foreach($this->registered_plugin as $handle => $plugin) {
wp_enqueue_script($handle, $plugin['script_path']);
}
}
/**
* Register a new vuejs plugin
*
* @param string $handle name of the plugin. Should be unique.
* @param string $script_path path of file plugin
* @param array|string $args
*/
public function register_vuejs_plugin($handle, $script_path, $args = []) {
global $TAINACAN_EXTRA_SCRIPTS;
if ( ! in_array( $handle, $this->registered_plugin ) ) {
$TAINACAN_EXTRA_SCRIPTS[] = $handle;
$this->registered_plugin[$handle] = [
'handle' => $handle,
'script_path' => $script_path,
'args' => $args
];
}
}
/**
* Get a list of all registered plugin
*
* @return array The list of registered plugin
*/
public function get_registered_plugin() {
return $this->registered_plugin;
}
/**
* Get one specific plugin by its slug
*
* @param string $handle Name of the plugin
*
* @return array|false The plugin definition or false if it is not found
*/
public function get_plugin($handle) {
return isset($this->registered_plugin[$handle]) ? $this->registered_plugin[$handle] : false;
}
}

View File

@ -19,6 +19,7 @@ function tainacan_blocks_add_gutenberg_blocks_actions() {
add_action('init', 'tainacan_blocks_register_tainacan_carousel_items_list'); add_action('init', 'tainacan_blocks_register_tainacan_carousel_items_list');
add_action('init', 'tainacan_blocks_register_tainacan_carousel_terms_list'); add_action('init', 'tainacan_blocks_register_tainacan_carousel_terms_list');
add_action('init', 'tainacan_blocks_register_tainacan_search_bar'); add_action('init', 'tainacan_blocks_register_tainacan_search_bar');
add_action('init', 'tainacan_blocks_register_tainacan_faceted_search');
add_action('init', 'tainacan_blocks_register_tainacan_collections_list'); add_action('init', 'tainacan_blocks_register_tainacan_collections_list');
add_action('init', 'tainacan_blocks_register_tainacan_carousel_collections_list'); add_action('init', 'tainacan_blocks_register_tainacan_carousel_collections_list');
add_action('init', 'tainacan_blocks_register_tainacan_facets_list'); add_action('init', 'tainacan_blocks_register_tainacan_facets_list');
@ -147,6 +148,37 @@ function tainacan_blocks_register_tainacan_dynamic_items_list(){
} }
} }
function tainacan_blocks_register_tainacan_faceted_search(){
global $TAINACAN_BASE_URL;
wp_register_script(
'faceted-search-theme',
$TAINACAN_BASE_URL . '/assets/js/theme_search.js',
['underscore']
//array('wp-components')
);
wp_register_script(
'faceted-search',
$TAINACAN_BASE_URL . '/assets/js/block_faceted_search.js',
array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor')
);
wp_register_style(
'faceted-search',
$TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-faceted-search.css',
array('wp-edit-blocks')
);
if (function_exists('register_block_type')) {
register_block_type( 'tainacan/faceted-search', array(
'editor_script' => 'faceted-search',
'style' => 'faceted-search',
'script' => 'faceted-search-theme'
) );
}
}
function tainacan_blocks_register_tainacan_carousel_items_list(){ function tainacan_blocks_register_tainacan_carousel_items_list(){
global $TAINACAN_BASE_URL; global $TAINACAN_BASE_URL;
@ -294,7 +326,7 @@ function tainacan_blocks_get_plugin_js_settings(){
$settings = [ $settings = [
'root' => esc_url_raw( rest_url() ) . 'tainacan/v2', 'root' => esc_url_raw( rest_url() ) . 'tainacan/v2',
'nonce' => wp_create_nonce( 'wp_rest' ), 'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : false,
'base_url' => $TAINACAN_BASE_URL, 'base_url' => $TAINACAN_BASE_URL,
'admin_url' => admin_url(), 'admin_url' => admin_url(),
'site_url' => site_url(), 'site_url' => site_url(),
@ -314,6 +346,10 @@ function tainacan_blocks_add_plugin_settings() {
wp_localize_script( 'carousel-items-list', 'tainacan_blocks', $settings ); wp_localize_script( 'carousel-items-list', 'tainacan_blocks', $settings );
wp_localize_script( 'carousel-terms-list', 'tainacan_blocks', $settings ); wp_localize_script( 'carousel-terms-list', 'tainacan_blocks', $settings );
wp_localize_script( 'search-bar', 'tainacan_blocks', $settings ); wp_localize_script( 'search-bar', 'tainacan_blocks', $settings );
wp_localize_script( 'faceted-search', 'tainacan_blocks', $settings );
// wp_localize_script( 'faceted-search-theme', 'tainacan_plugin', $settings );
wp_localize_script( 'faceted-search-theme', 'tainacan_plugin', \Tainacan\Admin::get_instance()->get_admin_js_localization_params() );
wp_localize_script( 'collections-list', 'tainacan_blocks', $settings ); wp_localize_script( 'collections-list', 'tainacan_blocks', $settings );
wp_localize_script( 'carousel-collections-list', 'tainacan_blocks', $settings ); wp_localize_script( 'carousel-collections-list', 'tainacan_blocks', $settings );
wp_localize_script( 'facets-list', 'tainacan_blocks', $settings ); wp_localize_script( 'facets-list', 'tainacan_blocks', $settings );

View File

@ -4,6 +4,8 @@ const tainacan = axios.create({
baseURL: tainacan_blocks.root baseURL: tainacan_blocks.root
}); });
tainacan.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce; if (tainacan_blocks.nonce) {
tainacan.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
}
export default tainacan; export default tainacan;

View File

@ -0,0 +1,289 @@
import tainacan from '../../js/axios.js';
import axios from 'axios';
const { __ } = wp.i18n;
const { TextControl, Button, Modal, SelectControl, RadioControl, Spinner } = wp.components;
export default class CollectionModal extends React.Component {
constructor(props) {
super(props);
// Initialize state
this.state = {
collectionViewModes: [],
collectionsPerPage: 24,
collectionId: undefined,
isLoadingCollections: false,
modalCollections: [],
totalModalCollections: 0,
collectionPage: 1,
collectionOrderBy: 'date-desc',
temporaryCollectionId: '',
searchCollectionName: '',
collections: [],
collectionsRequestSource: undefined
};
// Bind events
this.resetCollections = this.resetCollections.bind(this);
this.selectCollection = this.selectCollection.bind(this);
this.fetchCollections = this.fetchCollections.bind(this);
this.fetchModalCollections = this.fetchModalCollections.bind(this);
}
componentWillMount() {
this.setState({
collectionId: this.props.existingCollectionId,
temporaryCollectionId: this.props.existingCollectionId,
collectionPage: 1
});
this.fetchModalCollections();
}
cancelSelection() {
this.setState({
modalCollections: []
});
this.props.onCancelSelection();
}
// COLLECTIONS RELATED --------------------------------------------------
fetchModalCollections() {
let someModalCollections = this.state.modalCollections;
if (this.state.collectionPage <= 1)
someModalCollections = [];
let endpoint = '/collections/?perpage=' + this.state.collectionsPerPage + '&paged=' + this.state.collectionPage;
if (this.state.collectionOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.collectionOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.collectionOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.collectionOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
this.setState({
isLoadingCollections: true,
collectionPage: this.state.collectionPage + 1,
modalCollections: someModalCollections
});
tainacan.get(endpoint)
.then(response => {
let otherModalCollections = this.state.modalCollections;
for (let collection of response.data) {
otherModalCollections.push({
name: collection.name,
id: collection.id
});
}
this.setState({
isLoadingCollections: false,
modalCollections: otherModalCollections,
totalModalCollections: response.headers['x-wp-total']
});
return otherModalCollections;
})
.catch(error => {
console.log('Error trying to fetch collections: ' + error);
});
}
selectCollection(selectedCollectionId) {
this.setState({ collectionId: selectedCollectionId });
this.props.onSelectCollection(selectedCollectionId);
}
fetchCollections(name) {
if (this.state.collectionsRequestSource != undefined)
this.state.collectionsRequestSource.cancel('Previous collections search canceled.');
let aCollectionRequestSource = axios.CancelToken.source();
this.setState({
collectionsRequestSource: aCollectionRequestSource,
isLoadingCollections: true,
collections: []
});
let endpoint = '/collections/?perpage=' + this.state.collectionsPerPage;
if (name != undefined && name != '')
endpoint += '&search=' + name;
if (this.state.collectionOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.collectionOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.collectionOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.collectionOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
tainacan.get(endpoint, { cancelToken: aCollectionRequestSource.token })
.then(response => {
let someCollections = response.data.map((collection) => ({ name: collection.name, id: collection.id + '' }));
this.setState({
isLoadingCollections: false,
collections: someCollections
});
return someCollections;
})
.catch(error => {
console.log('Error trying to fetch collections: ' + error);
});
}
resetCollections() {
this.setState({
collectionId: null,
collectionPage: 1,
modalCollections: []
});
this.fetchModalCollections();
}
render() {
return (
<Modal
className="wp-block-tainacan-modal"
title={__('Select a collection to fetch items from', 'tainacan')}
onRequestClose={ () => this.cancelSelection() }
contentLabel={__('Select items', 'tainacan')}>
<div>
<div className="modal-search-area">
<TextControl
placeholder={ __('Search by collection\'s name', 'tainacan') }
label={__('Search for a collection', 'tainacan')}
value={ this.state.searchCollectionName }
onChange={(value) => {
this.setState({
searchCollectionName: value
});
_.debounce(this.fetchCollections(value), 300);
}}/>
<SelectControl
label={__('Order by', 'tainacan')}
value={ this.state.collectionOrderBy }
options={ [
{ label: __('Latest', 'tainacan'), value: 'date-desc' },
{ label: __('Oldest', 'tainacan'), value: 'date' },
{ label: __('Name (A-Z)', 'tainacan'), value: 'title' },
{ label: __('Name (Z-A)', 'tainacan'), value: 'title-desc' }
] }
onChange={ ( aCollectionOrderBy ) => {
this.state.collectionOrderBy = aCollectionOrderBy;
this.state.collectionPage = 1;
this.setState({
collectionOrderBy: this.state.collectionOrderBy,
collectionPage: this.state.collectionPage
});
if (this.state.searchCollectionName && this.state.searchCollectionName != '') {
this.fetchCollections(this.state.searchCollectionName);
} else {
this.fetchModalCollections();
}
}}/>
</div>
{(
this.state.searchCollectionName != '' ? (
this.state.collections.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryCollectionId }
options={
this.state.collections.map((collection) => {
return { label: collection.name, value: '' + collection.id }
})
}
onChange={ ( aCollectionId ) => {
this.setState({ temporaryCollectionId: aCollectionId });
} } />
}
</div>
</div>
) :
this.state.isLoadingCollections ? (
<Spinner />
) :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no collection found.', 'tainacan') }</p>
</div>
):
this.state.modalCollections.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryCollectionId }
options={
this.state.modalCollections.map((collection) => {
return { label: collection.name, value: '' + collection.id }
})
}
onChange={ ( aCollectionId ) => {
this.setState({ temporaryCollectionId: aCollectionId });
} } />
}
</div>
<div className="modal-loadmore-section">
<p>{ __('Showing', 'tainacan') + " " + this.state.modalCollections.length + " " + __('of', 'tainacan') + " " + this.state.totalModalCollections + " " + __('collections', 'tainacan') + "."}</p>
{
this.state.modalCollections.length < this.state.totalModalCollections ? (
<Button
isDefault
isSmall
onClick={ () => this.fetchModalCollections() }>
{__('Load more', 'tainacan')}
</Button>
) : null
}
</div>
</div>
) : this.state.isLoadingCollections ? <div class="spinner-container"><Spinner /></div> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no collection found.', 'tainacan') }</p>
</div>
)}
<div className="modal-footer-area">
<Button
isDefault
onClick={ () => { this.cancelSelection() }}>
{__('Cancel', 'tainacan')}
</Button>
<Button
isPrimary
disabled={ this.state.temporaryCollectionId == undefined || this.state.temporaryCollectionId == null || this.state.temporaryCollectionId == ''}
onClick={ () => this.selectCollection(this.state.temporaryCollectionId) }>
{__('Use selected Collection', 'tainacan')}
</Button>
{
this.state.isLoadingItems ? (
<Spinner />
) : null
}
</div>
</div>
</Modal>
)
}
}

View File

@ -0,0 +1,344 @@
@import '../../gutenberg-blocks-style.scss';
.wp-block-tainacan-faceted-search {
margin: 2em auto;
// Spinner
.spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: #555758;
}
// Skeleton loading
@-webkit-keyframes skeleton-animation {
0%{opacity: 1.0}
50%{opacity: 0.2}
100%{opacity: 1.0}
}
@-moz-keyframes skeleton-animation {
0%{opacity: 1.0}
50%{opacity: 0.2}
100%{opacity: 1.0}
}
@-o-keyframes skeleton-animation {
0%{opacity: 1.0}
50%{opacity: 0.2}
100%{opacity: 1.0}
}
@keyframes skeleton-animation {
0%{opacity: 1.0}
50%{opacity: 0.2}
100%{opacity: 1.0}
}
.skeleton {
border-radius: 2px;
background: #f2f2f2;
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite;
}
.preview-warning {
width: 100%;
font-size: 0.875em;
font-style: italic;
color: #898d8f;
text-align: center;
margin: 4px auto;
}
.items-list-placeholder {
font-size: 1.125em;
min-height: 400px;
width: 100%;
display: flex;
flex-wrap: nowrap;
flex-direction: column;
border-radius: 4px;
border: 1px solid rgba(200,200,200, 0.3);
overflow: hidden;
.search-control,
.filters,
.items,
.pagination {
background-color: var(--tainacan-background-color, white);
border: 1px solid rgba(200,200,200, 0.3);
padding: 12px;
margin: 0px;
border-radius: 1px;
}
.search-control {
flex: 0 0 15%;
display: flex;
justify-content: space-between;
align-items: center;
}
.below-search-control {
position: relative;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
flex: 1 0 auto;
.filters {
flex: 0 1 var(--tainacan-filter-menu-width-theme, 20%);
display: flex;
flex-direction: column;
padding: 40px 20px 60px 15px;
.fake-filter {
display: flex;
flex-direction: column;
width: 80%;
margin: 4% 12%;
.fake-text {
margin: 4px 0;
width: 35%;
background-color: var(--tainacan-label-color, rgba(200,200,200, 0.2));
}
.fake-searchbar {
width: 100%;
}
.fake-checkbox-list {
&>div {
width: 100%;
display: flex;
align-items: center;
&:nth-child(odd) .fake-text {
width: 60%;
}
}
.fake-checkbox {
display: block;
width: 0.4em;
height: 0.4em;
min-width: 0.4em;
min-height: 0.4em;
max-width: 0.4em;
max-height: 0.4em;
border: 2px solid var(--tainacan-input-border-color, rgba(200,200,200, 0.3));
border-radius: 2px;
margin-right: 4px;
}
.fake-text {
background-color: var(--tainacan-input-color, rgba(200,200,200, 0.3));
width: 54%;
}
.fake-link {
width: 25%;
margin: 3px;
}
}
}
.fake-filters-heading {
position: relative;
top: -1.3em;
left: -0.3em;
background-color: var(--tainacan-heading-color, rgba(200,200,200, 0.3));
height: 0.2em;
width: 28%;
border-radius: 2px;
}
}
.aside-filters {
display: flex;
flex-wrap: nowrap;
flex-direction: column;
flex: 1 1 auto;
.items {
flex: 1 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-content: flex-start;
}
.pagination {
flex: 0 1 5%;
display: flex;
justify-content: space-between;
align-items: center;
&>.fake-text {
background-color: var(--tainacan-info-color, rgba(200,200,200, 0.2));
}
}
}
}
.fake-text {
background-color: var(--tainacan-input-color, rgba(200,200,200, 0.3));
height: 0.2em;
width: 24%;
min-width: 1.25em;
border-radius: 2px;
}
.fake-link {
background-color: var(--tainacan-secondary, rgba(200,200,200, 0.3));
height: 0.2em;
width: 10%;
border-radius: 2px;
}
.fake-icon {
background-color: var(--tainacan-info-color, rgba(200,200,200, 0.3));
height: 0.3em;
width: 0.3em;
min-height: 0.3em;
min-width: 0.3em;
max-height: 0.3em;
max-width: 0.3em;
border-radius: 5px;
}
.fake-tooltip {
background-color: var(--tainacan-primary, rgba(200,200,200, 0.1));
position: absolute;
height: 0.75em;
width: 4em;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
top: -0.75em;
left: 1em;
.fake-link {
width: 100%;
margin: 0 4px 0 8px;
}
&:before {
content: "";
display: block;
position: absolute;
left: 12px;
width: 0;
height: 0;
border-style: solid;
}
&:before {
border-color: var(--tainacan-primary) transparent transparent transparent;
border-right-width: 7px;
border-top-width: 6px;
border-left-width: 7px;
bottom: -8px;
}
}
.fake-searchbar {
background-color: var(--tainacan-input-background-color, rgba(200,200,200, 0.3));
height: 0.8em;
width: 18%;
border: 2px solid var(--tainacan-input-border-color, rgba(200,200,200, 0.3));
border-radius: 3px;
.fake-advanced-searchbar {
display: block;
background-color: var(--tainacan-secondary, rgba(200,200,200, 0.3));
height: 0.2em;
border-radius: 3px;
width: 70%;
position: relative;
bottom: -0.85em;
}
}
.fake-hide-button {
display: flex;
justify-content: center;
align-items: center;
background-color: var(--tainacan-primary, rgba(200,200,200, 0.1));
height: 0.9em;
width: 0.9em;
font-size: 0.75em;
border-radius: 3px;
position: absolute;
left: 0px;
top: 42px;
.fake-icon {
background-color: var(--tainacan-secondary, rgba(200,200,200, 0.3));
}
}
.fake-button {
background-color: var(--tainacan-background-color, white);
height: 0.8em;
width: 10%;
max-width: 3.25em;
min-width: 1em;
margin-left: 6px;
border-radius: 3px;
display: flex;
align-items: center;
.fake-text {
background-color: var(--tainacan-input-color, rgba(200,200,200, 0.3));
width: 95%;
margin: 0 2px;
}
.fake-icon {
flex: 1 0 auto;
margin: 0 2px;
}
}
.fake-buttons-group {
flex: 0 0 15%;
display: flex;
justify-content: space-evenly;
}
.fake-item {
background-color: var(--tainacan-item-background-color, white);
flex: 1 0 180px;
margin: 12px;
height: 78px;
&.fake-item-hovered,
&:hover {
background-color: var(--tainacan-item-hover-background-color, rgba(200,200,200, 0.2));
.fake-item-header {
background-color: var(--tainacan-item-heading-hover-background-color, rgba(200,200,200, 0.3));
}
}
.fake-item-header {
height: 20px;
width: 100%;
position: relative;
top: 0;
display: flex;
align-items: center;
padding: 6px;
.fake-text {
background-color: var(--tainacan-heading-color, rgba(200,200,200, 0.35));
}
}
.fake-item-thumb {
background-size: cover;
background-color: var(--tainacan-input-border-color, rgba(200,200,200, 0.1));
height: 58px;
width: 58px;
float: left;
}
.fake-item-description {
background-color: var(--tainacan-info-color, rgba(200,200,200, 0.15));
height: 0.18em;
width: 60%;
border-radius: 2px;
margin: 8px 6px 2px 6px;
position: relative;
left: 62px;
&:nth-child(odd) {
width: 50%;
}
}
}
}
.theme-items-list {
max-width: 100% !important;
}
}

View File

@ -0,0 +1,932 @@
const { registerBlockType } = wp.blocks;
const { __ } = wp.i18n;
const { Button, ColorPicker, BaseControl, RangeControl, FontSizePicker, HorizontalRule, SelectControl, ToggleControl, Placeholder, PanelBody } = wp.components;
const { InspectorControls } = wp.editor;
import CollectionModal from './collection-modal.js';
import TermModal from './term-modal.js';
registerBlockType('tainacan/faceted-search', {
title: __('Tainacan Faceted Search', 'tainacan'),
icon:
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
height="24px"
width="24px">
<path
fill="#298596"
d="M21.43,13.64,19.32,16a2.57,2.57,0,0,1-2,1H11a3.91,3.91,0,0,0,0-.49,5.49,5.49,0,0,0-5-5.47V9.64A2.59,2.59,0,0,1,8.59,7H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,13.64ZM4,3A2,2,0,0,0,2,5v7.3a5.32,5.32,0,0,1,2-1V5H16V3ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1,0-7,2.74,2.74,0,0,1,.5,0A3.5,3.5,0,0,1,9,16a2.92,2.92,0,0,1,0,.51,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,1,0,5.5,18,1.5,1.5,0,0,0,7,16.53Z"/>
</svg>,
category: 'tainacan-blocks',
keywords: [ __( 'facets', 'tainacan' ), __( 'search', 'tainacan' ), __( 'items', 'tainacan' ) ],
description: __('A full items list faceted search from either the repository, a collection or a term.', 'tainacan'),
attributes: {
termId: {
type: String,
default: undefined
},
taxonomyId: {
type: String,
default: undefined
},
collectionId: {
type: String,
default: undefined
},
defaultViewMode: {
type: String,
default: 'masonry'
},
enabledViewModes: {
type: Array,
default: [ 'cards', 'masonry', 'table' ]
},
hideFilters: {
type: Boolean,
default: false
},
hideHideFiltersButton: {
type: Boolean,
default: false
},
hideSearch: {
type: Boolean,
default: false
},
hideAdvancedSearch: {
type: Boolean,
default: false
},
hideSortByButton: {
type: Boolean,
default: false
},
hideExposersButton: {
type: Boolean,
default: false
},
hideItemsPerPageButton: {
type: Boolean,
default: false
},
hideGoToPageButton: {
type: Boolean,
default: false
},
showFiltersButtonInsideSearchControl: {
type: Boolean,
default: false
},
startWithFiltersHidden: {
type: Boolean,
default: false
},
filtersAsModal: {
type: Boolean,
default: false
},
showInlineViewModeOptions: {
type: Boolean,
default: false
},
showFullscreenWithViewModes: {
type: Boolean,
default: false
},
listType: {
type: String,
default: 'collection'
},
isCollectionModalOpen: {
type: Boolean,
default: false
},
isTermModalOpen: {
type: Boolean,
default: false
},
backgroundColor: {
type: String,
default: '#ffffff'
},
baseFontSize: {
type: Number,
default: 16
},
filtersAreaWidth: {
type: Number,
default: 20
},
inputColor: {
type: String,
default: '#1d1d1d'
},
inputBackgroundColor: {
type: String,
default: '#ffffff'
},
inputBorderColor: {
type: String,
default: '#dbdbdb'
},
labelColor: {
type: String,
default: '#454647'
},
infoColor: {
type: String,
default: '#555758'
},
headingColor: {
type: String,
default: '#000000'
},
skeletonColor: {
type: String,
default: '#eeeeee'
},
itemBackgroundColor: {
type: String,
default: '#ffffff'
},
itemHoverBackgroundColor: {
type: String,
default: '#f2f2f2'
},
itemHeadingHoverBackgroundColor: {
type: String,
default: '#dbdbdb'
},
primaryColor: {
type: String,
default: '#d9eced'
},
secondaryColor: {
type: String,
default: '#298596'
}
},
supports: {
align: ['full', 'wide'],
html: true,
multiple: false
},
edit({ attributes, setAttributes, className, isSelected, clientId }){
let {
termId,
taxonomyId,
collectionId,
defaultViewMode,
enabledViewModes,
hideFilters,
hideHideFiltersButton,
hideSearch,
hideAdvancedSearch,
hideSortByButton,
hideExposersButton,
hideItemsPerPageButton,
hideGoToPageButton,
showFiltersButtonInsideSearchControl,
startWithFiltersHidden,
filtersAsModal,
showInlineViewModeOptions,
showFullscreenWithViewModes,
listType,
isCollectionModalOpen,
isTermModalOpen,
backgroundColor,
baseFontSize,
filtersAreaWidth,
inputColor,
inputBackgroundColor,
inputBorderColor,
labelColor,
infoColor,
headingColor,
skeletonColor,
itemBackgroundColor,
itemHoverBackgroundColor,
itemHeadingHoverBackgroundColor,
primaryColor,
secondaryColor
} = attributes;
const fontSizes = [
{
name: __( 'Tiny', 'tainacan' ),
slug: 'tiny',
size: 12,
},
{
name: __( 'Small', 'tainacan' ),
slug: 'small',
size: 14,
},
{
name: __( 'Normal', 'tainacan' ),
slug: 'normal',
size: 16,
},
{
name: __( 'Big', 'tainacan' ),
slug: 'big',
size: 18,
},
{
name: __( 'Huge', 'tainacan' ),
slug: 'huge',
size: 20,
},
];
function openCollectionModal() {
isCollectionModalOpen = true;
setAttributes( {
isCollectionModalOpen: isCollectionModalOpen
} );
}
function openTermModal() {
isTermModalOpen = true;
setAttributes( {
isTermModalOpen: isTermModalOpen
} );
}
return (
<div className={className}>
<div>
<InspectorControls>
<PanelBody
title={__('Search Control Area', 'tainacan')}
initialOpen={ true }
>
<ToggleControl
label={__('Hide search input', 'tainacan')}
help={ hideSearch ? __('Do not show textual search input', 'tainacan') : __('Toggle to show textual search input', 'tainacan')}
checked={ hideSearch }
onChange={ ( isChecked ) => {
hideSearch = isChecked;
setAttributes({ hideSearch: isChecked });
}
}
/>
<ToggleControl
label={__('Hide advanced search', 'tainacan')}
help={ hideAdvancedSearch || hideSearch ? __('Do not show advanced search', 'tainacan') : __('Toggle to show advanced search', 'tainacan')}
checked={ hideAdvancedSearch || hideSearch }
onChange={ ( isChecked ) => {
hideAdvancedSearch = isChecked;
setAttributes({ hideAdvancedSearch: isChecked });
}
}
/>
<ToggleControl
label={__('Hide "Sort By" button', 'tainacan')}
help={ hideSortByButton ? __('Do not show "Sort By" button', 'tainacan') : __('Toggle to show "Sort By" button', 'tainacan')}
checked={ hideSortByButton }
onChange={ ( isChecked ) => {
hideSortByButton = isChecked;
setAttributes({ hideSortByButton: isChecked });
}
}
/>
<ToggleControl
label={__('Show inline View Mode options', 'tainacan')}
help={ showInlineViewModeOptions ? __('Toggle to show View Mode options inline instead of a dropdown', 'tainacan') : __('Keep view mode options as a dropdown', 'tainacan')}
checked={ showInlineViewModeOptions }
onChange={ ( isChecked ) => {
showInlineViewModeOptions = isChecked;
setAttributes({ showInlineViewModeOptions: isChecked });
}
}
/>
<ToggleControl
label={__('Show Fullscreen with other View Modes', 'tainacan')}
help={ showFullscreenWithViewModes ? __('Toggle to show Fullscreen view mode alongside with other View Modes', 'tainacan') : __('Keep Fullscreen view mode separated from other View Mode Options', 'tainacan')}
checked={ showFullscreenWithViewModes }
onChange={ ( isChecked ) => {
showFullscreenWithViewModes = isChecked;
setAttributes({ showFullscreenWithViewModes: isChecked });
}
}
/>
<ToggleControl
label={__('Hide "View as..." button', 'tainacan')}
help={ hideExposersButton ? __('Do not show "View as...", the "Exposers" button', 'tainacan') : __('Toggle to show "View as...", the "Exposers" button', 'tainacan')}
checked={ hideExposersButton }
onChange={ ( isChecked ) => {
hideExposersButton = isChecked;
setAttributes({ hideExposersButton: isChecked });
}
}
/>
<ToggleControl
label={__('Show "Filters" button inside the Search Control', 'tainacan')}
help={ showFiltersButtonInsideSearchControl ? __('Toggle to show Filters button inside the Search Control, instead of floating left', 'tainacan') : __('Keep Filters button as a floating arrow on the left', 'tainacan')}
checked={ showFiltersButtonInsideSearchControl }
onChange={ ( isChecked ) => {
showFiltersButtonInsideSearchControl = isChecked;
setAttributes({ showFiltersButtonInsideSearchControl: isChecked });
}
}
/>
</PanelBody>
<PanelBody
title={__('Filters Area', 'tainacan')}
initialOpen={ true }
>
<ToggleControl
label={__('Hide Filters', 'tainacan')}
help={ hideFilters ? __('Do not show Filters with the list', 'tainacan') : __('Toggle to show Filters with the list', 'tainacan')}
checked={ hideFilters }
onChange={ ( isChecked ) => {
hideFilters = isChecked;
setAttributes({ hideFilters: isChecked });
}
}
/>
<ToggleControl
label={__('Hide "Hide Filters" button', 'tainacan')}
help={ hideHideFiltersButton || hideFilters ? __('Do not show "Hide Filters" button', 'tainacan') : __('Toggle to show "Hide Filters" button', 'tainacan')}
checked={ hideHideFiltersButton || hideFilters }
onChange={ ( isChecked ) => {
hideHideFiltersButton = isChecked;
setAttributes({ hideHideFiltersButton: isChecked });
}
}
/>
<ToggleControl
label={__('Start with Filters hidden', 'tainacan')}
help={ startWithFiltersHidden ? __('Render the list with filters hidden at first" button', 'tainacan') : __('Toggle to render the list with filters visible at first', 'tainacan')}
checked={ startWithFiltersHidden }
onChange={ ( isChecked ) => {
startWithFiltersHidden = isChecked;
setAttributes({ startWithFiltersHidden: isChecked });
}
}
/>
<ToggleControl
label={__('Filters as a Modal', 'tainacan')}
help={ filtersAsModal ? __('Render the filters area as modal instead of a collapse" button', 'tainacan') : __('Toggle to show filters list as a collapse instead of a modal', 'tainacan')}
checked={ filtersAsModal }
onChange={ ( isChecked ) => {
filtersAsModal = isChecked;
setAttributes({ filtersAsModal: isChecked });
}
}
/>
</PanelBody>
<PanelBody
title={__('Pagination Area', 'tainacan')}
initialOpen={ true }
>
<ToggleControl
label={__('Hide "Items per Page" button', 'tainacan')}
help={ hideItemsPerPageButton ? __('Do not show "Items per Page" button', 'tainacan') : __('Toggle to show "Items per Page" button', 'tainacan')}
checked={ hideItemsPerPageButton }
onChange={ ( isChecked ) => {
hideItemsPerPageButton = isChecked;
setAttributes({ hideItemsPerPageButton: isChecked });
}
}
/>
<ToggleControl
label={__('Hide "Go to Page" button', 'tainacan')}
help={ hideGoToPageButton ? __('Do not show "Go to Page" button', 'tainacan') : __('Toggle to show "Go to Page" button', 'tainacan')}
checked={ hideGoToPageButton }
onChange={ ( isChecked ) => {
hideGoToPageButton = isChecked;
setAttributes({ hideGoToPageButton: isChecked });
}
}
/>
</PanelBody>
<PanelBody
title={__('Colors and Sizes', 'tainacan')}
initialOpen={ false }
>
<FontSizePicker
fontSizes={ fontSizes }
value={ baseFontSize }
fallbackFontSize={ 16 }
onChange={ ( newFontSize ) => {
setAttributes( { baseFontSize: newFontSize } );
} }
/>
<RangeControl
label={ __('Filters Area Width (%)', 'tainacan') }
value={ filtersAreaWidth }
onChange={ ( width ) => setAttributes( { filtersAreaWidth: width } ) }
min={ 10 }
max={ 40 }
/>
<HorizontalRule />
<BaseControl
id="backgroundColorPicker"
label={ __('Background color', 'tainacan')}
help={ __('The background color of the entire items list', 'tainacan') }>
<ColorPicker
color={ backgroundColor }
onChangeComplete={ (colorValue ) => {
backgroundColor = colorValue.hex;
setAttributes({ backgroundColor: backgroundColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="secondaryColorPicker"
label={ __('Link and Active Main color', 'tainacan')}
help={ __('The text color links and other action or active state elements, such as select arrows, tooltip contents, etc', 'tainacan') }>
<ColorPicker
color={ secondaryColor }
onChangeComplete={ (colorValue ) => {
secondaryColor = colorValue.hex;
setAttributes({ secondaryColor: secondaryColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="primaryColorPicker"
label={ __('Tooltips background color', 'tainacan')}
help={ __('The tooltips background color and other elements, such as the hide filters button', 'tainacan') }>
<ColorPicker
color={ primaryColor }
onChangeComplete={ (colorValue ) => {
primaryColor = colorValue.hex;
setAttributes({ primaryColor: primaryColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="inputBackgroundColorPicker"
label={ __('Input Background color', 'tainacan')}
help={ __('The background color for input fields', 'tainacan') }>
<ColorPicker
color={ inputBackgroundColor }
onChangeComplete={ (colorValue ) => {
inputBackgroundColor = colorValue.hex;
setAttributes({ inputBackgroundColor: inputBackgroundColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="inputColorPicker"
label={ __('Input Text color', 'tainacan')}
help={ __('The text color for input fields, including dropdowns and buttons', 'tainacan') }>
<ColorPicker
color={ inputColor }
onChangeComplete={ (colorValue ) => {
inputColor = colorValue.hex;
setAttributes({ inputColor: inputColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="inputBorderColorPicker"
label={ __('Input Border color', 'tainacan')}
help={ __('The border color for input fields', 'tainacan') }>
<ColorPicker
color={ inputBorderColor }
onChangeComplete={ (colorValue ) => {
inputBorderColor = colorValue.hex;
setAttributes({ inputBorderColor: inputBorderColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="labelColorPicker"
label={ __('Label Text color', 'tainacan')}
help={ __('The text color for field labels', 'tainacan') }>
<ColorPicker
color={ labelColor }
onChangeComplete={ (colorValue ) => {
labelColor = colorValue.hex;
setAttributes({ labelColor: labelColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="headingColorPicker"
label={ __('Headings Text color', 'tainacan')}
help={ __('The text color for headings such as items title and filters menu header', 'tainacan') }>
<ColorPicker
color={ headingColor }
onChangeComplete={ (colorValue ) => {
headingColor = colorValue.hex;
setAttributes({ headingColor: headingColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="infoColorPicker"
label={ __('General Info Text color', 'tainacan')}
help={ __('The text color for other information such as item metadata, icons, number of pages, etc', 'tainacan') }>
<ColorPicker
color={ infoColor }
onChangeComplete={ (colorValue ) => {
infoColor = colorValue.hex;
setAttributes({ infoColor: infoColor });
}}
disableAlpha
/>
</BaseControl>
<BaseControl
id="itemBackgroundColorPicker"
label={ __('Item Background color', 'tainacan')}
help={ __('The background color for an item on the list', 'tainacan') }>
<ColorPicker
color={ itemBackgroundColor }
onChangeComplete={ (colorValue ) => {
itemBackgroundColor = colorValue.hex;
setAttributes({ itemBackgroundColor: itemBackgroundColor });
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="itemHoverBackgroundColorPicker"
label={ __('Item Hover Background color', 'tainacan')}
help={ __('The background color for an item on the list, when hovered', 'tainacan') }>
<ColorPicker
color={ itemHoverBackgroundColor }
onChangeComplete={ (colorValue ) => {
itemHoverBackgroundColor = colorValue.hex;
skeletonColor = colorValue.hex;
setAttributes({
itemHoverBackgroundColor: itemHoverBackgroundColor,
skeletonColor: skeletonColor
});
}}
disableAlpha
/>
</BaseControl>
<HorizontalRule />
<BaseControl
id="itemHeadingHoverBackgroundColorPicker"
label={ __('Item Heading Hover Background color', 'tainacan')}
help={ __('The background color for the item heading (where the title is), when hovered', 'tainacan') }>
<ColorPicker
color={ itemHeadingHoverBackgroundColor }
onChangeComplete={ (colorValue ) => {
itemHeadingHoverBackgroundColor = colorValue.hex;
setAttributes({ itemHeadingHoverBackgroundColor: itemHeadingHoverBackgroundColor });
}}
disableAlpha
/>
</BaseControl>
</PanelBody>
</InspectorControls>
</div>
{ isSelected ?
(
<div>
<div className="block-control">
<p style={{ display: 'flex', alignItems: 'baseline' }}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
height="24px"
width="24px">
<path
fill="#298596"
d="M21.43,13.64,19.32,16a2.57,2.57,0,0,1-2,1H11a3.91,3.91,0,0,0,0-.49,5.49,5.49,0,0,0-5-5.47V9.64A2.59,2.59,0,0,1,8.59,7H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,13.64ZM4,3A2,2,0,0,0,2,5v7.3a5.32,5.32,0,0,1,2-1V5H16V3ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1,0-7,2.74,2.74,0,0,1,.5,0A3.5,3.5,0,0,1,9,16a2.92,2.92,0,0,1,0,.51,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,1,0,5.5,18,1.5,1.5,0,0,0,7,16.53Z"/>
</svg>
{__('Show items list from: ', 'tainacan')}
&nbsp;
<SelectControl
label={ __('Items list source', 'tainacan') }
hideLabelFromVision
value={ listType }
options={ [
{ label: __('a Collection', 'tainacan'), value: 'collection' },
{ label: __('a Taxonomy Term', 'tainacan'), value: 'term' },
{ label: __('the Repository', 'tainacan'), value: 'repository' },
] }
onChange={ ( aListType) => {
listType = aListType;
setAttributes({ listType: aListType });
} }
/>
&nbsp;
{
(listType == 'collection' && collectionId != undefined) || (listType == 'term' && termId != undefined) ?
<Button
isPrimary
type="submit"
onClick={ () => listType == 'term' ? openTermModal() : openCollectionModal() }>
{ listType == 'term' ? __('Change Term', 'tainacan') : __('Change Collection', 'tainacan') }
</Button>
: null
}
</p>
</div>
</div>
) : null
}
{ ( termId == undefined && listType == 'term' ) || ( collectionId == undefined && listType == 'collection' ) ? (
<Placeholder
icon={(
<img
width={148}
src={ `${tainacan_blocks.base_url}/assets/images/tainacan_logo_header.svg` }
alt="Tainacan Logo"/>
)}>
<p>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
height="24px"
width="24px">
<path
fill="#298596"
d="M21.43,13.64,19.32,16a2.57,2.57,0,0,1-2,1H11a3.91,3.91,0,0,0,0-.49,5.49,5.49,0,0,0-5-5.47V9.64A2.59,2.59,0,0,1,8.59,7H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,13.64ZM4,3A2,2,0,0,0,2,5v7.3a5.32,5.32,0,0,1,2-1V5H16V3ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1,0-7,2.74,2.74,0,0,1,.5,0A3.5,3.5,0,0,1,9,16a2.92,2.92,0,0,1,0,.51,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,1,0,5.5,18,1.5,1.5,0,0,0,7,16.53Z"/>
</svg>
{__('Show a complete items list with faceted search.', 'tainacan')}
</p>
<Button
isPrimary
type="submit"
onClick={ () => listType == 'term' ? openTermModal() : openCollectionModal() }>
{ listType == 'term' ? __('Select a Term', 'tainacan') : __('Select a Collection', 'tainacan') }
</Button>
</Placeholder>
) :
(
<div style={{ fontSize: (baseFontSize - 2) + 'px' }}>
<div class="preview-warning">
{ __('Warning: this is just a demonstration. To see the items list, either preview or publish your post.', 'tainacan') }
</div>
<div
style={{
'--tainacan-background-color': backgroundColor,
'--tainacan-filter-menu-width-theme': filtersAreaWidth + '%',
'--tainacan-input-color': inputColor,
'--tainacan-input-background-color': inputBackgroundColor,
'--tainacan-input-border-color': inputBorderColor,
'--tainacan-label-color': labelColor,
'--tainacan-info-color': infoColor,
'--tainacan-heading-color': headingColor,
'--tainacan-skeleton-color': skeletonColor,
'--tainacan-item-background-color': itemBackgroundColor,
'--tainacan-item-hover-background-color': itemHoverBackgroundColor,
'--tainacan-item-heading-hover-background-color': itemHeadingHoverBackgroundColor,
'--tainacan-primary': primaryColor,
'--tainacan-secondary': secondaryColor
}}
class="items-list-placeholder">
<div class="search-control">
{
!hideSearch ?
<span class="fake-searchbar">
{ !hideAdvancedSearch ? <span class="fake-advanced-searchbar"></span> : null }
</span>
: null
}
{
showFiltersButtonInsideSearchControl && !hideHideFiltersButton ? <span class="fake-button"><div class="fake-icon"></div><div class="fake-text"></div></span> : null
}
<span class="fake-button"><div class="fake-text"></div></span>
<span class="fake-button"> { !hideSortByButton ? <div class="fake-text"></div> : null }<div class="fake-icon"></div><div class="fake-text"></div></span>
{
!showInlineViewModeOptions ?
<span class="fake-button"><div class="fake-icon"></div><div class="fake-text"></div></span>
:
<div class="fake-buttons-group">
{ Array(3).fill().map( () => <div class="fake-button"><div class="fake-icon"></div></div> )}
{ showFullscreenWithViewModes ? <span class="fake-button"><div class="fake-icon"></div></span> : null }
</div>
}
{
!showFullscreenWithViewModes ? <span class="fake-button"><div class="fake-icon"></div><div class="fake-text"></div></span> : null
}
{
!hideExposersButton ? <span class="fake-button"><div class="fake-icon"></div><div class="fake-text"></div></span> : null
}
</div>
<div class="below-search-control">
{ !showFiltersButtonInsideSearchControl & !hideHideFiltersButton && !hideFilters ? <span class="fake-hide-button"><div class="fake-icon"></div></span> : null }
{
!hideFilters && !filtersAsModal && !startWithFiltersHidden ?
<div
style={{
flexBasis: filtersAreaWidth + '%'
}}
class="filters">
<div class="fake-filters-heading"></div>
{ Array(2).fill().map( () => {
return <div class="fake-filter">
<span class="fake-text"></span>
<span class="fake-searchbar"></span>
</div>
} )}
<div class="fake-filter">
<span class="fake-text"></span>
<div class="fake-checkbox-list">
{ Array(4).fill().map( () => {
return <div>
<span class="fake-checkbox"></span>
<span class="fake-text"></span>
</div>
} ) }
<div class="fake-link"></div>
</div>
</div>
<div class="fake-filter">
<span class="fake-text"></span>
<span class="fake-searchbar"></span>
</div>
</div>
: null
}
<div class="aside-filters">
<div class="items">
{ Array(5).fill().map( () => {
return <div class="fake-item">
<div class="fake-item-header">
<div class="fake-text"></div>
</div>
<div
style={{
backgroundImage: tainacan_plugin ? 'url("' + tainacan_plugin.base_url + '/assets/images/placeholder_square.png")' : ''
}}
class="fake-item-thumb"></div>
{ Array(3).fill().map( () => <div class="fake-item-description"></div> ) }
</div>
} ) }
<div class="fake-item fake-item-hovered">
<div class="fake-item-header">
<div class="fake-tooltip"><div class="fake-link"></div></div>
<div class="fake-text"></div>
</div>
<div
style={{
backgroundImage: tainacan_plugin ? 'url("' + tainacan_plugin.base_url + '/assets/images/placeholder_square.png")' : ''
}}
class="fake-item-thumb"></div>
{ Array(3).fill().map( () => <div class="fake-item-description"></div> ) }
</div>
</div>
<div class="pagination">
<span class="fake-text"></span>
{ !hideItemsPerPageButton ? <span class="fake-button"><div class="fake-text"></div></span> : null }
{ !hideGoToPageButton ? <span class="fake-button"><div class="fake-text"></div></span> : null }
<div class="fake-buttons-group">
{ Array(6).fill().map( () => <div class="fake-link"></div> ) }
</div>
</div>
</div>
</div>
</div>
</div>
)
}
{ isCollectionModalOpen ?
<CollectionModal
existingCollectionId={ collectionId }
onSelectCollection={ (selectedCollectionId) => {
collectionId = selectedCollectionId;
setAttributes({
collectionId: collectionId,
isCollectionModalOpen: false
});
}}
onCancelSelection={ () => setAttributes({ isCollectionModalOpen: false }) }/>
: null
}
{ isTermModalOpen ?
<TermModal
existingTermId={ termId }
existingTaxonomyId={ taxonomyId }
onSelectTaxonomy={ (selectedTaxonomy) => {
taxonomyId = selectedTaxonomy;
setAttributes({ taxonomyId: selectedTaxonomy });
}}
onSelectTerm={ (selectedTermId) => {
termId = selectedTermId;
setAttributes({
termId: selectedTermId,
isTermModalOpen: false
});
}}
onCancelSelection={ () => setAttributes({ isTermModalOpen: false }) }/>
: null
}
</div>
);
},
save({ attributes, className }){
const {
termId,
taxonomyId,
collectionId,
defaultViewMode,
enabledViewModes,
hideFilters,
hideHideFiltersButton,
hideSearch,
hideAdvancedSearch,
hideSortByButton,
hideExposersButton,
hideItemsPerPageButton,
hideGoToPageButton,
showFiltersButtonInsideSearchControl,
startWithFiltersHidden,
filtersAsModal,
showInlineViewModeOptions,
showFullscreenWithViewModes,
listType,
backgroundColor,
baseFontSize,
filtersAreaWidth,
inputColor,
inputBackgroundColor,
inputBorderColor,
labelColor,
infoColor,
headingColor,
skeletonColor,
itemBackgroundColor,
itemHoverBackgroundColor,
itemHeadingHoverBackgroundColor,
primaryColor,
secondaryColor
} = attributes;
return <div
style={{
'font-size': baseFontSize + 'px',
'--tainacan-base-font-size': baseFontSize + 'px',
'--tainacan-background-color': backgroundColor,
'--tainacan-filter-menu-width-theme': filtersAreaWidth + '%',
'--tainacan-input-color': inputColor,
'--tainacan-input-background-color': inputBackgroundColor,
'--tainacan-input-border-color': inputBorderColor,
'--tainacan-label-color': labelColor,
'--tainacan-info-color': infoColor,
'--tainacan-heading-color': headingColor,
'--tainacan-skeleton-color': skeletonColor,
'--tainacan-item-background-color': itemBackgroundColor,
'--tainacan-item-hover-background-color': itemHoverBackgroundColor,
'--tainacan-item-heading-hover-background-color': itemHeadingHoverBackgroundColor,
'--tainacan-primary': primaryColor,
'--tainacan-secondary': secondaryColor
}}
className={ className }>
<main
term-id={ listType == 'term' ? termId : null }
taxonomy={ listType == 'term' ? 'tnc_tax_' + taxonomyId : null }
collection-id={ listType == 'collection' ? collectionId : null }
default-view-mode={ defaultViewMode }
enabled-view-modes={ enabledViewModes.toString() }
hide-filters = { hideFilters.toString() }
hide-hide-filters-button= { hideHideFiltersButton.toString() }
hide-search = { hideSearch.toString() }
hide-advanced-search = { hideAdvancedSearch.toString() }
hide-sort-by-button = { hideSortByButton.toString() }
hide-exposers-button = { hideExposersButton.toString() }
hide-items-per-page-button = { hideItemsPerPageButton.toString() }
hide-go-to-page-button = { hideGoToPageButton.toString() }
show-filters-button-inside-search-control = { showFiltersButtonInsideSearchControl.toString() }
start-with-filters-hidden = { startWithFiltersHidden.toString() }
filters-as-modal = { filtersAsModal.toString() }
show-inline-view-mode-options = { showInlineViewModeOptions.toString() }
show-fullscreen-with-view-modes = { showFullscreenWithViewModes.toString() }
id="tainacan-items-page">
</main>
</div>
}
});

View File

@ -0,0 +1,509 @@
import tainacan from '../../js/axios.js';
const { __ } = wp.i18n;
const { TextControl, Button, Modal, SelectControl, RadioControl, Spinner } = wp.components;
export default class TermModal extends React.Component {
constructor(props) {
super(props);
// Initialize state
this.state = {
modalTerms: [],
totalModalTerms: 0,
termsPerPage: 24,
termOrder: 'asc',
searchTermName: '',
temporarySelectedTermId: '',
terms: [],
isLoadingTerms: false,
taxonomyId: undefined,
taxonomyName: '',
isLoadingTaxonomies: false,
modalTaxonomies: [],
taxonomyOrderBy: 'date-desc',
totalModalTaxonomies: 0,
taxonomyPage: 1,
temporaryTaxonomyId: '',
searchTaxonomyName: '',
taxonomies: [],
};
// Bind events
this.fetchTerms = this.fetchTerms.bind(this);
this.fetchModalTerms = this.fetchModalTerms.bind(this);
this.selectTemporaryTerm = this.selectTemporaryTerm.bind(this);
this.onSelectTerm = this.onSelectTerm.bind(this);
this.resetTaxonomies = this.resetTaxonomies.bind(this);
this.selectTaxonomy = this.selectTaxonomy.bind(this);
this.fetchTaxonomies = this.fetchTaxonomies.bind(this);
this.fetchModalTaxonomies = this.fetchModalTaxonomies.bind(this);
this.fetchTaxonomy = this.fetchTaxonomy.bind(this);
}
componentWillMount() {
this.setState({
taxonomyId: this.props.existingTaxonomyId,
temporarySelectedTermId: this.props.existingTermId
});
if (this.props.existingTaxonomyId != null && this.props.existingTaxonomyId != undefined) {
this.fetchTaxonomy(this.props.existingTaxonomyId);
this.fetchModalTerms(0, this.props.existingTaxonomyId);
} else {
this.setState({ taxonomyPage: 1 });
this.fetchModalTaxonomies();
}
}
// TERM RELATED --------------------------------------------------
selectTemporaryTerm(termId) {
this.setState({ temporarySelectedTermId: termId });
}
onSelectTerm() {
this.props.onSelectTerm(this.state.temporarySelectedTermId);
}
cancelSelection() {
this.setState({
modalTerms: [],
modalTaxonomies: []
});
this.props.onCancelSelection();
}
fetchTerms(name) {
let endpoint = '/taxonomy/'+ this.state.taxonomyId + '/terms/?order=' + this.state.termOrder + '&hideempty=0&number=' + this.state.termsPerPage;
if (name != undefined && name != '')
endpoint += '&searchterm=' + name;
tainacan.get(endpoint)
.then(response => {
let someTerms = response.data.map((term) => ({
name: term.name,
id: term.id,
url: term.url,
header_image: [{
src: term.header_image,
alt: term.name
}]
}));
this.setState({
isLoadingTerms: false,
terms: someTerms
});
return someTerms;
})
.catch(error => {
console.log('Error trying to fetch terms: ' + error);
});
}
fetchModalTerms(offset, taxonomyId) {
let someModalTerms = this.state.modalTerms;
if (offset <= 0)
someModalTerms = [];
let endpoint = '/taxonomy/'+ taxonomyId + '/terms/?order=' + this.state.termOrder + '&hideempty=0&number=' + this.state.termsPerPage + '&offset=' + offset;
this.setState({
isLoadingTerms: true,
modalTerms: someModalTerms
});
tainacan.get(endpoint)
.then(response => {
let otherModalTerms = this.state.modalTerms;
for (let term of response.data) {
otherModalTerms.push({
name: term.name,
id: term.id,
url: term.url,
header_image: [{
src: term.header_image,
alt: term.name
}]
});
}
this.setState({
isLoadingTerms: false,
modalTerms: otherModalTerms,
totalModalTerms: response.headers['x-wp-total']
});
return otherModalTerms;
})
.catch(error => {
console.log('Error trying to fetch terms: ' + error);
});
}
// TAXONOMY RELATED --------------------------------------------------
fetchModalTaxonomies() {
let someModalTaxonomies = this.state.modalTaxonomies;
if (this.state.taxonomyPage <= 1)
someModalTaxonomies = [];
let endpoint = '/taxonomies/?perpage=' + this.state.termsPerPage + '&paged=' + this.state.taxonomyPage;
if (this.state.taxonomyOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.taxonomyOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.taxonomyOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.taxonomyOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
this.setState({
isLoadingTaxonomies: true,
taxonomyPage: this.state.taxonomyPage + 1,
modalTaxonomies: someModalTaxonomies
});
tainacan.get(endpoint)
.then(response => {
let otherModalTaxonomies = this.state.modalTaxonomies;
for (let taxonomy of response.data) {
otherModalTaxonomies.push({
name: taxonomy.name,
id: taxonomy.id
});
}
this.setState({
isLoadingTaxonomies: false,
modalTaxonomies: otherModalTaxonomies,
totalModalTaxonomies: response.headers['x-wp-total']
});
return otherModalTaxonomies;
})
.catch(error => {
console.log('Error trying to fetch taxonomies: ' + error);
});
}
fetchTaxonomy(taxonomyId) {
tainacan.get('/taxonomies/' + taxonomyId)
.then((response) => {
this.setState({ taxonomyName: response.data.name });
}).catch(error => {
console.log('Error trying to fetch taxonomy: ' + error);
});
}
selectTaxonomy(selectedTaxonomyId) {
this.setState({
taxonomyId: selectedTaxonomyId
});
this.props.onSelectTaxonomy(selectedTaxonomyId);
this.fetchTaxonomy(selectedTaxonomyId);
this.fetchModalTerms(0, selectedTaxonomyId);
}
fetchTaxonomies(name) {
this.setState({
isLoadingTaxonomies: true,
taxonomies: [],
terms: []
});
let endpoint = '/taxonomies/?perpage=' + this.state.termsPerPage;
if (name != undefined && name != '')
endpoint += '&search=' + name;
if (this.state.taxonomyOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.taxonomyOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.taxonomyOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.taxonomyOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
tainacan.get(endpoint)
.then(response => {
let someTaxonomies = response.data.map((taxonomy) => ({ name: taxonomy.name, id: taxonomy.id + '' }));
this.setState({
isLoadingTaxonomies: false,
taxonomies: someTaxonomies
});
return someTaxonomies;
})
.catch(error => {
console.log('Error trying to fetch taxonomies: ' + error);
});
}
resetTaxonomies() {
this.setState({
taxonomyId: null,
taxonomyPage: 1,
modalTaxonomies: []
});
this.fetchModalTaxonomies();
}
render() {
return this.state.taxonomyId != null && this.state.taxonomyId != undefined ? (
// Terms modal
<Modal
className="wp-block-tainacan-modal"
title={__('Select the desired terms from taxonomy ' + this.state.taxonomyName, 'tainacan')}
onRequestClose={ () => this.cancelSelection() }
contentLabel={__('Select terms', 'tainacan')}>
<div>
<div className="modal-search-area">
<TextControl
placeholder={ __('Search by term\'s name', 'tainacan') }
label={__('Search for a term', 'tainacan')}
value={ this.state.searchTermName }
onChange={(value) => {
this.setState({
searchTermName: value
});
_.debounce(this.fetchTerms(value), 300);
}}/>
<SelectControl
label={__('Order', 'tainacan')}
value={ this.state.termOrder }
options={ [
{ label: __('Name (A-Z)', 'tainacan'), value: 'asc' },
{ label: __('Name (Z-A)', 'tainacan'), value: 'desc' }
] }
onChange={ ( atermOrder ) => {
this.state.termOrder = atermOrder;
this.setState({
termOrder: this.state.termOrder
});
if (this.state.searchTermName && this.state.searchTermName != '') {
this.fetchTerms(this.state.searchTermName);
} else {
this.fetchModalTerms(0, this.state.taxonomyId);
}
}}/>
</div>
{(
this.state.searchTermName != '' ? (
this.state.terms.length > 0 ?
(
<div>
<ul className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporarySelectedTermId }
options={
this.state.terms.map((term) => {
return { label: term.name, value: '' + term.id }
})
}
onChange={ ( aTermId ) => {
this.selectTemporaryTerm(aTermId);
} } />
}
</ul>
{ this.state.isLoadingTerms ? <div class="spinner-container"><Spinner /></div> : null }
</div>
)
: this.state.isLoadingTerms ? <div class="spinner-container"><Spinner /></div> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no terms found.', 'tainacan') }</p>
</div>
) :
this.state.modalTerms.length > 0 ?
(
<div>
<ul className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporarySelectedTermId }
options={
this.state.modalTerms.map((term) => {
return { label: term.name, value: '' + term.id }
})
}
onChange={ ( aTermId ) => {
this.selectTemporaryTerm(aTermId);
} } />
}
</ul>
{ this.state.isLoadingTerms ? <div class="spinner-container"><Spinner /></div> : null }
<div className="modal-loadmore-section">
<p>{ __('Showing', 'tainacan') + " " + this.state.modalTerms.length + " " + __('of', 'tainacan') + " " + this.state.totalModalTerms + " " + __('terms', 'tainacan') + "."}</p>
{
this.state.modalTerms.length < this.state.totalModalTerms ? (
<Button
isDefault
isSmall
onClick={ () => this.fetchModalTerms(this.state.modalTerms.length, this.state.taxonomyId) }>
{__('Load more', 'tainacan')}
</Button>
) : null
}
</div>
</div>
) : this.state.isLoadingTerms ? <div class="spinner-container"><Spinner /></div> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no terms found.', 'tainacan') }</p>
</div>
)}
<div className="modal-footer-area">
<Button
isDefault
onClick={ () => this.resetTaxonomies() }>
{__('Switch taxonomy', 'tainacan')}
</Button>
<Button
isPrimary
onClick={ () => this.onSelectTerm() }>
{__('Finish', 'tainacan')}
</Button>
</div>
</div>
</Modal>
) : (
// Taxonomies modal
<Modal
className="wp-block-tainacan-modal"
title={__('Select a taxonomy to fetch terms from', 'tainacan')}
onRequestClose={ () => this.cancelSelection() }
contentLabel={__('Select terms', 'tainacan')}>
<div>
<div className="modal-search-area">
<TextControl
placeholder={ __('Search by taxonomy name', 'tainacan') }
label={__('Search for a taxonomy', 'tainacan')}
value={ this.state.searchTaxonomyName }
onChange={(value) => {
this.setState({
searchTaxonomyName: value
});
_.debounce(this.fetchTaxonomies(value), 300);
}}/>
<SelectControl
label={__('Order by', 'tainacan')}
value={ this.state.taxonomyOrderBy }
options={ [
{ label: __('Latest', 'tainacan'), value: 'date-desc' },
{ label: __('Oldest', 'tainacan'), value: 'date' },
{ label: __('Name (A-Z)', 'tainacan'), value: 'title' },
{ label: __('Name (Z-A)', 'tainacan'), value: 'title-desc' }
] }
onChange={ ( ataxonomyOrderBy ) => {
this.state.taxonomyOrderBy = ataxonomyOrderBy;
this.state.taxonomyPage = 1;
this.setState({
taxonomyOrderBy: this.state.taxonomyOrderBy,
taxonomyPage: this.state.taxonomyPage
});
if (this.state.searchTaxonomyName && this.state.searchTaxonomyName != '') {
this.fetchTaxonomies(this.state.searchTaxonomyName);
} else {
this.fetchModalTaxonomies();
}
}}/>
</div>
{(
this.state.searchTaxonomyName != '' ? (
this.state.taxonomies.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryTaxonomyId }
options={
this.state.taxonomies.map((taxonomy) => {
return { label: taxonomy.name, value: '' + taxonomy.id }
})
}
onChange={ ( aTaxonomyId ) => {
this.setState({ temporaryTaxonomyId: aTaxonomyId });
} } />
}
</div>
</div>
) :
this.state.isLoadingTaxonomies ? (
<div class="spinner-container"><Spinner /></div>
) :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no taxonomy found.', 'tainacan') }</p>
</div>
):
this.state.modalTaxonomies.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryTaxonomyId }
options={
this.state.modalTaxonomies.map((taxonomy) => {
return { label: taxonomy.name, value: '' + taxonomy.id }
})
}
onChange={ ( aTaxonomyId ) => {
this.setState({ temporaryTaxonomyId: aTaxonomyId });
} } />
}
</div>
<div className="modal-loadmore-section">
<p>{ __('Showing', 'tainacan') + " " + this.state.modalTaxonomies.length + " " + __('of', 'tainacan') + " " + this.state.totalModalTaxonomies + " " + __('taxonomies', 'tainacan') + "."}</p>
{
this.state.modalTaxonomies.length < this.state.totalModalTaxonomies ? (
<Button
isDefault
isSmall
onClick={ () => this.fetchModalTaxonomies() }>
{__('Load more', 'tainacan')}
</Button>
) : null
}
</div>
</div>
) : this.state.isLoadingTaxonomies ? <div class="spinner-container"><Spinner /></div> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no taxonomy found.', 'tainacan') }</p>
</div>
)}
<div className="modal-footer-area">
<Button
isDefault
onClick={ () => { this.cancelSelection() }}>
{__('Cancel', 'tainacan')}
</Button>
<Button
isPrimary
disabled={ this.state.temporaryTaxonomyId == undefined || this.state.temporaryTaxonomyId == null || this.state.temporaryTaxonomyId == ''}
onClick={ () => this.selectTaxonomy(this.state.temporaryTaxonomyId) }>
{__('Select terms', 'tainacan')}
</Button>
</div>
</div>
</Modal>
);
}
}

View File

@ -846,7 +846,7 @@ registerBlockType('tainacan/facets-list', {
blockId: { blockId: {
type: String, type: String,
default: undefined default: undefined
}, }
}, },
save({ attributes, className }){ save({ attributes, className }){
const { const {

View File

@ -497,6 +497,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_select_collection_fetch_items' => __( 'Select a collection to fetch items', 'tainacan' ), 'instruction_select_collection_fetch_items' => __( 'Select a collection to fetch items', 'tainacan' ),
'instruction_select_a_action' => __( 'Select an action', 'tainacan' ), 'instruction_select_a_action' => __( 'Select an action', 'tainacan' ),
'instruction_parent_term' => __( 'Type to search a Parent Term to choose.', 'tainacan' ), 'instruction_parent_term' => __( 'Type to search a Parent Term to choose.', 'tainacan' ),
'instruction_type_existing_item' => __( 'Type to add an existing item...', 'tainacan' ),
'instruction_type_existing_term' => __( 'Type to add an existing term...', '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_an_exporter_type' => __( 'Select an exporter from the options below:', 'tainacan'),
'instruction_select_a_collection' => __( 'Select a collection', 'tainacan' ), 'instruction_select_a_collection' => __( 'Select a collection', 'tainacan' ),

View File

@ -35,6 +35,12 @@ import routerTheme from './theme-router.js';
import eventBusSearch from '../../admin/js/event-bus-search'; import eventBusSearch from '../../admin/js/event-bus-search';
import { I18NPlugin, UserPrefsPlugin, ConsolePlugin } from '../../admin/js/utilities'; import { I18NPlugin, UserPrefsPlugin, ConsolePlugin } from '../../admin/js/utilities';
/* Registers Extra Vue Pluginss passed to the TainacanExtraVuePlugins */
if (typeof TainacanExtraVuePlugins != "undefined") {
for (let [extraVuePluginName, extraVuePluginObject] of Object.entries(TainacanExtraVuePlugin))
Vue.use(extraVuePluginObject);
}
// Configure and Register Plugins // Configure and Register Plugins
Vue.use(Buefy, { Vue.use(Buefy, {
defaultTooltipAnimated: true defaultTooltipAnimated: true
@ -45,6 +51,12 @@ Vue.use(I18NPlugin);
Vue.use(UserPrefsPlugin); Vue.use(UserPrefsPlugin);
Vue.use(ConsolePlugin, {visual: false}); Vue.use(ConsolePlugin, {visual: false});
/* Registers Extra Vue Components passed to the TainacanExtraVueComponents */
if (typeof TainacanExtraVueComponents != "undefined") {
for (let [extraVueComponentName, extraVueComponentObject] of Object.entries(TainacanExtraVueComponents))
Vue.component(extraVueComponentName, extraVueComponentObject);
}
Vue.component('tainacan-filter-item', TaincanFiltersList); Vue.component('tainacan-filter-item', TaincanFiltersList);
/* Filters */ /* Filters */
@ -73,77 +85,80 @@ Vue.component('view-mode-slideshow', ViewModeSlideshow);
Vue.use(eventBusSearch, { store: store, router: routerTheme}); Vue.use(eventBusSearch, { store: store, router: routerTheme});
export const ThemeItemsListing = new Vue({ document.addEventListener("DOMContentLoaded", () => {
el: '#tainacan-items-page', new Vue({
store, el: '#tainacan-items-page',
router: routerTheme, store,
data: { router: routerTheme,
termId: '', data: {
taxonomy: '', termId: '',
collectionId: '', taxonomy: '',
defaultViewMode: '', collectionId: '',
enabledViewModes: {}, defaultViewMode: '',
hideFilters: false, enabledViewModes: {},
hideHideFiltersButton: false, hideFilters: false,
hideSearch: false, hideHideFiltersButton: false,
hideAdvancedSearch: false, hideSearch: false,
hideSortByButton: false, hideAdvancedSearch: false,
hideExposersButton: false, hideSortByButton: false,
hideItemsPerPageButton: false, hideItemsPerPageButton: false,
hideGoToPageButton: false, hideGoToPageButton: false,
startWithFiltersHidden: false, showFiltersButtonInsideSearchControl: false,
filtersAsModal: false, startWithFiltersHidden: false,
showInlineViewModeOptions: false, filtersAsModal: false,
showFullscreenWithViewModes: false showInlineViewModeOptions: false,
}, showFullscreenWithViewModes: false
beforeMount () { },
beforeMount () {
// Collection or Term source settings
if (this.$el.attributes['collection-id'] != undefined)
this.collectionId = this.$el.attributes['collection-id'].value;
if (this.$el.attributes['term-id'] != undefined)
this.termId = this.$el.attributes['term-id'].value;
if (this.$el.attributes['taxonomy'] != undefined)
this.taxonomy = this.$el.attributes['taxonomy'].value;
// Collection or Term source settings // View Mode settings
if (this.$el.attributes['collection-id'] != undefined) if (this.$el.attributes['default-view-mode'] != undefined)
this.collectionId = this.$el.attributes['collection-id'].value; this.defaultViewMode = this.$el.attributes['default-view-mode'].value;
if (this.$el.attributes['term-id'] != undefined) else
this.termId = this.$el.attributes['term-id'].value; this.defaultViewMode = 'cards';
if (this.$el.attributes['taxonomy'] != undefined)
this.taxonomy = this.$el.attributes['taxonomy'].value;
// View Mode settings if (this.$el.attributes['enabled-view-modes'] != undefined)
if (this.$el.attributes['default-view-mode'] != undefined) this.enabledViewModes = this.$el.attributes['enabled-view-modes'].value.split(',');
this.defaultViewMode = this.$el.attributes['default-view-mode'].value;
else // Options related to hidding elements
this.defaultViewMode = 'cards'; if (this.$el.attributes['hide-filters'] != undefined)
this.hideFilters = this.$el.attributes['hide-filters'].value == 'true' ? true : false;
if (this.$el.attributes['hide-hide-filters-button'] != undefined)
this.hideHideFiltersButton = this.$el.attributes['hide-hide-filters-button'].value == 'true' ? true : false;
if (this.$el.attributes['hide-search'] != undefined)
this.hideSearch = this.$el.attributes['hide-search'].value == 'true' ? true : false;
if (this.$el.attributes['hide-advanced-search'] != undefined)
this.hideAdvancedSearch = this.$el.attributes['hide-advanced-search'].value == 'true' ? true : false;
if (this.$el.attributes['hide-sort-by-button'] != undefined)
this.hideSortByButton = this.$el.attributes['hide-sort-by-button'].value == 'true' ? true : false;
if (this.$el.attributes['hide-exposers-button'] != undefined)
this.hideExposersButton = this.$el.attributes['hide-exposers-button'].value == 'true' ? true : false
if (this.$el.attributes['hide-items-per-page-button'] != undefined)
this.hideItemsPerPageButton = this.$el.attributes['hide-items-per-page-button'].value == 'true' ? true : false;
if (this.$el.attributes['hide-go-to-page-button'] != undefined)
this.hideGoToPageButton = this.$el.attributes['hide-go-to-page-button'].value == 'true' ? true : false;
if (this.$el.attributes['enabled-view-modes'] != undefined) // Other Tweaks
this.enabledViewModes = this.$el.attributes['enabled-view-modes'].value.split(','); if (this.$el.attributes['show-filters-button-inside-search-control'] != undefined)
this.showFiltersButtonInsideSearchControl = this.$el.attributes['show-filters-button-inside-search-control'].value == 'true' ? true : false;
// Options related to hidding elements if (this.$el.attributes['start-with-filters-hidden'] != undefined)
if (this.$el.attributes['hide-filters'] != undefined) this.startWithFiltersHidden = this.$el.attributes['start-with-filters-hidden'].value == 'true' ? true : false;
this.hideFilters = this.$el.attributes['hide-filters'].value; if (this.$el.attributes['filters-as-modal'] != undefined)
if (this.$el.attributes['hide-hide-filters-button'] != undefined) this.filtersAsModal = this.$el.attributes['filters-as-modal'].value == 'true' ? true : false;
this.hideHideFiltersButton = this.$el.attributes['hide-hide-filters-button'].value; if (this.$el.attributes['show-inline-view-mode-options'] != undefined)
if (this.$el.attributes['hide-search'] != undefined) this.showInlineViewModeOptions = this.$el.attributes['show-inline-view-mode-options'].value == 'true' ? true : false;
this.hideSearch = this.$el.attributes['hide-search'].value; if (this.$el.attributes['show-fullscreen-with-view-modes'] != undefined)
if (this.$el.attributes['hide-advanced-search'] != undefined) this.showFullscreenWithViewModes = this.$el.attributes['show-fullscreen-with-view-modes'].value == 'true' ? true : false;
this.hideAdvancedSearch = this.$el.attributes['hide-advanced-search'].value; },
if (this.$el.attributes['hide-sort-by-button'] != undefined) render: h => h(ThemeSearch)
this.hideSortByButton = this.$el.attributes['hide-sort-by-button'].value; });
if (this.$el.attributes['hide-exposers-button'] != undefined)
this.hideExposersButton = this.$el.attributes['hide-exposers-button'].value;
if (this.$el.attributes['hide-items-per-page-button'] != undefined)
this.hideItemsPerPageButton = this.$el.attributes['hide-items-per-page-button'].value;
if (this.$el.attributes['hide-go-to-page-button'] != undefined)
this.hideGoToPageButton = this.$el.attributes['hide-go-to-page-button'].value;
// Other Tweaks
if (this.$el.attributes['start-with-filters-hidden'] != undefined)
this.startWithFiltersHidden = this.$el.attributes['start-with-filters-hidden'].value;
if (this.$el.attributes['filters-as-modal'] != undefined)
this.filtersAsModal = this.$el.attributes['filters-as-modal'].value;
if (this.$el.attributes['show-inline-view-mode-options'] != undefined)
this.showInlineViewModeOptions = this.$el.attributes['show-inline-view-mode-options'].value;
if (this.$el.attributes['show-fullscreen-with-view-modes'] != undefined)
this.showFullscreenWithViewModes = this.$el.attributes['show-fullscreen-with-view-modes'].value;
},
render: h => h(ThemeSearch)
}); });
// Initialize Ponyfill for Custom CSS properties // Initialize Ponyfill for Custom CSS properties

View File

@ -29,7 +29,7 @@
aria-controls="filters-modal" aria-controls="filters-modal"
:aria-expanded="isFiltersModalActive" :aria-expanded="isFiltersModalActive"
:class="hideHideFiltersButton ? 'is-hidden-tablet' : ''" :class="hideHideFiltersButton ? 'is-hidden-tablet' : ''"
v-if="!hideFilters && !openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)" v-if="!showFiltersButtonInsideSearchControl && !hideFilters && !openAdvancedSearch && !(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen)"
id="filter-menu-compress-button" id="filter-menu-compress-button"
:aria-label="!isFiltersModalActive ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters')" :aria-label="!isFiltersModalActive ? $i18n.get('label_show_filters') : $i18n.get('label_hide_filters')"
@click="isFiltersModalActive = !isFiltersModalActive" @click="isFiltersModalActive = !isFiltersModalActive"
@ -79,6 +79,21 @@
</div> </div>
</div> </div>
<!-- Another option of the Button for hiding filters -->
<div
v-if="showFiltersButtonInsideSearchControl && !hideHideFiltersButton && !hideFilters && !openAdvancedSearch"
class="search-control-item">
<button
class="button is-white"
:aria-label="$i18n.get('filters')"
@click="isFiltersModalActive = !isFiltersModalActive">
<span class="gray-icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-filters"/>
</span>
<span class="is-hidden-touch">{{ $i18n.get('filters') }}</span>
</button>
</div>
<!-- Displayed Metadata Dropdown --> <!-- Displayed Metadata Dropdown -->
<div <div
v-if="(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].dynamic_metadata)" v-if="(registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].dynamic_metadata)"
@ -536,6 +551,7 @@
hideItemsPerPageButton: false, hideItemsPerPageButton: false,
hideGoToPageButton: false, hideGoToPageButton: false,
// Other Tweaks // Other Tweaks
showFiltersButtonInsideSearchControl: false,
startWithFiltersHidden: false, startWithFiltersHidden: false,
filtersAsModal: false, filtersAsModal: false,
showInlineViewModeOptions: false, showInlineViewModeOptions: false,
@ -697,13 +713,15 @@
if (this.$userPrefs.get(prefsViewMode) == undefined) if (this.$userPrefs.get(prefsViewMode) == undefined)
this.$eventBusSearch.setInitialViewMode(this.defaultViewMode); this.$eventBusSearch.setInitialViewMode(this.defaultViewMode);
else { else {
let existingViewModeIndex = Object.keys(this.registeredViewModes).findIndex(viewMode => viewMode == this.$userPrefs.get(prefsViewMode)); const userPrefViewMode = this.$userPrefs.get(prefsViewMode);
if (existingViewModeIndex >= 0)
this.$eventBusSearch.setInitialViewMode(this.$userPrefs.get(prefsViewMode)); let existingViewModeIndex = Object.keys(this.registeredViewModes).findIndex(viewMode => viewMode == userPrefViewMode);
let enabledViewModeIndex = this.enabledViewModes.findIndex((viewMode) => viewMode == userPrefViewMode);
if (existingViewModeIndex >= 0 && enabledViewModeIndex >= 0)
this.$eventBusSearch.setInitialViewMode(userPrefViewMode);
else else
this.$eventBusSearch.setInitialViewMode(this.defaultViewMode); this.$eventBusSearch.setInitialViewMode(this.defaultViewMode);
} }
// For view modes such as slides, we force pagination to request only 12 per page // For view modes such as slides, we force pagination to request only 12 per page
let existingViewModeIndex = Object.keys(this.registeredViewModes).findIndex(viewMode => viewMode == this.$userPrefs.get(prefsViewMode)); let existingViewModeIndex = Object.keys(this.registeredViewModes).findIndex(viewMode => viewMode == this.$userPrefs.get(prefsViewMode));
if (existingViewModeIndex >= 0) { if (existingViewModeIndex >= 0) {
@ -715,7 +733,7 @@
this.showItemsHiddingDueSortingDialog(); this.showItemsHiddingDueSortingDialog();
// Watches window resize to adjust filter's top position and compression on mobile // Watches window resize to adjust filter's top position and compression on mobile
if (!this.hideFilters) { if (!this.hideFilters) {
this.hideFiltersOnMobile(); this.hideFiltersOnMobile();
window.addEventListener('resize', this.hideFiltersOnMobile); window.addEventListener('resize', this.hideFiltersOnMobile);
} }
@ -1385,7 +1403,7 @@
animation-duration: 0.5s; animation-duration: 0.5s;
p { p {
margin: 0 auto; margin: 0 auto !important;
font-size: 0.885em; font-size: 0.885em;
} }

View File

@ -14,6 +14,7 @@
:hide-exposers-button="$root.hideExposersButton ? $root.hideExposersButton : false" :hide-exposers-button="$root.hideExposersButton ? $root.hideExposersButton : false"
:hide-items-per-page-button="$root.hideItemsPerPageButton ? $root.hideItemsPerPageButton : false" :hide-items-per-page-button="$root.hideItemsPerPageButton ? $root.hideItemsPerPageButton : false"
:hide-go-to-page-button="$root.hideGoToPageButton ? $root.hideGoToPageButton : false" :hide-go-to-page-button="$root.hideGoToPageButton ? $root.hideGoToPageButton : false"
:show-filters-button-inside-search-control="$root.showFiltersButtonInsideSearchControl ? $root.showFiltersButtonInsideSearchControl : false"
:start-with-filters-hidden="$root.startWithFiltersHidden ? $root.startWithFiltersHidden : false" :start-with-filters-hidden="$root.startWithFiltersHidden ? $root.startWithFiltersHidden : false"
:filters-as-modal="$root.filtersAsModal ? $root.filtersAsModal : false" :filters-as-modal="$root.filtersAsModal ? $root.filtersAsModal : false"
:show-inline-view-mode-options="$root.showInlineViewModeOptions ? $root.showInlineViewModeOptions : false" :show-inline-view-mode-options="$root.showInlineViewModeOptions ? $root.showInlineViewModeOptions : false"
@ -25,7 +26,7 @@
export default { export default {
name: "ThemeSearch", name: "ThemeSearch",
created() { created() {
this.$userPrefs.init(); this.$userPrefs.init();
} }
} }
</script> </script>
@ -76,6 +77,21 @@ export default {
position: relative; position: relative;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
* {
// For Firefox
scrollbar-color: var(--tainacan-gray3) transparent;
scrollbar-width: thin;
// For Chromium and related
&::-webkit-scrollbar {
width: 0.55em;
opacity: 0.8;
}
&::-webkit-scrollbar-thumb {
background-color: var(--tainacan-gray3);
}
}
h1, h1,
h2, h2,
h3, h3,

View File

@ -29,7 +29,9 @@ module.exports = {
block_facets_list: './src/views/gutenberg-blocks/tainacan-facets/facets-list/index.js', block_facets_list: './src/views/gutenberg-blocks/tainacan-facets/facets-list/index.js',
block_facets_list_theme: './src/views/gutenberg-blocks/tainacan-facets/facets-list/facets-list-theme.js', block_facets_list_theme: './src/views/gutenberg-blocks/tainacan-facets/facets-list/facets-list-theme.js',
block_faceted_search: './src/views/gutenberg-blocks/tainacan-facets/faceted-search/index.js',
block_carousel_terms_list: './src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/index.js', block_carousel_terms_list: './src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/index.js',
block_carousel_terms_list_theme: './src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list-theme.js' block_carousel_terms_list_theme: './src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list-theme.js'