Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
vvasilev- committed Apr 1, 2019
2 parents 3e29778 + 1fb701d commit 670c70e
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 43 deletions.
4 changes: 4 additions & 0 deletions bin/webpack.metaboxes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const config = {
entry: {
metaboxes: './packages/metaboxes/index.js'
},
output: {
library: [ 'cf', '[name]' ],
libraryTarget: 'this'
},
externals: {
'react': [ 'cf', 'vendor', 'react' ],
'react-dom': [ 'cf', 'vendor', 'react-dom' ],
Expand Down
30 changes: 21 additions & 9 deletions core/REST_API/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,25 +287,37 @@ public function get_comment_meta( $data ) {
/**
* Get Carbon Fields association options data.
*
* @access public
*
* @return array
*/
public function get_association_data() {
$container_id = $_GET['container_id'];
$field_id = $_GET['field_id'];
$options = isset( $_GET['options'] ) ? $_GET['options'] : array();
$options = isset( $_GET['options'] ) ? explode( ';', $_GET['options'] ) : array();
$return_value = array();

$field = Helper::get_field( null, $container_id, $field_id );

foreach ( $options as $entry ) {
$options = array_map( function ( $option ) {
$option = explode( ':', $option );

return [
'id' => $option[0],
'type' => $option[1],
'subtype' => $option[2],
];
}, $options );

foreach ( $options as $option ) {
$item = array(
'type' => $entry['type'],
'subtype' => $entry['subtype'],
'thumbnail' => $field->get_thumbnail_by_type( $entry['id'], $entry['type'], $entry['subtype'] ),
'id' => intval( $entry['id'] ),
'title' => $field->get_title_by_type( $entry['id'], $entry['type'], $entry['subtype'] ),
'label' => $field->get_item_label( $entry['id'], $entry['type'], $entry['subtype'] ),
'is_trashed' => ( $entry['type'] == 'post' && get_post_status( $entry['id'] ) === 'trash' ),
'type' => $option['type'],
'subtype' => $option['subtype'],
'thumbnail' => $field->get_thumbnail_by_type( $option['id'], $option['type'], $option['subtype'] ),
'id' => intval( $option['id'] ),
'title' => $field->get_title_by_type( $option['id'], $option['type'], $option['subtype'] ),
'label' => $field->get_item_label( $option['id'], $option['type'], $option['subtype'] ),
'is_trashed' => ( $option['type'] == 'post' && get_post_status( $option['id'] ) === 'trash' ),
);

$return_value[] = $item;
Expand Down
94 changes: 85 additions & 9 deletions packages/core/fields/association/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
without,
isMatch,
isEmpty

} from 'lodash';
import {
combine,
Expand All @@ -44,6 +43,13 @@ class AssociationField extends Component {
*/
selectedList = createRef();

/**
* Keeps reference to the DOM bnode that contains the options.
*
* @type {Object}
*/
sourceList = createRef();

/**
* Lifecycle hook.
*
Expand All @@ -65,6 +71,47 @@ class AssociationField extends Component {
if ( value ) {
fetchSelectedOptions();
}

this.sourceList.current.addEventListener( 'scroll', this.handleSourceListScroll );
}

/**
* Lifecycle hook.
*
* @return {void}
*/
componentWillUnmount() {
this.sourceList.current.removeEventListener( 'scroll', this.handleSourceListScroll );
}

/**
* Handles the scroll event of the source list.
*
* @return {void}
*/
handleSourceListScroll = () => {
const {
fetchOptions,
setState,
options,
page,
queryTerm
} = this.props;

const sourceList = this.sourceList.current;

if ( sourceList.offsetHeight + sourceList.scrollTop === sourceList.scrollHeight ) {
setState( {
page: page + 1
} );

fetchOptions( {
type: 'append',
options: options,
queryTerm,
page: page + 1
} );
}
}

/**
Expand All @@ -79,8 +126,16 @@ class AssociationField extends Component {
setState
} = this.props;

setState( { queryTerm } );
fetchOptions( { queryTerm } );
setState( {
page: 1,
queryTerm
} );

fetchOptions( {
type: 'replace',
page: 1,
queryTerm
} );
}

/**
Expand Down Expand Up @@ -172,7 +227,8 @@ class AssociationField extends Component {
field,
totalOptionsCount,
selectedOptions,
queryTerm
queryTerm,
isLoading
} = this.props;

let { options } = this.props;
Expand All @@ -199,6 +255,12 @@ class AssociationField extends Component {
onChange={ this.handleSearchChange }
/>

{
isLoading
? <span className="cf-association__spinner spinner is-active"></span>
: ''
}

<span className="cf-association__counter">
{ sprintf(
__( 'Showing %1$d of %2$d results', 'carbon-fields-ui' ),
Expand All @@ -209,7 +271,7 @@ class AssociationField extends Component {
</div>

<div className="cf-association__cols">
<div className="cf-association__col">
<div className="cf-association__col" ref={ this.sourceList }>
{
options.map( ( option, index ) => {
return (
Expand All @@ -220,7 +282,9 @@ class AssociationField extends Component {

<div className="cf-association__option-content">
<span className="cf-association__option-title">
{ option.title }
<span className="cf-association__option-title-inner">
{ option.title }
</span>
</span>

<span className="cf-association__option-type">
Expand Down Expand Up @@ -368,10 +432,15 @@ function handler( props ) {

switch ( type ) {
case 'FETCH_OPTIONS':
setState( {
isLoading: true
} );

// eslint-disable-next-line
const request = window.jQuery.get( window.ajaxurl, {
action: 'carbon_fields_fetch_association_options',
term: payload.queryTerm,
page: payload.page || 1,
container_id: props.containerId,
field_name: hierarchyResolver()
}, null, 'json' );
Expand All @@ -382,7 +451,7 @@ function handler( props ) {
request.done( ( response ) => {
if ( response && response.success ) {
setState( {
options: response.data.options,
options: payload.type === 'replace' ? response.data.options : [ ...payload.options, ...response.data.options ],
totalOptionsCount: response.data.total_options
} );
} else {
Expand All @@ -391,6 +460,11 @@ function handler( props ) {
} );

request.fail( errorHandler );
request.always( () => {
setState( {
isLoading: false
} );
} );
break;

case 'FETCH_SELECTED_OPTIONS':
Expand All @@ -399,7 +473,7 @@ function handler( props ) {
'get',
{
container_id: props.containerId,
options: props.value,
options: props.value.map( ( option ) => `${ option.id }:${ option.type }:${ option.subtype }` ).join( ';' ),
field_id: hierarchyResolver()
}
)
Expand All @@ -418,7 +492,9 @@ const applyWithState = withState( {
options: [],
selectedOptions: [],
totalOptionsCount: 0,
queryTerm: ''
queryTerm: '',
page: 1,
isLoading: false
} );

const applyWithEffects = withEffects( aperture, { handler } );
Expand Down
66 changes: 54 additions & 12 deletions packages/core/fields/association/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,57 @@
.cf-association__bar {
position: relative;
z-index: 1;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
border-color: $wp-color-gray-light-500;
border-style: solid;
border-width: 1px 1px 0;
box-shadow: inset 0 1px 2px rgba( 0, 0, 0, 0.07 );

.cf-search-input {
flex: 1 1 auto;
}

.cf-search-input__inner {
border: 0;
box-shadow: none;

&:focus {
border-color: none;
box-shadow: none;
outline: none;
}
}

&:focus-within {
border-color: #5b9dd9;
box-shadow: 0 0 2px rgba( 30, 140, 190, 0.8 );
outline: 2px solid transparent;
}
}

.cf-association__counter {
position: absolute;
top: 50%;
right: 8px;
font-size: 12px;
line-height: 1;
color: $wp-color-dark-gray;
transform: translateY(-50%);
pointer-events: none;
margin-right: 5px;
margin-left: 5px;
}

.cf-association__spinner {
float: none;
margin: 0;
margin-left: 5px;
}

.cf-association__cols {
background: #fff;
position: relative;
z-index: 0;
display: flex;
border-width: 0 1px 1px;
border-width: 1px;
border-style: solid;
border-color: $wp-color-gray-light-500;

Expand Down Expand Up @@ -83,19 +115,29 @@
}

.cf-association__option-title {
overflow: hidden;
font-size: $wp-font-size;
line-height: $wp-line-height;
color: $wp-color-base-gray;
white-space: nowrap;
text-overflow: ellipsis;
flex: 1;
position: relative;
margin-right: $size-base;

.cf-association__option--selected & {
color: $wp-color-dark-silver-gray;
}
}

.cf-association__option-title-inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
font-size: $wp-font-size;
line-height: $wp-line-height;
color: $wp-color-base-gray;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
transform: translateY(-50%);
}

.cf-association__option-type {
font-size: 9px;
line-height: 1;
Expand Down
5 changes: 4 additions & 1 deletion packages/metaboxes/containers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export function renderContainer( container, context ) {
if ( node ) {
render(
<Component id={ container.id } />,
node
node,
() => {
node.dataset.mounted = true;
}
);
} else {
// eslint-disable-next-line no-console
Expand Down
5 changes: 5 additions & 0 deletions packages/metaboxes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import initializeMonitors from './monitors';
import initializeContainers from './containers';
import isGutenberg from './utils/is-gutenberg';

/**
* Public API.
*/
export { registerContainerType, getContainerType } from './containers/registry';

/**
* Sets the locale data for the package type
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ const INITIAL_STATE = {
* @return {Object}
*/
function getPostTemplateFromSelect( node ) {
let { value } = node;

// In Gutenberg for the "Default" template is used an empty string.
if ( value === 'default' ) {
value = '';
}

return {
post_template: node.value
post_template: value
};
}

Expand Down
Loading

0 comments on commit 670c70e

Please sign in to comment.