| Current Path : /home/ereika83/www/wp-content/plugins/edit-flow/modules/calendar/lib/react/ |
| Current File : /home/ereika83/www/wp-content/plugins/edit-flow/modules/calendar/lib/react/calendar.react.js |
/* global EF_CALENDAR, document */
/**
* External dependencies
*/
import React from 'react';
import ReactDOM from 'react-dom';
import { _n, __, sprintf } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import { CalendarHeader } from './calendar-header';
import './style.react.scss';
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatDeep( arr, d = 1 ) {
return d > 0 ? arr.reduce( ( acc, val ) => acc.concat( Array.isArray( val ) ? flatDeep( val, d - 1 ) : val ), [] )
: arr.slice();
}
/**
* Recursively organizes the items into Parent -> Child -> Child nested array
* @param {*} items A list of items represent
* @param {*} parent This is used recursively, to identify the child items parent
* @param {*} level This is to identify the current level of nesting
* @returns {array} Array of organized items
*/
function organizeItems( items, parent = 0, level = 0 ) {
return items
.filter( item => item.parent === parent )
.map( item => {
return [ { ...item, level } ]
.concat(
organizeItems( items, item.value, level + 1 )
);
} );
}
const EF_USER_MAP = ( { id: value, display_name: name } ) => ( { value, name } );
const EF_CATEGORY_MAP = ( { term_id: value, name, parent } ) => ( { value, name, parent } );
/**
* The number of weeks is a drop listing the maximum number of weeks a user can select (usually 12). This creates an array and fills
* it with null so we can map over the length of the array and fill it with the labels we need
*/
const NUM_WEEKS_OPTIONS = ( new Array( EF_CALENDAR.NUM_WEEKS.MAX ) )
.fill( null )
.map( ( value, index ) => ( { value: index + 1, label: sprintf( _n( '%d week', '%d weeks', index + 1, 'text-domain' ), index + 1 ) } ) );
const INITIAL_CATEGORY = EF_CALENDAR.CATEGORIES.filter( category => category.term_id === EF_CALENDAR.FILTERS.cat ).map( EF_CATEGORY_MAP )[ 0 ];
const INITIAL_USER = EF_CALENDAR.USERS.filter( user => user.id === EF_CALENDAR.FILTERS.author ).map( EF_USER_MAP )[ 0 ];
/**
* Filters are hardcoded here for the moment, eventually should introduce some filtering to support custom filters
* Maybe support applyFilters for folks who want to wrap an HOC around <CalendarFilters />
*/
const filters = [
{
name: 'post_status',
filterType: 'select',
label: __( 'Select a status', 'edit-flow' ),
options: [ { value: '', label: __( 'Select a status', 'edit-flow' ) } ]
.concat( EF_CALENDAR.POST_STATI.map( ( { name: value, label } ) => ( { value, label } ) ) ),
initialValue: EF_CALENDAR.FILTERS.post_status,
},
{
name: 'author',
filterType: 'combobox',
inputLabel: __( 'Find a user', 'edit-flow' ),
buttonOpenLabel: __( 'Open user menu', 'edit-flow' ),
buttonCloseLabel: __( 'Close user menu', 'edit-flow' ),
buttonClearLabel: __( 'Clear user selection', 'edit-flow' ),
placeholder: __( 'Select a user', 'edit-flow' ),
options: EF_CALENDAR.USERS.map( EF_USER_MAP ),
initialValue: INITIAL_USER ? INITIAL_USER : null,
selectFirstItemOnBlur: true,
},
{
name: 'cat',
filterType: 'combobox',
inputLabel: __( 'Find a category', 'edit-flow' ),
buttonOpenLabel: __( 'Open category menu', 'edit-flow' ),
buttonCloseLabel: __( 'Close category menu', 'edit-flow' ),
buttonClearLabel: __( 'Clear category selection', 'edit-flow' ),
placeholder: __( 'Select a category', 'edit-flow' ),
options: flatDeep(
organizeItems( EF_CALENDAR.CATEGORIES.map( EF_CATEGORY_MAP ), 0 ),
Infinity
),
initialValue: INITIAL_CATEGORY ? INITIAL_CATEGORY : null,
selectFirstItemOnBlur: true,
},
];
if ( EF_CALENDAR.POST_TYPES && EF_CALENDAR.POST_TYPES.length > 1 ) {
filters.push( {
name: 'cpt',
filterType: 'select',
label: __( 'Select a type', 'edit-flow' ),
options: [ { value: '', label: __( 'Select a type', 'edit-flow' ) } ]
.concat( EF_CALENDAR.POST_TYPES.map( ( { name: value, label } ) => ( { value, label } ) ) ),
initialValue: EF_CALENDAR.FILTERS.cpt,
} );
}
filters.push( {
name: 'num_weeks',
filterType: 'select',
label: __( 'Number of weeks', 'edit-flow' ),
options: NUM_WEEKS_OPTIONS,
initialValue: EF_CALENDAR.FILTERS.num_weeks,
} );
ReactDOM.render(
<CalendarHeader
numberOfWeeks={EF_CALENDAR.FILTERS.num_weeks}
beginningOfWeek={EF_CALENDAR.BEGINNING_OF_WEEK}
pageUrl={EF_CALENDAR.PAGE_URL}
filters={filters}
filterValues={EF_CALENDAR.FILTERS}
/>,
document.getElementById( 'ef-calendar-navigation-mount' )
);