Skip to content

Commit

Permalink
Merge pull request #5578 from Automattic/add/course-list-student-cour…
Browse files Browse the repository at this point in the history
…se-filter

Make course list filter single block and implement student course filter
  • Loading branch information
Imran92 authored Sep 9, 2022
2 parents fc603dc + 6ca0e42 commit 68cb4e1
Show file tree
Hide file tree
Showing 19 changed files with 478 additions and 128 deletions.
4 changes: 4 additions & 0 deletions assets/blocks/course-list-block/course-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ $block: '.wp-block-sensei-lms-course-list';
padding: 0 0 25px;
}

select {
background-position-y: center;
}

.wp-block-post-template {
.wp-block-post-featured-image {
margin: 0 auto 1.618em;
Expand Down
8 changes: 6 additions & 2 deletions assets/blocks/course-list-filter-block/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
"category": "sensei-lms",
"textdomain": "sensei-lms",
"attributes": {
"type": {
"align": {
"type": "string",
"default": "categories"
"default": "wide"
},
"types": {
"type": "array",
"default": [ "categories", "featured", "student_course" ]
}
},
"usesContext": [ "queryId", "query" ],
Expand Down
121 changes: 77 additions & 44 deletions assets/blocks/course-list-filter-block/course-list-filter-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,7 @@ import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
*/
import InvalidUsageError from '../../shared/components/invalid-usage';

const filters = {
categories: {
label: __( 'Categories', 'sensei-lms' ),
defaultOption: {
label: __( 'All Categories', 'sensei-lms' ),
value: 0,
},
},
featured: {
label: __( 'Featured', 'sensei-lms' ),
defaultOption: {
label: __( 'All Courses', 'sensei-lms' ),
value: 'all',
},
},
activity: {
label: __( 'Activity', 'sensei-lms' ),
defaultOption: {
label: __( 'All Courses', 'sensei-lms' ),
value: 0,
},
},
};

function useFilterOptions( type ) {
function useFilterOptions() {
const categories = useSelect( ( select ) => {
const terms = select( 'core' ).getEntityRecords(
'taxonomy',
Expand All @@ -53,28 +29,83 @@ function useFilterOptions( type ) {
};
} );

switch ( type ) {
case 'categories':
return [ filters.categories.defaultOption, ...categories ];
case 'featured':
return [
filters.featured.defaultOption,
return {
categories: {
label: __( 'Categories', 'sensei-lms' ),
options: [
{
label: __( 'All Categories', 'sensei-lms' ),
value: -1,
},
...categories,
],
defaultOption: -1,
},
featured: {
label: __( 'Featured', 'sensei-lms' ),
options: [
{
label: __( 'All Courses', 'sensei-lms' ),
value: 'all',
},
{
label: __( 'Featured', 'sensei-lms' ),
value: 'featured',
},
];
case 'activity':
return [ filters.activity.defaultOption ];
],
defaultOption: 'all',
},
student_course: {
label: __( 'Student Courses', 'sensei-lms' ),
options: [
{
label: __( 'All Courses', 'sensei-lms' ),
value: 'all',
},
{
label: __( 'Active', 'sensei-lms' ),
value: 'active',
},
{
label: __( 'Completed', 'sensei-lms' ),
value: 'completed',
},
],
defaultOption: 'all',
},
};
}

function updateSelectedTypesList( checked, types, setAttributes, key ) {
const newTypes = checked
? [ ...types, key ]
: types.filter( ( type ) => type !== key );
setAttributes( { types: newTypes } );
}

function SelectedFilters( { filters, types } ) {
if ( ! types || types.length < 1 ) {
return null;
}
return Object.keys( filters ).map( ( key ) => {
const filter = filters[ key ];
return types.includes( key ) ? (
<SelectControl
key={ filter.label }
options={ filter.options }
onChange={ () => {} }
value={ filter.defaultOption }
/>
) : null;
} );
}

function CourseListFilter( {
attributes: { type },
attributes: { types },
context: { query },
setAttributes,
} ) {
const options = useFilterOptions( type );
const filters = useFilterOptions();
const blockProps = useBlockProps();

if ( 'course' !== query?.postType ) {
Expand All @@ -96,18 +127,20 @@ function CourseListFilter( {
<ToggleControl
key={ key }
label={ filters[ key ].label }
checked={ key === type }
onChange={ () => setAttributes( { type: key } ) }
checked={ types.includes( key ) }
onChange={ ( checked ) =>
updateSelectedTypesList(
checked,
types,
setAttributes,
key
)
}
/>
) ) }
</PanelBody>
</InspectorControls>
<SelectControl
className="sensei-lms-course-list-filter__select"
options={ options }
onChange={ () => {} }
value={ filters[ type ].defaultOption.value }
/>
<SelectedFilters filters={ filters } types={ types } />
</div>
);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe( 'CourseListFilterBlockEdit', () => {
const { getByText } = render(
<CourseListFilter
clientId="some-client-id"
attributes={ { type: 'categories' } }
attributes={ { types: [ 'categories' ] } }
context={ context }
/>
);
Expand All @@ -57,7 +57,7 @@ describe( 'CourseListFilterBlockEdit', () => {
const { getByRole } = render(
<CourseListFilter
clientId="some-client-id"
attributes={ { type: 'featured' } }
attributes={ { types: [ 'featured' ] } }
context={ context }
/>
);
Expand All @@ -66,22 +66,24 @@ describe( 'CourseListFilterBlockEdit', () => {
).toBeInTheDocument();
} );

it( 'should render the dropdown for activity filter', () => {
const { getByText } = render(
it( 'should render the dropdown for student course filter', () => {
const { getByRole } = render(
<CourseListFilter
clientId="some-client-id"
attributes={ { type: 'activity' } }
attributes={ { types: [ 'student_course' ] } }
context={ context }
/>
);
expect( getByText( 'All Courses' ) ).toBeInTheDocument();
expect(
within( getByRole( 'combobox' ) ).getByText( 'Completed' )
).toBeInTheDocument();
} );

it( 'should render an error', () => {
const { getByText } = render(
<CourseListFilter
clientId="some-client-id"
attributes={ { type: 'activity' } }
attributes={ { types: [ 'activity' ] } }
context={ { query: { postType: 'post' } } }
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.editor-styles-wrapper {
.wp-block-sensei-lms-course-list-filter {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
}
7 changes: 2 additions & 5 deletions assets/blocks/course-list-filter-block/course-list-filter.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
const courseListFeaturedFilterElements = document.querySelectorAll(
'.wp-sensei-course-list-block-filter select'
'.wp-block-sensei-lms-course-list-filter select'
);

courseListFeaturedFilterElements.forEach( ( element ) => {
element.onchange = ( evt ) => {
const url = new URL( window.location.href );
url.searchParams.set(
evt.target.dataset.paramKey + evt.target.dataset.queryId,
evt.target.value
);
url.searchParams.set( evt.target.dataset.paramKey, evt.target.value );
window.location.href = url;
};
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.wp-block-sensei-lms-course-list-filter {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
2 changes: 1 addition & 1 deletion assets/blocks/course-list-filter-block/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import { category as icon } from '@wordpress/icons';
import icon from '../../icons/course-list-filter.svg';
import metadata from './block.json';
import edit from './course-list-filter-edit';

Expand Down
2 changes: 1 addition & 1 deletion assets/blocks/global-blocks-style-editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
@import 'course-actions-block/course-actions/course-actions-editor';
@import 'course-progress-block/course-progress-editor';
@import 'course-list-block/course-list-block-editor';
@import 'course-list-filter-block/course-list-filter-edit';
@import 'course-list-filter-block/course-list-filter-editor';
1 change: 1 addition & 0 deletions assets/blocks/global-blocks-style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
@import 'course-categories-block/course-categories';
@import 'course-list-block/course-list';
@import 'course-progress-block/course-progress';
@import 'course-list-filter-block/course-list-filter';
3 changes: 3 additions & 0 deletions assets/icons/course-list-filter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
/**
* Class Sensei_Course_List_Categories_Filter
*/
class Sensei_Course_List_Categories_Filter {
class Sensei_Course_List_Categories_Filter extends Sensei_Course_List_Filter_Abstract {

/**
* Name of the filter.
*/
const FILTER_NAME = 'categories';

/**
* Unique key for the filter param.
Expand All @@ -27,21 +32,17 @@ class Sensei_Course_List_Categories_Filter {
* @param int $query_id The id of the Query block this filter is rendering inside.
*/
public function get_content( $query_id ) : string {
$category_id = 0;
$filter_param_key = $this->param_key . $query_id;
// phpcs:ignore WordPress.Security.NonceVerification
if ( isset( $_GET[ $filter_param_key ] ) ) {
$category_id = intval( $_GET[ $filter_param_key ] ); // phpcs:ignore WordPress.Security.NonceVerification
}
$filter_param_key = $this->param_key . $query_id;
$category_id = isset( $_GET[ $filter_param_key ] ) ? intval( $_GET[ $filter_param_key ] ) : -1; // phpcs:ignore WordPress.Security.NonceVerification -- Argument is used to filter courses.
$course_categories = get_terms(
[
'taxonomy' => 'course-category',
'hide_empty' => true,
]
);

return '<select class="course_list_filter_block" data-param-key="' . $this->param_key . '" data-query-id="' . $query_id . '" >
<option value="">' . esc_html__( 'All Categories', 'sensei-lms' ) . '</option>' .
return '<select data-param-key="' . esc_attr( $filter_param_key ) . '">
<option value="-1">' . esc_html__( 'All Categories', 'sensei-lms' ) . '</option>' .
join(
'',
array_map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
/**
* Class Sensei_Course_List_Featured_Filter
*/
class Sensei_Course_List_Featured_Filter {
class Sensei_Course_List_Featured_Filter extends Sensei_Course_List_Filter_Abstract {

/**
* Name of the filter.
*/
const FILTER_NAME = 'featured';

/**
* Unique key for the filter param.
Expand All @@ -37,20 +42,17 @@ public function __construct() {
'featured' => __( 'Featured', 'sensei-lms' ),
];
}

/**
* Get the content to be be rendered inside the filtered block.
*
* @param int $query_id The id of the Query block this filter is rendering inside.
*/
public function get_content( $query_id ) : string {
$selected_option = 'all';
$filter_param_key = $this->param_key . $query_id;
// phpcs:ignore WordPress.Security.NonceVerification
if ( isset( $_GET[ $filter_param_key ] ) ) {
$selected_option = sanitize_text_field( wp_unslash( $_GET[ $filter_param_key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification
}
$selected_option = isset( $_GET[ $filter_param_key ] ) ? sanitize_text_field( wp_unslash( $_GET[ $filter_param_key ] ) ) : 'all'; // phpcs:ignore WordPress.Security.NonceVerification -- Argument is used to filter courses.

return '<select data-param-key="' . $this->param_key . '" data-query-id="' . $query_id . '" >' .
return '<select data-param-key="' . esc_attr( $filter_param_key ) . '">' .
join(
'',
array_map(
Expand Down
Loading

0 comments on commit 68cb4e1

Please sign in to comment.