- { children }
-
-
-
- { sprintf(
- // Translators: %s = visibility setting label.
- __(
- 'This block is only visible to %s',
- 'lifterlms'
- ),
- getSetting( llms_visibility )
- ) }
-
-
-
- );
- }
-}
diff --git a/src/js/block-visibility/settings.js b/src/js/block-visibility/settings.js
deleted file mode 100644
index 4dd0f1e1..00000000
--- a/src/js/block-visibility/settings.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Settings used by the block visibility component
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP deps.
-import { __ } from '@wordpress/i18n';
-
-/**
- * Settings value -> label map.
- *
- * @type {Object}
- */
-const settings = {
- all: __( 'everyone', 'lifterlms' ),
- enrolled: __( 'enrolled users', 'lifterlms' ),
- not_enrolled: __( 'non-enrolled users or visitors', 'lifterlms' ),
- logged_in: __( 'logged in users', 'lifterlms' ),
- logged_out: __( 'logged out users', 'lifterlms' ),
-};
-
-/**
- * Retrieve the label for a single setting value
- *
- * @since 2.0.0
- *
- * @param {string} setting Setting value.
- * @return {string} Setting label.
- */
-export const getSetting = ( setting ) => settings[ setting ] || setting;
-
-/**
- * Array of settings options as used by a select control
- *
- * @since 2.0.0
- *
- * @return {Object[]} Array of objects to be passed into the options property for a select control.
- */
-export const options = Object.keys( settings ).map( ( key ) => ( {
- label: settings[ key ],
- value: key,
-} ) );
diff --git a/src/js/blocks-backwards-compat.js b/src/js/blocks-backwards-compat.js
deleted file mode 100644
index 70facb93..00000000
--- a/src/js/blocks-backwards-compat.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Ensure backwards compatibility with WP Core packages we rely on.
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// Import aliased versions of WP Core Packages.
-import { createReduxStore, register } from 'llmsWPData';
-
-// Make text definitions of all the data stores we reference via import.
-window.wp.blockEditor.store = 'core/block-editor';
-window.wp.editor.store = 'core/editor';
-window.wp.notices.store = 'core/notices';
-
-// Ensure we can register data stores.
-window.wp.data = {
- ...window.wp.data,
- createReduxStore,
- register,
-};
diff --git a/src/js/blocks.js b/src/js/blocks.js
deleted file mode 100644
index 5396cc3f..00000000
--- a/src/js/blocks.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Main Block editor entry point.
- *
- * @since 1.0.0
- * @version 2.0.0
- */
-
-// SCSS.
-import '../scss/blocks.scss';
-
-// Internal Deps.
-import './block-visibility/';
-import './dom-ready/';
-import './post-visibility/';
-import './formats/shortcodes/';
-import './sidebar/';
-import './data/';
-
-// Register all Core Blocks.
-import registerBlocks from './blocks/';
-registerBlocks();
-
-// Import core Components and expose them for 3rd parties to utilize.
-import Components from './components/';
-window.llms.components = Components;
diff --git a/src/js/blocks/course-continue-button/index.js b/src/js/blocks/course-continue-button/index.js
deleted file mode 100644
index 4efba59d..00000000
--- a/src/js/blocks/course-continue-button/index.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * BLOCK: llms/course-continue-button
- *
- * @since 1.0.0
- * @since 1.5.0 Add supported post type settings.
- * @since 1.8.0 Use imports in favor of "wp." variables.
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { Button } from '@wordpress/components';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/course-continue-button';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = [ 'course' ];
-
-/**
- * Register: Course Continue Button Block
- *
- * @since 1.0.0
- *
- * @param {string} name Block name.
- * @param {Object} settings Block settings.
- * @return {?WPBlock} The block, if it has been successfully, registered; otherwise `undefined`.
- */
-export const settings = {
- title: __( 'Course Continue Button', 'lifterlms' ),
- icon: {
- foreground: '#2295ff',
- src: 'migrate',
- },
- category: 'llms-blocks', // common, formatting, layout widgets, embed. see https://wordpress.org/gutenberg/handbook/block-api/#category.
- keywords: [ __( 'LifterLMS', 'lifterlms' ) ],
-
- /**
- * The edit function describes the structure of your block in the context of the editor.
- * This represents what the editor will render when the block is used.
- *
- * The "edit" property must be a valid function.
- *
- * @since 1.0.0
- *
- * @param {Object} props Block properties.
- * @return {Function} Component HTML fragment.
- */
- edit( props ) {
- return (
- } terms Array of term objects.
- * @return {Fragment} Component html fragment.
- */
- renderTerms( terms ) {
- const last = terms.length - 1;
- return (
-
- { !! terms
- ? terms.map( ( term, index ) =>
- this.renderTerm( term, last === index )
- )
- : __( 'Loading…', 'lifterlms' ) }
-
- );
- }
-
- /**
- * Render the HTML for a single term.
- *
- * @since Unknown
- *
- * @param {Object} term A term object.
- * @param {boolean} last Whether or not this is the last term in the list.
- * @return {Fragment} Component html fragment.
- */
- renderTerm( term, last ) {
- return (
-
-
- { term.name }
-
- { last ? '' : ', ' }
-
- );
- }
-
- /**
- * Render the component.
- *
- * @since Unknown
- *
- * @return {Fragment} Component html fragment.
- */
- render() {
- const { terms } = this.state;
- const { taxonomyName } = this.props;
-
- return Array.isArray( terms ) && ! terms.length ? (
- ''
- ) : (
-
- { taxonomyName } : { this.renderTerms( terms ) }
-
- );
- }
-}
diff --git a/src/js/blocks/course-progress/editor.scss b/src/js/blocks/course-progress/editor.scss
deleted file mode 100644
index fbc3a8cb..00000000
--- a/src/js/blocks/course-progress/editor.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Editor Styles
- *
- * CSS for just Backend enqueued after style.scss
- * which makes it higher in priority.
- *
- * @since 1.6.0
- * @version 1.6.0
- */
-
-.wp-block-llms-course-progress {
-
- display: flex;
- .progress-bar {
- background: $color-grey-light;
- border-radius: 4px;
- flex: 1;
- margin: 10px 0;
- overflow: hidden;
- .progress--fill {
- background: $color-brand-blue;
- height: 100%;
- width: 50%;
- }
- }
- span {
- padding-left: 5px;
- vertical-align: middle;
- }
-
-}
diff --git a/src/js/blocks/course-progress/index.js b/src/js/blocks/course-progress/index.js
deleted file mode 100644
index 6d7648f1..00000000
--- a/src/js/blocks/course-progress/index.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * BLOCK: llms/course-progress
- *
- * @since 1.0.0
- * @since 1.5.0 Add supported post type settings.
- * @since 1.8.0 Remove import of empty CSS file.
- * Use `import` in favor of "wp." constants.
- * Set shortcode attribute check_enrollment to true(1) so to display the progress to enrolled users only.
- * Do not support llms_visibility.
- * @since 1.9.0 Turned into a dynamic block.
- */
-
-// WP deps.
-import { __ } from '@wordpress/i18n';
-
-// CSS.
-import './editor.scss';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = [ 'course' ];
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/course-progress';
-
-/**
- * Register: Course Progress Block
- *
- * @type {Object}
- */
-export const settings = {
- title: __( 'Course Progress', 'lifterlms' ),
- icon: {
- foreground: '#2295ff',
- src: 'chart-area',
- },
- category: 'llms-blocks',
- keywords: [ __( 'LifterLMS', 'lifterlms' ) ],
- supports: {
- llms_visibility: false,
- },
-
- /**
- * Block edit method
- *
- * @since 1.0.0
- * @since 1.8.0 Use `className` in favor of `class`.
- *
- * @param {Object} props Block properties.
- * @return {Object} Component HTML fragment.
- */
- edit( props ) {
- return (
-
- );
- },
-
- /**
- * Save block content
- *
- * @since 1.0.0
- * @since 1.8.0 Set shortcode attribute check_enrollment to true (1) so to display the progress to enrolled users only.
- * @since 1.9.0 Turned into a dynamic block.
- *
- * @return {null} Saving disabled for "dynamic" block.
- */
- save() {
- return null;
- },
- deprecated: [
- {
- /**
- * Block Editor Save
- *
- * @since 1.0.0
- * @deprecated 1.8.0
- *
- * @param {Object} props Component properties object.
- * @return {Object} Component HTML Fragment.
- */
- save( props ) {
- return (
-
- [lifterlms_course_progress]
-
- );
- },
- },
- ],
-};
diff --git a/src/js/blocks/course-syllabus/editor.scss b/src/js/blocks/course-syllabus/editor.scss
deleted file mode 100644
index c984f160..00000000
--- a/src/js/blocks/course-syllabus/editor.scss
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Block Editor Styles
- */
-
-.llms-syllabus-wrapper {
-
- margin: 15px;
- text-align: center;
-
- .llms-section-title {
- margin: 25px 0 0;
- }
-
-}
-
-.llms-course-navigation {
- @include clearfix();
-
- .llms-prev-lesson,
- .llms-next-lesson,
- .llms-back-to-course {
- width: 49%;
- }
-
- .llms-prev-lesson,
- .llms-back-to-course {
- float: left;
- margin-right: 0.5%;
- }
-
- .llms-next-lesson,
- .llms-prev-lesson + .llms-back-to-course {
- float: right;
- margin-left: 0.5%;
- }
-
-}
-
-.llms-lesson-preview {
- display: inline-block;
- margin-top: 15px;
- max-width: 100%;
- position: relative;
- width: 480px;
-
- .llms-lesson-link {
- background: #f1f1f1;
- color: #212121;
- display: block;
- // height: 100%;
- padding: 15px;
- text-decoration: none;
-
- @include clearfix();
-
- &:hover {
- background: #eaeaea;
- }
-
- &:visited {
- color: #212121;
- }
-
- }
-
- .llms-lesson-thumbnail {
- margin-bottom: 10px;
- img {
- display: block;
- width: 100%;
- }
- }
-
- .llms-pre-text {
- text-align: left;
- }
-
- .llms-lesson-title {
- font-weight: 700;
- margin: 0 auto 10px;
- text-align: left;
- &:last-child {
- margin-bottom: 0;
- }
- }
-
- .llms-lesson-excerpt {
- text-align: left;
- }
-
- .llms-main {
- float: left;
- width: 100%;
- }
- .llms-extra {
- float: right;
- width: 15%;
- }
-
- .llms-extra + .llms-main {
- width: 85%;
- }
-
- .llms-lesson-counter,
- .llms-free-lesson-svg,
- .llms-lesson-complete,
- .llms-lesson-complete-placeholder {
- display: block;
- font-size: 32px;
- margin-bottom: 15px;
- }
-
- &.is-free,
- &.is-complete {
- .llms-lesson-complete {
- color: $color-brand-blue;
- }
- }
-
- .llms-icon-free {
- background: $color-brand-blue;
- border-radius: 4px;
- color: #f1f1f1;
- display: inline-block;
- padding: 5px 6px 4px;
- line-height: 1;
- font-size: 14px;
- }
-
- &.is-incomplete {
- .llms-lesson-complete {
- color: #cacaca;
- }
- }
-
- .llms-lesson-counter {
- font-size: 16px;
- line-height: 1;
- }
-
- .llms-free-lesson-svg {
- fill: currentColor;
- height: 23px;
- width: 50px;
- }
-
- p {
- margin-bottom: 0;
- margin-top: 0;
- }
-
-}
diff --git a/src/js/blocks/course-syllabus/index.js b/src/js/blocks/course-syllabus/index.js
deleted file mode 100644
index 8f9f8eb3..00000000
--- a/src/js/blocks/course-syllabus/index.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * BLOCK: llms/course-syllabus
- *
- * Renders a course syllabus
- *
- * @since 1.0.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-import ServerSideRender from '@wordpress/server-side-render';
-
-// Internal Deps.
-import './editor.scss';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/course-syllabus';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = [ 'course' ];
-
-/**
- * Register Course Syllabus Block
- *
- * @since 1.0.0
- */
-export const settings = {
- title: __( 'Course Syllabus', 'lifterlms' ),
- icon: {
- foreground: '#2295ff',
- src: 'grid-view',
- },
- category: 'llms-blocks',
- keywords: [ __( 'LifterLMS', 'lifterlms' ) ],
- attributes: {
- course_id: {
- type: 'int',
- default: 0,
- },
- },
-
- /**
- * The edit function describes the structure of your block in the context of the editor.
- * This represents what the editor will render when the block is used.
- *
- * The "edit" property must be a valid function.
- *
- * @since 1.0.0
- * @since 2.0.0 Don't render InspectorControls since the block doesn't have any actual settings.
- *
- * @param {Object} props Block properties.
- * @return {Fragment} Component HTML fragment.
- */
- edit: ( props ) => {
- const currentPost = wp.data.select( 'core/editor' ).getCurrentPost();
- const { attributes } = props;
-
- return (
-
-
-
- );
- },
-
- /**
- * The save function defines the way in which the different attributes should be combined
- * into the final markup, which is then serialized by Gutenberg into post_content.
- *
- * The "save" property must be specified and must be a valid function.
- *
- * @since 1.0.0
- *
- * @return {null} Saving disable for "dynamic" blocks.
- */
- save: () => {
- return null;
- },
-};
diff --git a/src/js/blocks/course-syllabus/inspect.js b/src/js/blocks/course-syllabus/inspect.js
deleted file mode 100644
index 6be86170..00000000
--- a/src/js/blocks/course-syllabus/inspect.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Block Attributes Inspector: Course Syllabus
- *
- * @since 1.0.0
- * @since 1.6.0 Import `InspectorControls` from `wp.blockEditor` in favor of deprecated `wp.editor`
- * @since 1.7.0 Import `InspectorControls` from `wp.blockEditor` and fallback to `wp.editor` to maintain backwards compatibility.
- * @version 1.6.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/block-editor';
-import { PanelBody } from '@wordpress/components';
-
-/**
- * Block inspector component
- *
- * @since 1.0.0
- */
-export default class Inspector extends Component {
- /**
- * Render the component
- *
- * @since 2.0.0
- *
- * @return {InspectorControls} Component HTML fragment.
- */
- render() {
- return (
-
-
-
- );
- }
-}
diff --git a/src/js/blocks/form-fields/.eslintrc.js b/src/js/blocks/form-fields/.eslintrc.js
deleted file mode 100644
index 4bab50fb..00000000
--- a/src/js/blocks/form-fields/.eslintrc.js
+++ /dev/null
@@ -1,19 +0,0 @@
-module.exports = {
- rules: {
- camelcase: [
- 'error',
- {
- allow: [
- 'data_store*',
- 'llms_*',
- 'label_show_empty',
- 'options_preset',
- 'last_column',
- 'html_attrs',
- 'min_strength',
- 'meter_description',
- ],
- },
- ],
- },
-};
diff --git a/src/js/blocks/form-fields/checks.js b/src/js/blocks/form-fields/checks.js
deleted file mode 100644
index 3adc50fa..00000000
--- a/src/js/blocks/form-fields/checks.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Form Field related checks
- *
- * @since Unknown
- * @version 2.0.0
- */
-
-// External Deps.
-import { forEach } from 'lodash';
-
-// WP Deps.
-import { select } from '@wordpress/data';
-
-// Internal deps.
-import { store as fieldsStore } from '../../data/fields';
-
-/**
- * Determines if the block is (or contains) field block/s
- *
- * If the block contains innerBlocks (or is a reusable block) it
- * passes the list of contained to filterBlocks.
- *
- * @since Unknown
- * @since 2.0.0 Adds support for reusable blocks.
- *
- * @param {Object} block A block object.
- * @return {Object[]} An array of field blocks.
- */
-function filterBlock( block ) {
- // when running `wp.blocks.parse()` for a reusable block `false` gets passed in and I don't understand it.
- if ( ! block ) {
- return [ block ];
- }
-
- // Check the block's inner blocks.
- if ( block.innerBlocks.length ) {
- return filterBlocks( block.innerBlocks );
- }
-
- // Reusable blocks don't have inner blocks defined so we need to look them up this way.
- if ( 'core/block' === block.name ) {
- const { blocks } = select( 'core' ).getEditedEntityRecord(
- 'postType',
- 'wp_block',
- block.attributes.ref
- );
- return filterBlocks( blocks );
- }
-
- // Only return form field blocks.
- if ( -1 === block.name.indexOf( 'llms/form-field' ) ) {
- return [];
- }
-
- return [ block ];
-}
-
-/**
- * Recursively filter blocks (checking inner blocks)
- *
- * Returns only a (flattened) list of field blocks.
- *
- * @since 2.0.0
- *
- * @param {Object[]} blocks An array of blocks to filter.
- * @return {Object[]} An array of field blocks.
- */
-function filterBlocks( blocks = [] ) {
- let fieldBlocks = [];
-
- forEach( blocks, ( block ) => {
- const filtered = filterBlock( block );
- if ( filtered.length ) {
- fieldBlocks = fieldBlocks.concat( filtered );
- }
- } );
-
- return fieldBlocks;
-}
-
-/**
- * Retrieve a "flattened" list of all form fields from a list of blocks
- *
- * Recursively checks each block for it's inner blocks to determine if there's
- * fields in the block.
- *
- * @since Unknown
- *
- * @param {Object[]} blocks An array of blocks to filter.
- * @return {Object[]} An array of field blocks.
- */
-export const getFieldBlocks = ( blocks = [] ) => {
- if ( ! Array.isArray( blocks ) ) {
- blocks = [ blocks ];
- }
- return filterBlocks( blocks );
-};
-
-/**
- * Ensure field attributes are unique in the requested context
- *
- * @since Unknown
- * @since 2.0.0 Added `context` parameter and use data from the llms/user-info-fields store.
- *
- * @param {string} key Attribute key name.
- * @param {string} val String to check for uniqueness.
- * @param {string} context Field context to look within. Accepts "global" to check against all fields or "local"
- * to check only against loaded fields in the current form.
- * @return {boolean} Returns `true` when the string is unique across the form and `false` if it's not.
- */
-export const isUnique = ( key, val, context = 'global' ) => {
- const { getFieldBy } = select( fieldsStore );
- return getFieldBy( key, val, context ) ? false : true;
-};
diff --git a/src/js/blocks/form-fields/edit.js b/src/js/blocks/form-fields/edit.js
deleted file mode 100644
index dcf5c82d..00000000
--- a/src/js/blocks/form-fields/edit.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/**
- * Edit components
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// External deps.
-import { snakeCase, kebabCase, uniqueId } from 'lodash';
-
-// WP deps.
-import { hasBlockSupport, getBlockType } from '@wordpress/blocks';
-import {
- useBlockProps,
- InnerBlocks,
- InspectorControls,
- store as blockEditorStore,
-} from '@wordpress/block-editor';
-import { dispatch, select } from '@wordpress/data';
-import { store as noticesStore } from '@wordpress/notices';
-import { PanelBody, Slot, Fill } from '@wordpress/components';
-import { useEffect } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import Field from './field';
-import Inspector from './inspect';
-import { isUnique } from './checks';
-import manageFieldGroupAttributes from './group-data';
-import GroupLayoutControl from './group-layout-control';
-import { store as fieldsStore } from '../../data/fields';
-
-/**
- * Generate a unique "name" attribute.
- *
- * @since 1.6.0
- * @since 2.0.0 Removed '_field' and added the current post id to ensure uniqueness across multiple forms.
- *
- * @param {string} name Base name, generally the field's "field" attribute. EG: "text".
- * @return {string} A unique name, in snake case, suitable to be used as a field's "name" attribute.
- */
-const generateName = ( name ) => {
- const { getCurrentPostId } = select( 'core/editor' );
- return snakeCase( uniqueId( `${ name }_${ getCurrentPostId() }_` ) );
-};
-
-/**
- * Generate a unique "id" attribute.
- *
- * @since 1.6.0
- *
- * @param {string} name Base name, generally the field's "name" attribute. EG: "text_field_1".
- * @return {string} A unique name, in kebab case, suitable to be used as a field's "id" attribute.
- */
-const generateId = ( name ) => {
- return kebabCase( name );
-};
-
-/**
- * Sets up block attributes, filling defaults and generating unique values.
- *
- * @since 1.6.0
- * @since 1.12.0 Add data_store_key generation.
- *
- * @param {Object} atts Default block attributes object.
- * @param {Object} blockAtts Actual WP_Block attributes object.
- * @param {boolean} addingField Determines if the field is new and should clear certain generated attributes.
- * @return {Object} Attribute object suitable for use when registering the block.
- */
-const setupAtts = ( atts, blockAtts, addingField ) => {
- // Merge configured defaults into the block attributes.
- Object.keys( blockAtts ).forEach( ( key ) => {
- const defaultValue = blockAtts[ key ].__default;
- if (
- 'undefined' !== typeof defaultValue &&
- 'undefined' === typeof atts[ key ]
- ) {
- atts[ key ] = defaultValue;
- }
- } );
-
- if ( ! atts.name || ( addingField && ! atts.isConfirmationField ) ) {
- let name = generateName( atts.field );
- while ( ! isUnique( 'name', name ) ) {
- name = generateName( atts.field );
- }
- atts.name = name;
- }
-
- if ( ! atts.id || ( addingField && ! atts.isConfirmationField ) ) {
- let id = generateId( atts.name );
- while ( ! isUnique( 'id', id, 'local' ) ) {
- id = generateId( uniqueId( `${ atts.field }-field-` ) );
- }
- atts.id = id;
- }
-
- if (
- '' === atts.data_store_key ||
- ( addingField && ! atts.isConfirmationField )
- ) {
- atts.data_store_key = atts.name;
- }
-
- return atts;
-};
-
-/**
- * Edit action for a field.
- *
- * @since 2.0.0
- *
- * @param {Object} props Component properties.
- * @return {Object} HTML component fragment.
- */
-export function EditField( props ) {
- let { attributes } = props,
- shouldSetupAtts = true;
-
- const { name } = props,
- block = getBlockType( name ),
- { clientId, context, setAttributes } = props,
- inspectorSupports = block.supports.llms_field_inspector,
- editFills = block.supports.llms_edit_fill,
- { fillEditAfter, fillInspectorControls } = block,
- { getSelectedBlockClientId } = select( blockEditorStore ),
- { isDuplicate } = select( fieldsStore ),
- inFieldGroup = context[ 'llms/fieldGroup/fieldLayout' ] ? true : false,
- addingField =
- attributes.name && isDuplicate( attributes.name, clientId ),
- /**
- * This identifies when a reusable block containing a multiple=false block is added
- *
- * @see {@link https://github.com/WordPress/gutenberg/issues/32863}
- */
- isReusableWithMultipleValidationError =
- ! hasBlockSupport( name, 'multiple', true ) && addingField,
- /**
- * Prevent confirmation fields from being copied/pasted into the editor out of their intended context.
- *
- * @see {@link https://github.com/gocodebox/lifterlms-blocks/issues/106}
- */
- isConfirmWhichHasBeenCopied =
- ! inFieldGroup && attributes.isConfirmationField;
-
- if (
- isReusableWithMultipleValidationError ||
- isConfirmWhichHasBeenCopied
- ) {
- shouldSetupAtts = false;
- }
-
- attributes = shouldSetupAtts
- ? setupAtts( attributes, block.attributes, addingField )
- : attributes;
-
- // Manage field data for blocks in field groups.
- if ( inFieldGroup && shouldSetupAtts ) {
- manageFieldGroupAttributes( props );
- }
-
- // Add columns CSS class.
- const blockProps = useBlockProps( {
- className: `llms-fields llms-cols-${ attributes.columns }`,
- } );
-
- // We can't disable the variation transformer by context so we'll do it this way which is gross but works.
- useEffect( () => {
- if (
- block.variations &&
- block.variations.length &&
- clientId === getSelectedBlockClientId()
- ) {
- const interval = setInterval( () => {
- const el = document.querySelector(
- '.block-editor-block-inspector .block-editor-block-variation-transforms'
- );
- if ( el ) {
- el.style.display = attributes.isConfirmationField
- ? 'none'
- : 'inline-block';
- clearInterval( interval );
- }
-
- return () => {
- clearInterval( interval );
- };
- }, 10 );
- }
- } );
-
- if (
- isReusableWithMultipleValidationError ||
- isConfirmWhichHasBeenCopied
- ) {
- let toRemove = null;
-
- if ( isReusableWithMultipleValidationError ) {
- const { createErrorNotice } = dispatch( noticesStore ),
- { getBlockHierarchyRootClientId } = select( blockEditorStore );
- toRemove = getBlockHierarchyRootClientId( clientId );
-
- createErrorNotice(
- __(
- 'The reusable block cannot be added because it contains one or more blocks which can only be used once per page.',
- 'lifterlms'
- ),
- {
- id: `llms-reusable-multiples-err-${ toRemove }`,
- isDismissible: true,
- }
- );
- } else if ( isConfirmWhichHasBeenCopied ) {
- toRemove = clientId;
- }
-
- setTimeout( () => {
- dispatch( blockEditorStore ).removeBlock( toRemove );
- }, 10 );
-
- return null;
- }
-
- return (
-
-
-
-
-
- { inspectorSupports.customFill && (
-
- { fillInspectorControls(
- attributes,
- setAttributes,
- props
- ) }
-
- ) }
-
- { editFills.after && (
-
- { fillEditAfter( attributes, setAttributes, props ) }
-
- ) }
-
- );
-}
-
-/**
- * Edit action for a field group.
- *
- * @since 2.0.0
- *
- * @param {Object} props Component properties.
- * @return {Object} HTML component fragment.
- */
-export function EditGroup( props ) {
- const { attributes, clientId, name, setAttributes } = props,
- { fieldLayout } = attributes,
- { getBlock } = select( blockEditorStore ),
- block = getBlock( clientId ),
- blockType = getBlockType( name ),
- { allowed, template, lock } = blockType.llmsInnerBlocks,
- primaryBlock =
- block &&
- block.innerBlocks.length &&
- 'llms/form-field-confirm-group' === block.name
- ? block.innerBlocks[
- blockType.findControllerBlockIndex( block.innerBlocks )
- ]
- : null,
- primaryBlockType = primaryBlock
- ? getBlockType( primaryBlock.name )
- : null,
- editFills = primaryBlockType
- ? primaryBlockType.supports.llms_edit_fill
- : { after: false },
- inspectorSupports = blockType.supports.llms_field_inspector,
- hasLayout =
- blockType.providesContext &&
- blockType.providesContext[ 'llms/fieldGroup/fieldLayout' ];
-
- let orientation = 'columns' === fieldLayout ? 'horizontal' : 'vertical';
- if ( ! hasLayout ) {
- orientation = 'vertical';
- }
-
- return (
-
-
-
- { hasLayout && (
-
- ) }
-
- { inspectorSupports.customFill &&
- blockType.fillInspectorControls(
- attributes,
- setAttributes,
- props
- ) }
-
-
-
-
-
-
-
- { editFills.after && (
-
- ) }
-
- );
-}
diff --git a/src/js/blocks/form-fields/editor.scss b/src/js/blocks/form-fields/editor.scss
deleted file mode 100644
index 8c09671d..00000000
--- a/src/js/blocks/form-fields/editor.scss
+++ /dev/null
@@ -1,165 +0,0 @@
-//
-// Editor Styles for Admin Panel
-//
-// @since 1.6.0
-// @version 1.6.0
-//
-
-.llms-invalid-control {
-
- margin-bottom: 24px;
- .components-base-control {
- margin-bottom: 0;
- .components-text-control__input {
- border-color: #cc1818;
- background-color: rgba( #cc1818, 0.05 );
- }
- }
- .llms-invalid-control--msg {
- background-color: rgba( #cc1818, 0.05 );
- border-left: 4px solid #cc1818;
- color: #cc1818;
- font-style: italic;
- font-size: 12px;
- margin-bottom: 0;
- padding: 6px 2px 6px 8px;
- }
-
-}
-
-.llms-pwd-meter {
- border: 1px solid #e35b5b;
- margin-top: 5px;
- border-radius: 4px;
- overflow: hidden;
- > div {
- background: rgba( 227, 91, 91, 0.25 );
- font-size: 75%;
- padding: 0 5px;
- width: 25%;
- }
-}
-
-.llms-fields {
-
- input,
- textarea {
- border: 1px solid #999;
- color: #757575;
- padding: 4px 8px;
- &:focus::placeholder {
- opacity: 0;
- }
- &::placeholder {
- color: #757575;
- }
- }
-
- input:not([type=radio]):not([type="checkbox"]),
- textarea,
- select {
- width: 100%;
- }
-
- input:not([type=radio]) {
- border-radius: 4px;
- }
- textarea { resize: none; }
-
- select {
- max-Width: none;
- pointer-events: none;
- }
-
- .llms-field {
-
- .block-editor-rich-text__editable {
- display: block;
- }
-
- label.llms-is-required {
- > div { display: inline; }
- &:after {
- content: '\00a0*';
- color: #dc5757;
- }
- }
-
- }
-
-}
-
-
-li.llms-field-option {
- display: flex;
-
- &.llms-sort-helper {
- background: #fff;
- border: 1px solid $color-grey-light;
- height: auto !important;
- padding: 5px 10px;
- z-index: 999;
- }
-
- .llms-field-opt-default {
- margin-top: 6px;
- .components-radio-control__input {
- margin-right: 0;
- }
- }
-
- .llms-field-opt-default,
- .llms-field-opt-text,
- .llms-field-opt-text .components-base-control__field {
- margin-bottom: 0 !important;
- }
-
- .llms-drag-handle {
- flex: 0.8;
- padding-top: 6px;
- }
-
- .llms-field-opt-default-wrap,
- .llms-del-field-opt-wrap {
- flex: 1;
- }
-
- .llms-del-field-opt-wrap {
- margin-left: 4px;
- button {
- margin-top: 3px;
- &[aria-expanded="true"], &:hover {
- color: #cc1818;
- }
- }
- }
-
- .llms-field-opt-text-wrap {
- flex: 7;
- }
-
-}
-
-.llms-cols-12 .llms-field { width: 100%; }
-.llms-cols-9 .llms-field { width: 75%; }
-.llms-cols-8 .llms-field { width: 66.66%; }
-.llms-cols-6 .llms-field { width: 50%; }
-.llms-cols-4 .llms-field { width: 33.33%; }
-.llms-cols-3 .llms-field { width: 25%; }
-
-.llms-field-group[data-field-layout="columns"] {
- [class*=llms-cols-] .llms-field { width: 100%; }
- .llms-cols-12 { width: 100%; }
- .llms-cols-9 { width: 75%; }
- .llms-cols-8 { width: 66.66%; }
- .llms-cols-6 { width: 50%; }
- .llms-cols-4 { width: 33.33%; }
- .llms-cols-3 { width: 25%; }
- .block-editor-block-list__layout {
- > .wp-block.llms-fields {
- display: inline-block;
- &:nth-child( odd ) { padding-right: 28px; }
- &:nth-child( even ) { padding-left: 28px; }
- }
- }
-}
diff --git a/src/js/blocks/form-fields/field.js b/src/js/blocks/form-fields/field.js
deleted file mode 100644
index fff90faf..00000000
--- a/src/js/blocks/form-fields/field.js
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * Generic Field component
- *
- * @since 1.6.0
- * @version 1.6.0
- */
-
-// WP deps.
-import { RichText } from '@wordpress/block-editor';
-import { __ } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { Slot } from '@wordpress/components';
-
-// Internal deps.
-import './editor.scss';
-import InputGroupOptions from './input-group-options';
-
-/**
- * Render a field in the block editor
- *
- * @since 1.6.0
- * @since 1.7.1 Add block editor rendering for password type fields.
- */
-export default class Field extends Component {
- /**
- * Determine the type of field.
- *
- * @since 1.7.1
- *
- * @return {string} Field type identifier.
- */
- getFieldType() {
- const {
- attributes: { field },
- } = this.props;
-
- if (
- -1 !== [ 'email', 'text', 'number', 'url', 'tel' ].indexOf( field )
- ) {
- return 'input';
- }
-
- return field;
- }
-
- /**
- * Render the field.
- *
- * @since 1.6.0
- * @since 1.7.1 Add rendering for password type fields.
- *
- * @return {Object} HTML Fragment.
- */
- render() {
- const { attributes, setAttributes, block, clientId } = this.props,
- { description, label, options, placeholder, required } = attributes,
- editFills = block.supports.llms_edit_fill;
-
- const classes = [];
- if ( required ) {
- classes.push( 'llms-is-required' );
- }
-
- const fieldType = this.getFieldType();
-
- /**
- * Get the default option for a select field.
- *
- * @since 1.6.0
- *
- * @return {string} Default option value.
- */
- const getDefaultOption = () => {
- if ( placeholder ) {
- return placeholder;
- }
-
- if ( ! options.length ) {
- return '';
- }
-
- let text = options[ 0 ].text;
-
- const defaults = options.filter( ( opt ) => 'yes' === opt.default );
-
- if ( defaults.length ) {
- text = defaults[ 0 ].text;
- }
-
- return text;
- };
-
- return (
-
-
- { 'html' !== fieldType && (
- {
- setAttributes( {
- label: val,
- } );
- } }
- allowedFormats={ [ 'bold', 'italic' ] }
- aria-label={
- label
- ? __( 'Field label' )
- : __(
- 'Empty field label; start writing to add a label'
- )
- }
- placeholder={ __( 'Enter a label' ) }
- />
- ) }
- { 'input' === fieldType && (
-
- setAttributes( {
- placeholder: event.target.value,
- } )
- }
- value={ placeholder }
- placeholder={ __(
- 'Add optional placeholder text',
- 'lifterlms'
- ) }
- />
- ) }
- { 'password' === fieldType && (
-
- ) }
- { 'textarea' === fieldType && (
-
-
- { editFills.after && (
-
- ) }
-
- );
- }
-}
diff --git a/src/js/blocks/form-fields/fields/checkboxes.js b/src/js/blocks/form-fields/fields/checkboxes.js
deleted file mode 100644
index fd504bff..00000000
--- a/src/js/blocks/form-fields/fields/checkboxes.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * BLOCK: llms/form-field-checkboxes
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { createBlock } from '@wordpress/blocks';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
- getDefaultOptionsArray,
-} from '../settings';
-import icon from '../../../icons/field-checkbox';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-checkboxes';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Field composition type.
- *
- * @type {string}
- */
-export const composed = false;
-
-/**
- * Block settings
- *
- * @since 1.12.0 Add transform support and default options.
- * @since 2.0.0 Major refactor for 2.0.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( getDefaultSettings(), {
- title: __( 'Checkboxes', 'lifterlms' ),
- description: __(
- 'A single checkbox toggle or a group of multiple checkboxes.',
- 'lifterlms'
- ),
- icon: {
- src: icon,
- },
- category: 'llms-custom-fields',
- supports: {
- llms_field_inspector: {
- options: true,
- },
- },
- attributes: {
- field: {
- __default: 'checkbox',
- },
- options: {
- __default: getDefaultOptionsArray( 2, 0 ),
- },
- },
- transforms: {
- from: [
- {
- type: 'block',
- blocks: [ 'llms/form-field-radio', 'llms/form-field-select' ],
- transform: ( attributes ) =>
- createBlock( name, {
- ...attributes,
- field: settings.attributes.field.__default,
- } ),
- },
- ],
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/confirm-group.js b/src/js/blocks/form-fields/fields/confirm-group.js
deleted file mode 100644
index a8e3e1e4..00000000
--- a/src/js/blocks/form-fields/fields/confirm-group.js
+++ /dev/null
@@ -1,322 +0,0 @@
-/**
- * BLOCK: llms/form-field-confirm-group
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { createBlock } from '@wordpress/blocks';
-import { dispatch, select } from '@wordpress/data';
-import { store as blockEditorStore } from '@wordpress/block-editor';
-import { Button } from '@wordpress/components';
-import { __, isRTL, sprintf } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-
-import { store as fieldsStore } from '../../../data/fields';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-confirm-group';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Retrieve block attributes for a controller block
- *
- * @since 2.0.0
- *
- * @param {Object} attributes Existing attributes to merge defaults into.
- * @return {Object} Updated block attributes.
- */
-function getControllerBlockAttrs( attributes = {} ) {
- return {
- ...attributes,
- columns: 6,
- last_column: false,
- isConfirmationControlField: true,
- llms_visibility: 'off',
- };
-}
-
-/**
- * Retrieve block attributes for a controlled (confirmation) block
- *
- * @since 2.0.0
- *
- * @param {Object} attributes Existing attributes to merge defaults into.
- * @return {Object} Updated block attributes.
- */
-function getControlledBlockAttrs( attributes = {} ) {
- return {
- ...attributes,
- label: attributes.label
- ? // Translators: %s label of the controller field.
- sprintf( __( 'Confirm %s', 'lifterlms' ), attributes.label )
- : '',
- columns: 6,
- last_column: true,
- data_store: false,
- data_store_key: false,
- isConfirmationField: true,
- llms_visibility: 'off',
- };
-}
-
-/**
- * Revert the confirmation group to a single field
- *
- * Replaces the group block with the controller block (first inner child) of the group.
- *
- * @since 2.0.0
- *
- * @param {string} clientId Client ID of the group block.
- * @return {void}
- */
-function revertToSingle( clientId ) {
- const { getBlock } = select( blockEditorStore ),
- { replaceBlock } = dispatch( blockEditorStore ),
- block = getBlock( clientId ),
- { innerBlocks } = block,
- { llms_visibility } = block.attributes,
- { name, attributes } = innerBlocks[
- findControllerBlockIndex( innerBlocks )
- ];
-
- doFieldUnload( attributes.name );
-
- replaceBlock(
- clientId,
- createBlock( name, {
- ...attributes,
- columns: 12,
- last_column: true,
- isConfirmationControlField: false,
- match: '',
- llms_visibility,
- } )
- );
-}
-
-/**
- * Unloads field immediately prior to running block transforms
- *
- * During transformations fields will show up as duplicates if we rely
- * on the blocks-watcher to unload fields, to combat this
- * we'll unload the fields manually before the transformations are
- * run.
- *
- * @since 2.0.0
- *
- * @param {string} name Field name attribute.
- * @return {void}
- */
-function doFieldUnload( name ) {
- const { unloadField } = dispatch( fieldsStore );
- unloadField( name );
-}
-
-/**
- * Allowed blocks list.
- *
- * @type {string[]}
- */
-const allowed = [
- 'llms/form-field-text',
- 'llms/form-field-user-email',
- 'llms/form-field-user-login',
- 'llms/form-field-user-password',
-];
-
-/**
- * Block transforms.
- *
- * @type {Object}
- */
-const transforms = {
- from: [],
- to: [],
-};
-
-/**
- * Create a block transform for each of the allowed blocks
- *
- * When creating a confirm group from a single block the first child
- * should be a direct copy of the block itself (EG: user-email -> user->email).
- *
- * The second child should be a simple text block with the type of the first block
- * (eg: user-email to text with a field type email).
- *
- * Therefore each transform is identical except for the block type of the first child
- * block.
- *
- * @since 2.0.0
- *
- * @param {string} blockName Name of the block being transformed into a group.
- * @return {void}
- */
-allowed.forEach( ( blockName ) => {
- transforms.from.push( {
- type: 'block',
- blocks: [ blockName ],
- transform: ( attributes ) => {
- const { llms_visibility } = attributes;
-
- doFieldUnload( attributes.name );
-
- const children = [
- createBlock( blockName, getControllerBlockAttrs( attributes ) ),
- createBlock(
- 'llms/form-field-text',
- getControlledBlockAttrs( attributes )
- ),
- ];
-
- return createBlock(
- name,
- { llms_visibility },
- isRTL() ? children.reverse() : children
- );
- },
- } );
-
- transforms.to.push( {
- type: 'block',
- blocks: [ blockName ],
- isMatch: () => {
- const { getSelectedBlock } = select( blockEditorStore ),
- { innerBlocks } = getSelectedBlock(),
- controllerBlock =
- innerBlocks[ findControllerBlockIndex( innerBlocks ) ],
- { name } = controllerBlock || {};
-
- return name === blockName;
- },
- transform: ( groupAttributes, innerBlocks ) => {
- const { llms_visibility } = groupAttributes,
- controllerBlock =
- innerBlocks[ findControllerBlockIndex( innerBlocks ) ],
- { name, attributes } = controllerBlock;
-
- doFieldUnload( attributes.name );
-
- return createBlock( name, {
- ...attributes,
- columns: 12,
- last_column: true,
- isConfirmationControlField: false,
- match: '',
- llms_visibility,
- } );
- },
- } );
-} );
-
-/**
- * Fill the controls slot with additional controls specific to this field.
- *
- * @since 2.0.0
- * @param {Object} attributes Block attributes.
- * @param {Function} setAttributes Reference to the block's setAttributes() function.
- * @param {Object} props Block properties.
- * @return {Button} Component HTML Fragment.
- */
-const fillInspectorControls = ( attributes, setAttributes, props ) => {
- const { clientId } = props;
-
- return (
- revertToSingle( clientId ) }>
- { __( 'Remove confirmation field', 'lifterlms' ) }
-
- );
-};
-
-/**
- * Finds the index of the primary (controller) field in the group
- *
- * @since 2.0.0
- *
- * @param {Object[]} innerBlocks ) Inner blocks array.
- * @return {number} Array index of the primary block within the inner blocks array.
- */
-const findControllerBlockIndex = ( innerBlocks ) =>
- innerBlocks.findIndex(
- ( { attributes } ) => attributes.isConfirmationControlField
- );
-
-/**
- * Block settings
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( getDefaultSettings( 'group' ), {
- title: __( 'Input Confirmation Group', 'lifterlms' ),
- description: __(
- 'Adds a required confirmation field to an input field.',
- 'lifterlms'
- ),
- icon: {
- src: 'controls-repeat',
- },
- category: 'llms-custom-fields',
- transforms,
- fillInspectorControls,
- findControllerBlockIndex,
- supports: {
- llms_field_inspector: {
- customFill: 'confirmGroupAdditionalControls',
- },
- inserter: false,
- },
- llmsInnerBlocks: {
- allowed,
-
- /**
- * Create block template depending on it's innerBlocks
- *
- * If the block has no children, setup matching text fields (type can be changed later).
- *
- * Otherwise pass in `null` which will allow various composed fields to be setup through
- * transformation. They'll be locked by template locking even though no template is provided.
- *
- * @since 2.0.0
- *
- * @param {Object} options
- * @param {?Object} options.block Block object.
- * @return {?Array} An InnerBlocks template array.
- */
- template: ( { block } ) => {
- let template = null;
-
- if ( ! block || ! block.innerBlocks.length ) {
- template = [
- [ 'llms/form-field-text', getControllerBlockAttrs() ],
- [ 'llms/form-field-text', getControlledBlockAttrs() ],
- ];
- }
-
- return template;
- },
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/radio.js b/src/js/blocks/form-fields/fields/radio.js
deleted file mode 100644
index a9702ec3..00000000
--- a/src/js/blocks/form-fields/fields/radio.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * BLOCK: llms/form-field-radio
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { createBlock } from '@wordpress/blocks';
-
-// Internal Deps.
-import {
- getSettingsFromBase,
- getDefaultPostTypes,
- getDefaultOptionsArray,
-} from '../settings';
-import icon from '../../../icons/field-radio';
-import { settings as baseSettings } from './checkboxes';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-radio';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Field composition type.
- *
- * @type {string}
- */
-export const composed = false;
-
-/**
- * Block settings
- *
- * @since 1.12.0 Add transform support and default options.
- * @since 2.0.0 Add reusable block support.
- * @since 2.0.0 Add default keys.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( baseSettings, {
- title: __( 'Radio', 'lifterlms' ),
- description: __(
- 'A group of radio inputs which can be populated with any number of options.',
- 'lifterlms'
- ),
- icon: {
- src: icon,
- },
- attributes: {
- field: {
- __default: 'radio',
- },
- options: {
- __default: getDefaultOptionsArray( 2, 1 ),
- },
- },
- transforms: {
- from: [
- {
- type: 'block',
- blocks: [
- 'llms/form-field-checkboxes',
- 'llms/form-field-select',
- ],
- transform: ( attributes ) =>
- createBlock( name, {
- ...attributes,
- field: settings.attributes.field.__default,
- } ),
- },
- ],
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/redeem-voucher.js b/src/js/blocks/form-fields/fields/redeem-voucher.js
deleted file mode 100644
index ab0ef80b..00000000
--- a/src/js/blocks/form-fields/fields/redeem-voucher.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * BLOCK: llms/form-field-redeem-voucher
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { ToggleControl } from '@wordpress/components';
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-redeem-voucher';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Fill the controls slot with additional controls specific to this field.
- *
- * @since 1.6.0
- *
- * @param {Object} attributes Block attributes.
- * @param {Function} setAttributes Reference to the block's setAttributes() function.
- * @return {ToggleControl} Component HTML fragment.
- */
-const fillInspectorControls = ( attributes, setAttributes ) => {
- const { toggleable, required } = attributes;
-
- if ( required ) {
- return null;
- }
-
- return (
- setAttributes( { toggleable: ! toggleable } ) }
- help={
- !! toggleable
- ? __(
- 'Field is revealed when the toggle is clicked.',
- 'lifterlms'
- )
- : __( 'Field is always visible.', 'lifterlms' )
- }
- />
- );
-};
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'Voucher Code Redemption', 'lifterlms' ),
- description: __(
- 'Allows user to redeem a voucher code during account registration.',
- 'lifterlms'
- ),
- icon: {
- src: 'tickets-alt',
- },
- supports: {
- inserter: true,
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- storage: false,
- customFill: 'redeemVoucher',
- },
- },
- attributes: {
- id: {
- __default: 'llms_voucher',
- },
- field: {
- __default: 'text',
- },
- label: {
- __default: __( 'Have a voucher?', 'lifterlms' ),
- },
- name: {
- __default: 'llms_voucher',
- },
- placeholder: {
- __default: __( 'Voucher Code', 'lifterlms' ),
- },
- data_store: {
- __default: false,
- },
- data_store_key: {
- __default: false,
- },
-
- toggleable: {
- __default: false,
- },
- },
- fillInspectorControls,
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/select.js b/src/js/blocks/form-fields/fields/select.js
deleted file mode 100644
index 5175f90e..00000000
--- a/src/js/blocks/form-fields/fields/select.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * BLOCK: llms/form-field-select
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import { createBlock } from '@wordpress/blocks';
-
-// Internal Deps.
-import { getSettingsFromBase, getDefaultPostTypes } from '../settings';
-import icon from '../../../icons/field-select';
-import { settings as baseSettings } from './radio';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-select';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Field composition type.
- *
- * @type {string}
- */
-export const composed = false;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.12.0 Add transform support and default options.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( baseSettings, {
- title: __( 'Dropdown', 'lifterlms' ),
- description: __(
- 'A select field which can be populated with any number of options.',
- 'lifterlms'
- ),
- icon: {
- src: icon,
- },
- attributes: {
- field: {
- __default: 'select',
- },
- },
- supports: {
- llms_field_inspector: {
- placeholder: true,
- },
- },
- transforms: {
- from: [
- {
- type: 'block',
- blocks: [
- 'llms/form-field-checkboxes',
- 'llms/form-field-radio',
- ],
- transform: ( attributes ) =>
- createBlock( name, {
- ...attributes,
- field: settings.attributes.field.__default,
- } ),
- },
- ],
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/text.js b/src/js/blocks/form-fields/fields/text.js
deleted file mode 100644
index 8f8d2f6f..00000000
--- a/src/js/blocks/form-fields/fields/text.js
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * BLOCK: llms/form-field-text
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { TextControl } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-import defaultIcon from '../../../icons/field-text';
-import numberIcon from '../../../icons/field-number';
-
-const baseSettings = getDefaultSettings();
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-text';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block Variations
- *
- * @type {Object[]}
- */
-const variations = [
- {
- name: 'text',
- title: __( 'Text', 'lifterlms' ),
- description: __(
- 'An input field which accepts any form of text.',
- 'lifterlms'
- ),
- isDefault: true,
- icon: defaultIcon,
- },
- {
- name: 'email',
- title: __( 'Email', 'lifterlms' ),
- description: __(
- 'A text input field which only accepts an email address.',
- 'lifterlms'
- ),
- icon: 'email-alt',
- },
- {
- name: 'password',
- title: __( 'Password', 'lifterlms' ),
- description: __( 'User password confirmation field.', 'lifterlms' ),
- icon: 'lock',
- scope: [],
- },
- {
- name: 'number',
- title: __( 'Number', 'lifterlms' ),
- description: __(
- 'An input field which only accepts numeric input.',
- 'lifterlms'
- ),
- icon: numberIcon,
- attributes: {
- html_attrs: {
- min: '',
- max: '',
- },
- },
- },
- {
- name: 'tel',
- title: __( 'Phone Number', 'lifterlms' ),
- description: __(
- 'An input field which only accepts phone numbers.',
- 'lifterlms'
- ),
- icon: 'phone',
- },
- {
- name: 'url',
- title: __( 'Website Address / URL', 'lifterlms' ),
- description: __(
- 'An input field which only accepts a website address or URL.',
- 'lifterlms'
- ),
- icon: 'admin-links',
- },
-];
-
-/**
- * Add information to each variation
- *
- * @since 2.0.0
- *
- * @param {Object} variation A block variation object.
- * @return {Object[]} Update block variations array.
- */
-variations.forEach( ( variation ) => {
- // Setup scope.
- variation.scope = variation.scope || [ 'block', 'inserter', 'transform' ];
-
- // Update the icon (add the default foreground color.
- variation.icon = {
- ...baseSettings.icon,
- src: variation.icon,
- };
-
- // Add a "field" attribute based off the variation name.
- if ( ! variation.attributes ) {
- variation.attributes = {};
- }
- variation.attributes.field = variation.name;
-
- // Add an isActive function.
- variation.isActive = ( blockAttributes, variationAttributes ) =>
- blockAttributes.field === variationAttributes.field;
-} );
-
-/**
- * Fill the controls slot with additional controls specific to this field.
- *
- * @since 2.0.0
- *
- * @param {Object} attributes Block attributes.
- * @param {Function} setAttributes Reference to the block's setAttributes() function.
- * @return {Fragment} Component HTML Fragment.
- */
-const fillInspectorControls = ( attributes, setAttributes ) => {
- // We only add extra controls to the number variation.
- if ( attributes.isConfirmationField || 'number' !== attributes.field ) {
- return;
- }
-
- // Add min/max options to a number field.
- const { html_attrs } = attributes,
- { min, max } = html_attrs;
-
- return (
-
-
- setAttributes( { html_attrs: { ...html_attrs, min } } )
- }
- />
-
-
- setAttributes( { html_attrs: { ...html_attrs, max } } )
- }
- />
-
- );
-};
-
-/**
- * Block settings
- *
- * @since 2.0.0
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( baseSettings, {
- title: __( 'Text', 'lifterlms' ),
- description: __( 'A simple text input field.', 'lifterlms' ),
- icon: {
- src: defaultIcon,
- },
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- supports: {
- inserter: false,
- llms_field_inspector: {
- customFill: 'fieldTextAdditionalControls',
- },
- },
- variations,
- fillInspectorControls,
-} );
diff --git a/src/js/blocks/form-fields/fields/textarea.js b/src/js/blocks/form-fields/fields/textarea.js
deleted file mode 100644
index 0322e180..00000000
--- a/src/js/blocks/form-fields/fields/textarea.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * BLOCK: llms/form-field-textarea
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { createBlock } from '@wordpress/blocks';
-import { TextControl } from '@wordpress/components';
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-textarea';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = false;
-
-/**
- * Fill the controls slot with additional controls specific to this field.
- *
- * @since 1.12.0
- * @since 2.0.0 Update to use `html_attrs.rows` in favor of `attributes.rows`.
- *
- * @param {Object} attributes Block attributes.
- * @param {Function} setAttributes Reference to the block's setAttributes() function.
- * @return {TextControl} Component html fragment.
- */
-const fillInspectorControls = ( attributes, setAttributes ) => {
- const { html_attrs } = attributes,
- { rows } = html_attrs;
-
- return (
-
- setAttributes( { html_attrs: { ...html_attrs, rows } } )
- }
- min="2"
- step="1"
- />
- );
-};
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 2.0.0 Refactor for 2.0.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'Textarea', 'lifterlms' ),
- description: __(
- 'A text field accepting multiple lines of user information.',
- 'lifterlms'
- ),
- icon: {
- src: 'editor-paragraph',
- },
- category: 'llms-custom-fields',
- supports: {
- inserter: true,
- llms_field_inspector: {
- customFill: 'fieldTextarea',
- },
- },
- attributes: {
- field: {
- __default: 'textarea',
- },
- html_attrs: {
- __default: {
- rows: 4,
- },
- },
- },
- fillInspectorControls,
- transforms: {
- from: [
- {
- type: 'block',
- blocks: [ 'llms/form-field-text' ],
- transform: ( attributes ) =>
- createBlock( name, {
- ...attributes,
- html_attrs: {
- ...attributes.html_attrs,
- rows: 4,
- },
- field: 'textarea',
- } ),
- },
- ],
- to: [
- {
- type: 'block',
- blocks: [ 'llms/form-field-text' ],
- transform: ( attributes ) =>
- createBlock( 'llms/form-field-text', {
- ...attributes,
- field: 'text',
- } ),
- },
- ],
- },
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-city.js b/src/js/blocks/form-fields/fields/user-address-city.js
deleted file mode 100644
index 50899b38..00000000
--- a/src/js/blocks/form-fields/fields/user-address-city.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-city
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-city';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User City', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's billing city.",
- 'lifterlms'
- ),
- icon: {
- src: 'location-alt',
- },
- supports: {
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- match: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_billing_city',
- },
- label: {
- __default: __( 'City', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_city',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_billing_city',
- },
- },
- parent: [ 'llms/form-field-user-address' ],
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-country.js b/src/js/blocks/form-fields/fields/user-address-country.js
deleted file mode 100644
index 40657a0c..00000000
--- a/src/js/blocks/form-fields/fields/user-address-country.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-country
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './select';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-country';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Country', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's billing country.",
- 'lifterlms'
- ),
- icon: {
- src: 'admin-site',
- },
- supports: {
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- match: false,
- storage: false,
- options: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_billing_country',
- },
- label: {
- __default: __( 'Country', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_country',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_billing_country',
- },
- options_preset: {
- __default: 'countries',
- },
- placeholder: {
- __default: __( 'Select a Country', 'lifterlms' ),
- },
- },
- parent: [ 'llms/form-field-user-address' ],
- },
- [ 'transforms' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-postal-code.js b/src/js/blocks/form-fields/fields/user-address-postal-code.js
deleted file mode 100644
index 0ff656f0..00000000
--- a/src/js/blocks/form-fields/fields/user-address-postal-code.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-postal-code
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-postal-code';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Postal Code', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's postal or zip code.",
- 'lifterlms'
- ),
- icon: {
- src: 'post-status',
- },
- supports: {
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- match: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_billing_zip',
- },
- label: {
- __default: __( 'Postal / Zip Code', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_zip',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_billing_zip',
- },
- },
- parent: [ 'llms/form-field-user-address-region' ],
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-region.js b/src/js/blocks/form-fields/fields/user-address-region.js
deleted file mode 100644
index 3c0b4568..00000000
--- a/src/js/blocks/form-fields/fields/user-address-region.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-region
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-region';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.12.0 Add transform support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( getDefaultSettings( 'group' ), {
- title: __( 'User Street Address', 'lifterlms' ),
- description: __( "Collect a user's street address.", 'lifterlms' ),
- icon: {
- src: 'id-alt',
- },
- supports: {
- multiple: false,
- },
- parent: [ 'llms/form-field-user-name' ],
- llmsInnerBlocks: {
- allowed: [
- 'llms/form-field-user-address-state',
- 'llms/form-field-user-address-postal-code',
- ],
- template: [
- [
- 'llms/form-field-user-address-state',
- { columns: 6, last_column: false },
- ],
- [
- 'llms/form-field-user-address-postal-code',
- { columns: 6, last_column: true },
- ],
- ],
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/user-address-state.js b/src/js/blocks/form-fields/fields/user-address-state.js
deleted file mode 100644
index 3ccf23d7..00000000
--- a/src/js/blocks/form-fields/fields/user-address-state.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-state
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './select';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-state';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Country', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's billing country.",
- 'lifterlms'
- ),
- icon: {
- src: 'location',
- },
- supports: {
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- storage: false,
- options: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_billing_state',
- },
- label: {
- __default: __( 'State / Region', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_state',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_billing_state',
- },
- options_preset: {
- __default: 'states',
- },
- placeholder: {
- __default: __( 'Select a State / Region', 'lifterlms' ),
- },
- },
- parent: [ 'llms/form-field-user-address-region' ],
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- },
- [ 'transforms' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-street-primary.js b/src/js/blocks/form-fields/fields/user-address-street-primary.js
deleted file mode 100644
index 99a3b638..00000000
--- a/src/js/blocks/form-fields/fields/user-address-street-primary.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-street-primary
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-street-primary';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Street Address', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's street address.",
- 'lifterlms'
- ),
- icon: {
- src: 'admin-home',
- },
- supports: {
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_billing_address_1',
- },
- label: {
- __default: __( 'Address', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_address_1',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_billing_address_1',
- },
- },
- parent: [ 'llms/form-field-user-address-street' ],
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-street-secondary.js b/src/js/blocks/form-fields/fields/user-address-street-secondary.js
deleted file mode 100644
index 25ba2c5c..00000000
--- a/src/js/blocks/form-fields/fields/user-address-street-secondary.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-street-secondary
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- settings as baseSettings,
- postTypes,
-} from './user-address-street-primary';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-street-secondary';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Street Address Additional Information', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's street address.",
- 'lifterlms'
- ),
- attributes: {
- id: {
- __default: 'llms_billing_address_2',
- },
- label: {
- __default: '',
- },
- placeholder: {
- __default: __( 'Apartment, suite, etc…', 'lifterlms' ),
- },
- name: {
- __default: 'llms_billing_address_2',
- },
- required: {
- __default: false,
- },
- data_store_key: {
- __default: 'llms_billing_address_2',
- },
- label_show_empty: {
- __default: true,
- },
- },
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-address-street.js b/src/js/blocks/form-fields/fields/user-address-street.js
deleted file mode 100644
index 8245b83b..00000000
--- a/src/js/blocks/form-fields/fields/user-address-street.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address-street
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-
-/**
- * Block Namer
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address-street';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block Settings
- *
- * @since 1.6.0
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( getDefaultSettings( 'group' ), {
- title: __( 'User Street Address', 'lifterlms' ),
- description: __( "Collect a user's street address.", 'lifterlms' ),
- icon: {
- src: 'id-alt',
- },
- supports: {
- multiple: false,
- },
- llmsInnerBlocks: {
- allowed: [
- 'llms/form-field-user-address-street-primary',
- 'llms/form-field-user-address-street-secondary',
- ],
- template: [
- [
- 'llms/form-field-user-address-street-primary',
- { columns: 8, last_column: false },
- ],
- [
- 'llms/form-field-user-address-street-secondary',
- { columns: 4, last_column: true },
- ],
- ],
- },
- parent: [ 'llms/form-field-user-name' ],
-} );
diff --git a/src/js/blocks/form-fields/fields/user-address.js b/src/js/blocks/form-fields/fields/user-address.js
deleted file mode 100644
index c67c791e..00000000
--- a/src/js/blocks/form-fields/fields/user-address.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-address
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-address';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {boolean}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.12.0 Add transform support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- getDefaultSettings( 'group' ),
- {
- title: __( 'User Address', 'lifterlms' ),
- description: __(
- "A group of fields used to collect a user's full address.",
- 'lifterlms'
- ),
- icon: {
- src: 'id-alt',
- },
- supports: {
- inserter: true,
- multiple: false,
- },
- llmsInnerBlocks: {
- allowed: [
- 'llms/form-field-user-address-street',
- 'llms/form-field-user-address-city',
- 'llms/form-field-user-address-country',
- 'llms/form-field-user-address-region',
- ],
- template: [
- [ 'llms/form-field-user-address-street' ],
- [ 'llms/form-field-user-address-city' ],
- [ 'llms/form-field-user-address-country' ],
- [ 'llms/form-field-user-address-region' ],
- ],
- },
- },
- [ 'providesContext' ]
-);
diff --git a/src/js/blocks/form-fields/fields/user-display-name.js b/src/js/blocks/form-fields/fields/user-display-name.js
deleted file mode 100644
index 0c464791..00000000
--- a/src/js/blocks/form-fields/fields/user-display-name.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-display-name
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-display-name';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 2.0.0
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Display Name', 'lifterlms' ),
- description: __(
- 'Allows a user to choose how their name will be displayed publicly on the site.',
- 'lifterlms'
- ),
- icon: {
- src: 'nametag',
- },
- supports: {
- inserter: true,
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'display_name',
- },
- field: {
- __default: 'text',
- },
- label: {
- __default: __( 'Display Name', 'lifterlms' ),
- },
- name: {
- __default: 'display_name',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'users',
- },
- data_store_key: {
- __default: 'display_name',
- },
- },
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-email.js b/src/js/blocks/form-fields/fields/user-email.js
deleted file mode 100644
index 47c9171c..00000000
--- a/src/js/blocks/form-fields/fields/user-email.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-email
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-email';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Email', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's account email address.",
- 'lifterlms'
- ),
- icon: {
- src: 'email-alt',
- },
- supports: {
- inserter: true,
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'email_address',
- },
- field: {
- __default: 'email',
- },
- label: {
- __default: __( 'Email Address', 'lifterlms' ),
- },
- name: {
- __default: 'email_address',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'users',
- },
- data_store_key: {
- __default: 'user_email',
- },
- },
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-first-name.js b/src/js/blocks/form-fields/fields/user-first-name.js
deleted file mode 100644
index f242dcf8..00000000
--- a/src/js/blocks/form-fields/fields/user-first-name.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-first-name
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-first-name';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'First Name', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's first name.",
- 'lifterlms'
- ),
- icon: {
- src: 'admin-users',
- },
- supports: {
- multiple: false, // Can only have a single email address field.
- llms_field_inspector: {
- id: false,
- name: false,
- required: true,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'first_name',
- },
- field: {
- __default: 'text',
- },
- label: {
- __default: __( 'First Name', 'lifterlms' ),
- },
- name: {
- __default: 'first_name',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'first_name',
- },
- },
- parent: [ 'llms/form-field-user-name' ],
- usesContext: [ 'llms/fieldGroup/fieldLayout' ],
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-last-name.js b/src/js/blocks/form-fields/fields/user-last-name.js
deleted file mode 100644
index b18eff44..00000000
--- a/src/js/blocks/form-fields/fields/user-last-name.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-last-name
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './user-first-name';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-last-name';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( baseSettings, {
- title: __( 'Last Name', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's last name.",
- 'lifterlms'
- ),
- attributes: {
- id: {
- __default: 'last_name',
- },
- label: {
- __default: __( 'Last Name', 'lifterlms' ),
- },
- name: {
- __default: 'last_name',
- },
- data_store_key: {
- __default: 'last_name',
- },
- },
-} );
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-login.js b/src/js/blocks/form-fields/fields/user-login.js
deleted file mode 100644
index b45b6dad..00000000
--- a/src/js/blocks/form-fields/fields/user-login.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-login
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-login';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 2.0.0
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Login', 'lifterlms' ),
- description: __(
- "Field used to collect a user's account username. If this field is omitted a username will be automatically generated based off their email address. Users can always login using either their email address or username.",
- 'lifterlms'
- ),
- icon: {
- src: 'admin-users',
- },
- supports: {
- inserter: true,
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- required: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'user_login',
- },
- field: {
- __default: 'text',
- },
- label: {
- __default: __( 'Username', 'lifterlms' ),
- },
- name: {
- __default: 'user_login',
- },
- required: {
- __default: true,
- },
- data_store: {
- __default: 'users',
- },
- data_store_key: {
- __default: 'user_login',
- },
- llms_visibility: {
- default: 'logged_out',
- },
- },
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-names.js b/src/js/blocks/form-fields/fields/user-names.js
deleted file mode 100644
index 1019ec3c..00000000
--- a/src/js/blocks/form-fields/fields/user-names.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * BLOCK: llms/form-field-passwords
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import {
- default as getDefaultSettings,
- getSettingsFromBase,
- getDefaultPostTypes,
-} from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-name';
-
-/**
- * Array of supported post types.
- *
- * @type {Array}
- */
-export const postTypes = getDefaultPostTypes();
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 2.0.0
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase( getDefaultSettings( 'group' ), {
- title: __( 'User name', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's first and last name.",
- 'lifterlms'
- ),
- icon: {
- src: 'admin-users',
- },
- supports: {
- inserter: true,
- multiple: false,
- },
- llmsInnerBlocks: {
- allowed: [
- 'llms/form-field-user-first-name',
- 'llms/form-field-user-last-name',
- ],
- template: [
- [
- 'llms/form-field-user-first-name',
- { columns: 6, last_column: false },
- ],
- [
- 'llms/form-field-user-last-name',
- { columns: 6, last_column: true },
- ],
- ],
- },
-} );
diff --git a/src/js/blocks/form-fields/fields/user-password.js b/src/js/blocks/form-fields/fields/user-password.js
deleted file mode 100644
index bea5bfda..00000000
--- a/src/js/blocks/form-fields/fields/user-password.js
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-password
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-import {
- SelectControl,
- TextControl,
- ToggleControl,
-} from '@wordpress/components';
-import { RichText } from '@wordpress/block-editor';
-import { Fragment } from '@wordpress/element';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-password';
-
-export const composed = true;
-
-const fillEditAfter = ( attributes, setAttributes ) => {
- const { meter, meter_description } = attributes;
-
- if ( ! meter ) {
- return;
- }
-
- return (
-
-
-
{ __( 'Very Weak', 'lifterlms' ) }
-
-
- setAttributes( { meter_description } )
- }
- allowedFormats={ [ 'core/bold', 'core/italic' ] }
- aria-label={
- meter_description
- ? __(
- 'Password strength meter description',
- 'lifterlms'
- )
- : __(
- 'Empty Password strength meter description; start writing to add a label'
- )
- }
- placeholder={ __(
- 'Enter a description for the password strength meter',
- 'lifterlms'
- ) }
- />
-
- );
-};
-
-/**
- * Fill the controls slot with additional controls specific to this field.
- *
- * @since 2.0.0
- *
- * @param {Object} attributes Block attributes.
- * @param {Function} setAttributes Reference to the block's setAttributes() function.
- * @return {Fragment} Component HTML Fragment.
- */
-const fillInspectorControls = ( attributes, setAttributes ) => {
- const { isConfirmationField, meter, min_strength, html_attrs } = attributes,
- { minlength } = html_attrs;
-
- if ( isConfirmationField ) {
- return;
- }
-
- return (
-
- setAttributes( { meter: ! meter } ) }
- />
-
- { meter && (
-
- setAttributes( { min_strength } )
- }
- options={ [
- { value: 'strong', label: __( 'Strong', 'lifterlms' ) },
- { value: 'medium', label: __( 'Medium', 'lifterlms' ) },
- { value: 'weak', label: __( 'Weak', 'lifterlms' ) },
- ] }
- />
- ) }
-
-
- setAttributes( {
- html_attrs: {
- ...html_attrs,
- minlength: val * 1,
- },
- } )
- }
- />
-
- );
-};
-
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Password', 'lifterlms' ),
- description: __(
- "A special field used to collect a user's account password.",
- 'lifterlms'
- ),
- icon: {
- src: 'lock',
- },
- supports: {
- inserter: true,
- multiple: false, // Can only have a single user password field.
- llms_field_inspector: {
- id: false,
- name: false,
- required: false,
- storage: false,
- customFill: 'userPassAdditionalControls',
- },
- llms_edit_fill: {
- after: 'userPassStrengthMeter',
- },
- },
- attributes: {
- // Defaults.
- id: {
- __default: 'password',
- },
- field: {
- __default: 'password',
- },
- label: {
- __default: __( 'Password', 'lifterlms' ),
- },
- name: {
- __default: 'password',
- },
- required: {
- __default: true,
- },
- match: {
- __default: 'password_confirm',
- },
- data_store: {
- __default: 'users',
- },
- data_store_key: {
- __default: 'user_pass',
- },
-
- // Extra attributes.
- meter: {
- type: 'boolean',
- __default: true,
- },
- meter_description: {
- type: 'string',
- __default: __(
- 'A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.',
- 'lifterlms'
- ),
- },
- min_strength: {
- type: 'string',
- __default: 'strong',
- },
- html_attrs: {
- __default: {
- minlength: 8,
- },
- },
- },
- fillEditAfter,
- fillInspectorControls,
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/fields/user-phone.js b/src/js/blocks/form-fields/fields/user-phone.js
deleted file mode 100644
index 3d0d4932..00000000
--- a/src/js/blocks/form-fields/fields/user-phone.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * BLOCK: llms/form-field-user-email
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import { __ } from '@wordpress/i18n';
-
-// Internal Deps.
-import { settings as baseSettings, postTypes } from './text';
-import { getSettingsFromBase } from '../settings';
-
-/**
- * Block Name
- *
- * @type {string}
- */
-export const name = 'llms/form-field-user-phone';
-
-/**
- * Is this a default or composed field?
- *
- * @type {string}
- */
-export const composed = true;
-
-/**
- * Block settings
- *
- * @since 1.6.0
- * @since 1.12.0 Add data store support.
- * @since 2.0.0 Add reusable block support.
- *
- * @type {Object}
- */
-export const settings = getSettingsFromBase(
- baseSettings,
- {
- title: __( 'User Phone', 'lifterlms' ),
- description: __(
- "A field used to collect a user's phone number.",
- 'lifterlms'
- ),
- icon: {
- src: 'phone',
- },
- supports: {
- inserter: true,
- multiple: false,
- llms_field_inspector: {
- id: false,
- name: false,
- storage: false,
- },
- },
- attributes: {
- id: {
- __default: 'llms_phone',
- },
- field: {
- __default: 'tel',
- },
- label: {
- __default: __( 'Phone Number', 'lifterlms' ),
- },
- name: {
- __default: 'llms_phone',
- },
- data_store: {
- __default: 'usermeta',
- },
- data_store_key: {
- __default: 'llms_phone',
- },
- },
- },
- [ 'transforms', 'variations' ]
-);
-
-export { postTypes };
diff --git a/src/js/blocks/form-fields/group-data.js b/src/js/blocks/form-fields/group-data.js
deleted file mode 100644
index 98de58ac..00000000
--- a/src/js/blocks/form-fields/group-data.js
+++ /dev/null
@@ -1,148 +0,0 @@
-// WP deps.
-import { dispatch, select } from '@wordpress/data';
-
-// Exterenal deps.
-import { find, isEmpty, merge } from 'lodash';
-
-/**
- * Retrieve a list of field group blocks
- *
- * @since 2.0.0
- *
- * @return {?Array.} Array of supporting block objects
- */
-function getSupportingParents() {
- const { getBlockTypes, hasBlockSupport } = select( 'core/blocks' );
- return getBlockTypes().filter( ( block ) =>
- hasBlockSupport( block, 'llms_field_group' )
- );
-}
-
-/**
- * Retrieve the field group parent for a given block
- *
- * @since 2.0.0
- *
- * @param {string} clientId The client ID of an existing block.
- * @return {Object} WP Block object of the parent.
- */
-function getParentFieldGroup( clientId ) {
- const { getBlock, getBlockParentsByBlockName } = select(
- 'core/block-editor'
- );
- return getBlock(
- getBlockParentsByBlockName(
- clientId,
- getSupportingParents().map( ( { name } ) => name )
- )
- );
-}
-
-/**
- * Retrieve the sibling block for a block in a field group
- *
- * @since 2.0.0
- *
- * @param {string} clientId The client ID of an existing block.
- * @return {?Object} WP Block object of the sibling.
- */
-function getSibling( clientId ) {
- const parent = getParentFieldGroup( clientId );
- return parent && parent.innerBlocks.length
- ? find( parent.innerBlocks, ( block ) => block.clientId !== clientId )
- : null;
-}
-
-function updateChildren( {
- setAttributes,
- currentUpdates,
- siblingClientId,
- siblingUpdates,
-} = {} ) {
- const { updateBlockAttributes } = dispatch( 'core/block-editor' );
-
- /**
- * Persist the staged updates.
- *
- * The setTimeout is bad but fixes no-op/memory leak.
- *
- * @see https://github.com/WordPress/gutenberg/issues/21049#issuecomment-632134201
- */
- setTimeout( () => {
- if ( ! isEmpty( currentUpdates ) ) {
- setAttributes( currentUpdates );
- }
-
- if ( siblingClientId && ! isEmpty( siblingUpdates ) ) {
- updateBlockAttributes( siblingClientId, siblingUpdates );
- }
- } );
-}
-
-function getConfirmGroupUpdates( attributes, siblingAttributes ) {
- const currentUpdates = {},
- siblingUpdates = {};
-
- // Updates matching, id, & name fields.
- if ( attributes.isConfirmationControlField ) {
- const { name, id } = attributes,
- confirmName = `${ name }_confirm`,
- confirmId = `${ id }_confirm`;
-
- siblingUpdates.match = id;
- siblingUpdates.name = confirmName;
- siblingUpdates.id = confirmId;
-
- currentUpdates.match = confirmId;
- }
-
- // Sync required attribute between grouped fields.
- if ( attributes.required !== siblingAttributes.required ) {
- siblingUpdates.required = attributes.required;
- }
-
- // Sync the field variation type.
- if ( attributes.field !== siblingAttributes.field ) {
- siblingUpdates.field = attributes.field;
- }
-
- return {
- currentUpdates,
- siblingUpdates,
- };
-}
-
-export default function ( { attributes, clientId, setAttributes } = {} ) {
- const sibling = getSibling( clientId );
-
- let currentUpdates = {},
- siblingUpdates = {};
-
- // When a preview is generated in the block switcher you don't have anything to work with here.
- if ( ! sibling ) {
- return;
- }
-
- const siblingClientId = sibling.clientId;
-
- // Syncing for confirm group fields.
- if (
- attributes.isConfirmationControlField ||
- attributes.isConfirmationField
- ) {
- const groupUpdates = getConfirmGroupUpdates(
- attributes,
- sibling.attributes
- );
-
- currentUpdates = merge( currentUpdates, groupUpdates.currentUpdates );
- siblingUpdates = merge( siblingUpdates, groupUpdates.siblingUpdates );
- }
-
- updateChildren( {
- setAttributes,
- currentUpdates,
- siblingClientId,
- siblingUpdates,
- } );
-}
diff --git a/src/js/blocks/form-fields/group-layout-control.js b/src/js/blocks/form-fields/group-layout-control.js
deleted file mode 100644
index 42e73abe..00000000
--- a/src/js/blocks/form-fields/group-layout-control.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { RadioControl } from '@wordpress/components';
-import { __ } from '@wordpress/i18n';
-import { store as blockEditorStore } from '@wordpress/block-editor';
-import { dispatch } from '@wordpress/data';
-
-/**
- * On Change callback for the radio control element
- *
- * Updates the block's attributes and sets the child blocks column attributes
- * depending on the newly selected field layout option.
- *
- * If the selected layout is "stacked" makes children full width and sets them all as the
- * last column.
- *
- * If the selected layout is "columns" makes children 50/50 width, sets the last field as the
- * last column and marks the other fields as not being the last column.
- *
- * @since 2.0.0
- *
- * @param {Object} options
- * @param {string} options.fieldLayout The newly selected field layout option.
- * @param {Function} options.setAttributes Function to set attributes on the current block (group).
- * @param {Object[]} options.innerBlocks Array of the current block's innerBlocks.
- * @return {void}
- */
-function onChange( { fieldLayout, setAttributes, innerBlocks } ) {
- const { updateBlockAttributes } = dispatch( blockEditorStore );
-
- // Update the field layout on the group block.
- setAttributes( { fieldLayout } );
-
- // Update inner blocks.
- const columns = 'columns' === fieldLayout ? 6 : 12;
- innerBlocks.forEach( ( { clientId }, index ) => {
- let last_column = 1 === index;
- if ( 0 === index && 'stacked' === fieldLayout ) {
- last_column = true;
- }
-
- updateBlockAttributes( clientId, { columns, last_column } );
- } );
-}
-
-export default function ( props ) {
- const { attributes, block, setAttributes } = props,
- { fieldLayout } = attributes,
- { innerBlocks } = block;
-
- return (
-
- onChange( { fieldLayout, setAttributes, innerBlocks } )
- }
- options={ [
- { value: 'columns', label: __( 'Columns', 'lifterlms' ) },
- { value: 'stacked', label: __( 'Stacked', 'lifterlms' ) },
- ] }
- />
- );
-}
diff --git a/src/js/blocks/form-fields/index.js b/src/js/blocks/form-fields/index.js
deleted file mode 100644
index 5422af9b..00000000
--- a/src/js/blocks/form-fields/index.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Export all fields in the fields library.
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// Hooks.
-import './reusable';
-
-// Confirm Field Group.
-import * as confirmGroup from './fields/confirm-group';
-
-// Default Fields.
-import * as checkboxes from './fields/checkboxes';
-import * as radio from './fields/radio';
-import * as select from './fields/select';
-import * as text from './fields/text';
-import * as textarea from './fields/textarea';
-
-// Composed Fields.
-import * as redeemVoucher from './fields/redeem-voucher';
-
-import * as userDisplayName from './fields/user-display-name';
-import * as userLogin from './fields/user-login';
-import * as userEmail from './fields/user-email';
-import * as userFirstName from './fields/user-first-name';
-import * as userLastName from './fields/user-last-name';
-import * as userNames from './fields/user-names';
-import * as userPassword from './fields/user-password';
-
-// User Address Fields.
-import * as userAddress from './fields/user-address';
-import * as userAddressStreet from './fields/user-address-street';
-import * as userAddressStreetPrimary from './fields/user-address-street-primary';
-import * as userAddressStreetSecondary from './fields/user-address-street-secondary';
-import * as userAddressCity from './fields/user-address-city';
-import * as userAddressCountry from './fields/user-address-country';
-import * as userAddressRegion from './fields/user-address-region';
-import * as userAddressState from './fields/user-address-state';
-import * as userAddressPostalCode from './fields/user-address-postal-code';
-
-import * as userPhone from './fields/user-phone';
-
-export {
- confirmGroup,
- checkboxes,
- radio,
- select,
- text,
- textarea,
- redeemVoucher,
- userAddress,
- userAddressStreet,
- userAddressStreetPrimary,
- userAddressStreetSecondary,
- userAddressCity,
- userAddressCountry,
- userAddressRegion,
- userAddressState,
- userAddressPostalCode,
- userDisplayName,
- userEmail,
- userFirstName,
- userLastName,
- userLogin,
- userNames,
- userPassword,
- userPhone,
-};
diff --git a/src/js/blocks/form-fields/input-group-options.js b/src/js/blocks/form-fields/input-group-options.js
deleted file mode 100644
index 6bf4fb40..00000000
--- a/src/js/blocks/form-fields/input-group-options.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Output a list of checkbox or radio options
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-// WP deps.
-import { withInstanceId } from '@wordpress/compose';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Output a list of options for an input group field (checkbox/radio).
- *
- * @since 1.6.0
- * @since 2.0.0 Moved out of `field.js` to it's own file and added an instance id.
- *
- * @param {Object} options
- * @param {Object[]} options.options Array of options objects.
- * @param {string} options.fieldType Field node type (eg "checkbox" or "radio").
- * @param {number} options.instanceId Unique component instanceId.
- * @return {Object} HTML Fragment.
- */
-function InputOptionsGroup( { options, fieldType, instanceId } ) {
- return (
-
- { options.map( ( option, index ) => (
-
- { ' ' }
- { option.text }
-
- ) ) }
-
- );
-}
-
-export default withInstanceId( InputOptionsGroup );
diff --git a/src/js/blocks/form-fields/inspect-field-options.js b/src/js/blocks/form-fields/inspect-field-options.js
deleted file mode 100644
index 5ecd3a81..00000000
--- a/src/js/blocks/form-fields/inspect-field-options.js
+++ /dev/null
@@ -1,364 +0,0 @@
-/**
- * Inspector settings component for managing a field's options
- *
- * Used on Radios, Checkboxes, and Selects
- *
- * @since 1.6.0
- * @since 1.8.0 Updated lodash imports.
- */
-
-// WP Deps.
-import {
- Button,
- BaseControl,
- TextControl,
- Tooltip,
- RadioControl,
- CheckboxControl,
-} from '@wordpress/components';
-import { Component } from '@wordpress/element';
-import { __, sprintf } from '@wordpress/i18n';
-
-// External Deps.
-import {
- SortableContainer,
- SortableElement,
- SortableHandle,
-} from 'react-sortable-hoc';
-import { cloneDeep } from 'lodash';
-
-/**
- * Move an item's position within an array.
- *
- * @since 1.6.0
- *
- * @param {Array} array The array.
- * @param {number} from Item's original index.
- * @param {number} to Item's new index.
- * @return {Array} Modified array.
- */
-const arrayMove = ( array, from, to ) => {
- array = array.slice();
- array.splice(
- to < 0 ? array.length + to : to,
- 0,
- array.splice( from, 1 )[ 0 ]
- );
- return array;
-};
-
-/**
- * Drag Handle Component
- *
- * @since 1.6.0
- *
- * @return {Object} Component HTML Fragment.
- */
-const DragHandle = SortableHandle( () => (
-
- :::
-
-) );
-
-/**
- * Sortable container component
- *
- * Holds the list of the field's options.
- *
- * @since 1.6.0
- *
- * @return {Object} Component HTML Fragment.
- */
-const OptionsList = SortableContainer(
- ( { items, onChange, onRemove, showKeys, type } ) => {
- return (
-
- { items.map( ( option, index ) => (
-
- ) ) }
-
- );
- }
-);
-
-/**
- * Sortable element component
- *
- * Each element represents a single option.
- *
- * @since 1.6.0
- * @since 1.12.0 Added tooltip for the "Make Default" radio control & updated the icon used for item deletion.
- * @since 2.0.0 Added special treatment for checkboxes.
- *
- * @return {Object} Component HTML Fragment.
- */
-const OptionItem = SortableElement(
- ( { item, i, onChange, onRemove, showKeys, type } ) => {
- const OptionControl =
- 'checkbox' === type ? (
- {
- onChange(
- { ...item, default: true === val ? 'yes' : 'no' },
- i
- );
- } }
- tabIndex="-1"
- />
- ) : (
- {
- onChange( { ...item, default: val }, i );
- } }
- options={ [ { label: '', value: 'yes' } ] }
- tabIndex="-1"
- />
- );
-
- return (
-
-
-
-
- { OptionControl }
-
-
-
-
- onChange( { ...item, text: val }, i )
- }
- placeholder={ __( 'Option text', 'lifterlms' ) }
- />
- { showKeys && (
-
- onChange( { ...item, key: val }, i )
- }
- placeholder={ __( 'Saved value', 'lifterlms' ) }
- />
- ) }
-
-
- {
- onRemove( i );
- } }
- tabIndex="-1"
- isSmall
- />
-
-
- );
- }
-);
-
-/**
- * Inspector "Options" component
- *
- * Used to CRUD options for select, checkboxes, and radio field blocks.
- *
- * @since 1.6.0
- */
-export default class InspectorFieldOptions extends Component {
- /**
- * Constructor
- *
- * @since 1.6.0
- *
- * @return {void}
- */
- constructor() {
- super( ...arguments );
-
- const { options } = this.props.attributes;
- this.state = {
- showKeys: false,
- items: options,
- };
- }
-
- /**
- * Called when sorting completes, updates options order.
- *
- * @since 1.6.0
- *
- * @param {number} options
- * @param {number} options.oldIndex The option's previous index.
- * @param {number} options.newIndex The option's new index.
- * @return {void}
- */
- onSortEnd = ( { oldIndex, newIndex } ) => {
- this.updateOptions( arrayMove( this.state.items, oldIndex, newIndex ) );
- };
-
- /**
- * Update options
- *
- * @since 1.6.0
- *
- * @param {Object[]} options Options array.
- * @return {void}
- */
- updateOptions = ( options ) => {
- const { setAttributes } = this.props;
-
- setAttributes( { options } );
- this.setState( { items: options } );
- };
-
- /**
- * Component render
- *
- * @since 1.6.0
- *
- * @return {BaseControl} Component HTML fragment.
- */
- render() {
- const { attributes, setAttributes } = this.props,
- { id, field } = attributes,
- { showKeys } = this.state;
-
- let { options } = attributes;
-
- options = cloneDeep( options );
-
- /**
- * Add a new option.
- *
- * @since 1.6.0
- * @since 1.12.0 Newly created options will be the default for radio and selects.
- * Added default text and keys when adding a new option.
- *
- * @return {void}
- */
- const addOption = () => {
- const count = options.length;
-
- let isDefault = 'no';
- if ( [ 'radio', 'select' ].includes( field ) ) {
- isDefault = count ? 'no' : 'yes';
- }
-
- onOptionChange(
- {
- // Translators: %d = Option index in the list of options.
- text: sprintf( __( 'Option %d', 'lifterlms' ), count + 1 ),
- // Translators: %d = Option index in the list of options.
- key: sprintf( __( 'option_%d', 'lifterlms' ), count + 1 ),
- default: isDefault,
- },
- options.length
- );
- };
-
- /**
- * Delete an existing option
- *
- * @since 1.6.0
- * @since 1.12.0 When deleting a default option, set the first item as the new default.
- *
- * @param {number} index Index of the deleted option.
- * @return {void}
- */
- const removeOption = ( index ) => {
- const wasDefault = 'yes' === options[ index ].default,
- newOptions = options.filter( ( opt, i ) => i !== index );
-
- // If it was the default option and there's at least one option left make the first item in the list the new default.
- if ( wasDefault && newOptions.length ) {
- newOptions[ 0 ].default = 'yes';
- }
-
- setAttributes( { options: newOptions } );
- };
-
- /**
- * Callback when options are changed.
- *
- * @since 1.6.0
- * @since 2.0.0 Pass an id to
- * Pass the field type to
- * Also allow multiple defaults for checkboxes.
- *
- * @param {Object} option Option data.
- * @param {number} index Option index.
- * @return {void}
- */
- const onOptionChange = ( option, index ) => {
- const prevOption = options[ index ] ? options[ index ] : false,
- { field } = this.props.attributes;
-
- options[ index ] = option;
- this.updateOptions( options );
-
- // When setting an option as the "default", set all other options to not be the default,
- // if not a checkbox.
- if (
- 'checkbox' !== field &&
- 'yes' === option.default &&
- prevOption &&
- prevOption.default !== option.default
- ) {
- options.forEach( ( opt, i ) => {
- if ( i !== index ) {
- onOptionChange( { ...opt, default: 'no' }, i );
- }
- } );
- }
- };
-
- return (
-
-
-
- {
- addOption();
- } }
- >
- { __( 'Add option', 'lifterlms' ) }
-
-
- this.setState( { showKeys: ! showKeys } ) }
- >
- { showKeys
- ? __( 'Hide keys', 'lifterlms' )
- : __( 'Show keys', 'lifterlms' ) }
-
-
- );
- }
-}
diff --git a/src/js/blocks/form-fields/inspect.js b/src/js/blocks/form-fields/inspect.js
deleted file mode 100644
index 62ad784d..00000000
--- a/src/js/blocks/form-fields/inspect.js
+++ /dev/null
@@ -1,694 +0,0 @@
-/**
- * Inspector settings for the Course Information Block.
- *
- * @since 1.6.0
- * @version 2.0.0
- */
-
-// WP Deps.
-import {
- InspectorControls,
- InspectorAdvancedControls,
- store as blockEditorStore,
-} from '@wordpress/block-editor';
-import {
- PanelBody,
- SelectControl,
- Slot,
- TextControl,
- ToggleControl,
-} from '@wordpress/components';
-import { select, dispatch } from '@wordpress/data';
-import { Component, Fragment } from '@wordpress/element';
-import { __, sprintf } from '@wordpress/i18n';
-import {
- switchToBlockType,
- getPossibleBlockTransformations,
- getBlockType,
-} from '@wordpress/blocks';
-import { store as editorStore } from '@wordpress/editor';
-
-// Internal Deps.
-import InspectorFieldOptions from './inspect-field-options';
-import getBlocksFlat from '../../util/get-blocks-flat';
-import { store as fieldsStore } from '../../data/fields';
-import { isUnique } from './checks';
-
-/**
- * Block Inspector for Field blocks
- *
- * @since 1.6.0
- */
-export default class Inspector extends Component {
- /**
- * Constructor
- *
- * @since 2.0.0
- *
- * @param {Object} props Component properties.
- * @return {void}
- */
- constructor( props ) {
- super( props );
- this.state = {
- validationErrors: {},
- };
- }
-
- /**
- * Retrieve a specific block by it's ID attribute.
- *
- * @since 1.6.0
- *
- * @param {string} fieldId The field ID.
- * @return {Object | boolean} A block object or false if not found.
- */
- getBlockByFieldId( fieldId ) {
- const blocks = getBlocksFlat().filter(
- ( block ) => fieldId === block.attributes.id
- );
- if ( blocks ) {
- return blocks[ 0 ];
- }
-
- return false;
- }
-
- getColumnsOptions( context ) {
- let options = [];
-
- // Full width is allowed inside stacked groups or when the field is being used solo.
- if (
- ! context ||
- ( context &&
- ( ! context[ 'llms/fieldGroup/fieldLayout' ] ||
- 'stacked' === context[ 'llms/fieldGroup/fieldLayout' ] ) )
- ) {
- options.push( {
- value: 12,
- label: __( '100%', 'lifterlms' ),
- } );
- }
-
- options = options.concat( [
- {
- value: 9,
- label: __( '75%', 'lifterlms' ),
- },
- {
- value: 8,
- label: __( '66.66%', 'lifterlms' ),
- },
- {
- value: 6,
- label: __( '50%', 'lifterlms' ),
- },
- {
- value: 4,
- label: __( '33.33%', 'lifterlms' ),
- },
- {
- value: 3,
- label: __( '25%', 'lifterlms' ),
- },
- ] );
-
- return options;
- }
-
- /**
- * Retrieve an array of objects to be used in the Matching Field select control.
- *
- * @since 1.6.0
- *
- * @return {Object[]} Array of objects for the select control options list.
- */
- getMatchFieldOptions() {
- const { clientId, name } = this.props;
-
- const opts = [
- {
- value: '',
- label: __( 'Select a field', 'lifterlms' ),
- },
- ];
-
- return opts.concat(
- getBlocksFlat()
- .filter(
- ( block ) =>
- block.clientId !== clientId &&
- -1 !== name.indexOf( 'llms/form-field-' )
- )
- .map( ( block ) => {
- const { id, label } = block.attributes;
-
- return {
- value: id,
- label: `${ label } (${ id })`,
- };
- } )
- );
- }
-
- /**
- * Determine if the block has inspector support
- *
- * The block must have support for at least one inspector control.
- *
- * @since 1.6.0
- *
- * @return {boolean} Returns `true` if the block has inspector support.
- */
- hasInspectorSupport() {
- const { inspectorSupports } = this.props;
- return (
- Object.keys( inspectorSupports ).filter(
- ( key ) => inspectorSupports[ key ]
- ).length >= 1
- );
- }
-
- /**
- * Determine if the block has inspector support for a specific control
- *
- * @since 1.6.0
- *
- * @param {string} control Control ID.
- * @return {boolean} Returns `true` if the block has support for inspector controls.
- */
- hasInspectorControlSupport( control ) {
- const { inspectorSupports } = this.props;
- return inspectorSupports[ control ];
- }
-
- canTransformToGroup( block ) {
- // If the block is already within a confirmation block then we can't add a confirmation group.
- if ( ! block || this.isInAConfirmGroup( block ) ) {
- return false;
- }
- return getPossibleBlockTransformations( [ block ] )
- .map( ( { name } ) => name )
- .includes( 'llms/form-field-confirm-group' );
- }
-
- isInAConfirmGroup( block ) {
- return this.getParentGroupClientId( block ) ? true : false;
- }
-
- getParentGroupClientId( block ) {
- if ( ! block ) {
- return false;
- }
-
- const { clientId } = block,
- { getBlockParentsByBlockName } = select( blockEditorStore ),
- parents = getBlockParentsByBlockName(
- clientId,
- 'llms/form-field-confirm-group'
- );
-
- return parents.length ? parents[ 0 ] : false;
- }
-
- getBlockSiblings( block ) {
- const parentClientId = this.getParentGroupClientId( block );
-
- if ( ! parentClientId ) {
- return [];
- }
-
- const { getBlock } = select( blockEditorStore ),
- parentBlock = getBlock( parentClientId );
-
- return parentBlock.innerBlocks.filter(
- ( { clientId } ) => clientId !== block.clientId
- );
- }
-
- /**
- * Retrieve an error message for use in error notices thrown by updateValueWithValidation()
- *
- * @since 2.0.0
- *
- * @param {string} key Field key.
- * @return {string} Error message for the given validation issue.
- */
- getValidationErrText( key ) {
- let msg = '';
-
- const val = this.state.validationErrors[ key ];
-
- if ( ! val ) {
- msg = __( 'The value cannot be blank.', 'lifterlms' );
- } else if ( this.containsInvalidCharacters( val ) ) {
- // Translators: %s = user-submitted value.
- msg = __(
- 'The value "%s" contains invalid characters. Only letters, numbers, underscores, and hyphens are allowed.',
- 'lifterlms'
- );
- } else {
- switch ( key ) {
- case 'data_store_key':
- // Translators: %s = user-submitted value.
- msg = __(
- 'The user meta key "%s" is not unique. Please choose a unique value.',
- 'lifterlms'
- );
- break;
-
- case 'id':
- // Translators: %s = user-submitted value.
- msg = __(
- 'The ID "%s" is not unique. Please choose a unique field ID.',
- 'lifterlms'
- );
- break;
-
- case 'name':
- // Translators: %s = user-submitted value.
- msg = __(
- 'The name "%s" is not unique. Please choose a globally unique field name.',
- 'lifterlms'
- );
- break;
-
- default:
- // Translators: %s = user-submitted value.
- msg = __(
- 'The chosen value "%s" is invalid.',
- 'lifterlms'
- );
- }
- }
-
- return sprintf( msg, val );
- }
-
- /**
- * Determine if invalid characters are present in an attribute
- *
- * This validates the data_store_key, name, and ID attributes only.
- *
- * This is a pretty accurate version of characters allowed in HTML name/id attributes
- * on the HTML 4 spec. HTML 5 allows a tremendous number of characters but I'd rather
- * not validate strictly against that because I want to ensure we can use the same
- * characters for usermeta keys.
- *
- * For future Thomas who will have forgetten how to read the regex: allows alphanumeric chars, hyphens, and underscores.
- *
- * @since 2.0.0
- *
- * @param {string} val Attribute value.
- * @return {boolean} Returns `true` if the value contains invalid chars and `false` otherwise.
- */
- containsInvalidCharacters( val ) {
- return val.match( /[^A-Za-z0-9\-\_]/g ) ? true : false;
- }
-
- /**
- * Sets (or remove) a validation error for given key
- *
- * Passing a null value removes an existing validation error.
- *
- * @since 2.0.0
- *
- * @param {string} key Attribute key.
- * @param {?string} val Content of the invalid value, an empty string, or `null` to remove an existing validation error.
- * @return {void}
- */
- setValidationError( key, val = null ) {
- this.setState( {
- validationErrors: {
- ...this.state.validationErrors,
- [ key ]: val,
- },
- } );
- }
-
- /**
- * Determines if a block attribute has a validation error.
- *
- * @since 2.0.0
- *
- * @param {string} key Attribute key.
- * @return {boolean} Returns `true` when a validation error is present and `false`` if not.
- */
- hasValidationErr( key ) {
- return 'string' === typeof this.state.validationErrors[ key ];
- }
-
- /**
- * Component to render a TextControl with built-in data validation and error display
- *
- * @since 2.0.0
- *
- * @param {Object} props
- * @param {Inspector} props.parent Reference to the parent Inspector component.
- * @param {string} props.attrKey Attribute key name for the control input.
- * @param {string} props.label Label property passed to TextControl.
- * @param {string} props.help Help property passed to TextControl.
- * @return {Object} Component HTML fragment.
- */
- ValidatedTextControl( { parent, attrKey, label, help } ) {
- const { attributes } = parent.props,
- value = attributes[ attrKey ],
- hasError = parent.hasValidationErr( attrKey ),
- className = hasError ? 'llms-invalid-control' : '';
-
- return (
-
-
- parent.updateValueWithValidation(
- attrKey,
- newValue,
- 'name' === attrKey ? 'global' : 'local'
- )
- }
- />
- { hasError && (
-
- { parent.getValidationErrText( attrKey ) }
-
- ) }
-
- );
- }
-
- /**
- * Set attributes with built-in validation
- *
- * Validates fields for uniqueness against field data in the llms/user-info-fields data
- * store. Prevents storage of invalid data and throws an error notice when validation issues
- * are encountered.
- *
- * @since 2.0.0
- *
- * @param {string} key Field key.
- * @param {string} newValue Field value.
- * @param {string} context Validation context. Accepts "global" to validate against all known fields
- * or "local" to validate against loaded fields in the current form.
- * @return {void}
- */
- updateValueWithValidation( key, newValue, context = 'local' ) {
- const { clientId, attributes, setAttributes } = this.props,
- { name } = attributes,
- currentValue = attributes[ key ],
- { editField, renameField } = dispatch( fieldsStore ),
- { lockPostSaving, unlockPostSaving } = dispatch( editorStore ),
- errorId = `llms-${ key }-validation-err-${ clientId }-${ name }`;
-
- // No change.
- if ( newValue === currentValue ) {
- return;
- }
-
- const isEmpty = ! newValue,
- hasInvalidChars = this.containsInvalidCharacters( newValue ),
- hasUniqueVal = isUnique( newValue, key, context ),
- isValid = ! isEmpty && ! hasInvalidChars && hasUniqueVal;
-
- this.setValidationError( key );
- unlockPostSaving( errorId );
- if ( ! isValid ) {
- this.setValidationError( key, newValue );
-
- /**
- * When a field is "emptied" we'll throw an error but don't save the empty value.
- * This results in an error being displayed and the initial (pre deletion) value being
- * restored. If someone highlights the whole field and deletes it the whole field name
- * stays and an error displays. If the backspace one at a time the first character will
- * remain.
- *
- * This isn't ideal but I can't find a way to let them completely empty the data
- * without rewriting the duplicate detection logic in the main `edit()` component.
- */
- if ( isEmpty ) {
- return;
- }
- lockPostSaving( errorId );
- }
-
- if ( 'name' === key ) {
- // Renaming a duplicate will cause overwrites of the original field.
- if ( ! hasUniqueVal ) {
- newValue = newValue.slice( 0, -1 );
- }
- renameField( attributes.name, newValue );
- } else {
- editField( attributes.name, { [ key ]: newValue } );
- }
-
- setAttributes( {
- [ key ]: newValue,
- } );
- }
-
- /**
- * Render the Block Inspector
- *
- * @since 1.6.0
- * @since 1.12.0 Add inspector controls for data store mapping.
- *
- * @return {Fragment} Component HTML fragment.
- */
- render() {
- // Return early if there's no inspector options to display.
- if ( ! this.hasInspectorSupport() ) {
- return '';
- }
-
- const { attributes, setAttributes, clientId, context } = this.props,
- block = select( blockEditorStore ).getBlock( clientId ),
- {
- required,
- placeholder,
- columns,
- isConfirmationField,
- isConfirmationControlField,
- } = attributes;
-
- const canTransformToGroup = this.canTransformToGroup( block ),
- isInAConfirmGroup = this.isInAConfirmGroup( block );
-
- return (
-
-
-
- { ! isConfirmationField &&
- this.hasInspectorControlSupport( 'required' ) && (
-
- setAttributes( {
- required: ! required,
- } )
- }
- help={
- !! required
- ? __(
- 'Field is required.',
- 'lifterlms'
- )
- : __(
- 'Field is optional.',
- 'lifterlms'
- )
- }
- />
- ) }
-
- {
- columns = parseInt( columns, 10 );
- setAttributes( { columns } );
-
- const sibling = this.getBlockSiblings( block );
-
- if (
- sibling.length &&
- columns + sibling[ 0 ].attributes.columns >
- 12
- ) {
- const { updateBlockAttributes } = dispatch(
- blockEditorStore
- );
- updateBlockAttributes(
- sibling[ 0 ].clientId,
- {
- columns: 12 - columns,
- }
- );
- }
- } }
- help={ __(
- 'Determines the width of the form field.',
- 'lifterlms'
- ) }
- value={ columns }
- options={ this.getColumnsOptions( context ) }
- />
-
- { this.hasInspectorControlSupport( 'options' ) && (
-
- ) }
-
- { this.hasInspectorControlSupport( 'placeholder' ) && (
-
- setAttributes( { placeholder } )
- }
- help={ __(
- 'Displays a placeholder option as the selected instead of a default value.',
- 'lifterlms'
- ) }
- />
- ) }
-
- { ( canTransformToGroup ||
- ( isConfirmationControlField &&
- isInAConfirmGroup ) ) && (
- {
- const {
- replaceBlock,
- selectBlock,
- } = dispatch( blockEditorStore ),
- {
- findControllerBlockIndex,
- } = getBlockType(
- 'llms/form-field-confirm-group'
- ),
- { getBlock } = select(
- blockEditorStore
- );
-
- let replaceClientId = clientId,
- newBlockType =
- 'llms/form-field-confirm-group',
- blockToSwitch = block,
- selectBlockId = null;
-
- if ( isInAConfirmGroup ) {
- replaceClientId = this.getParentGroupClientId(
- block
- );
- blockToSwitch = getBlock(
- replaceClientId
- );
- newBlockType = block.name;
- }
-
- const switched = switchToBlockType(
- blockToSwitch,
- newBlockType
- );
-
- replaceBlock( replaceClientId, switched );
-
- if ( ! isInAConfirmGroup ) {
- const { innerBlocks } = switched[ 0 ],
- controllerIndex = findControllerBlockIndex(
- innerBlocks
- );
-
- selectBlockId =
- innerBlocks[ controllerIndex ]
- .clientId;
- } else {
- selectBlockId = switched[ 0 ].clientId;
- }
-
- selectBlock( selectBlockId );
- } }
- help={
- isInAConfirmGroup
- ? __(
- 'A Confirmation field is active.',
- 'lifterlms'
- )
- : __(
- 'No confirmation field.',
- 'lifterlms'
- )
- }
- />
- ) }
-
- { this.hasInspectorControlSupport( 'customFill' ) && (
-
- ) }
-
-
- { ! isConfirmationField &&
- this.hasInspectorControlSupport( 'storage' ) && (
-
-
-
- ) }
-
-
-
- { ! isConfirmationField &&
- this.hasInspectorControlSupport( 'name' ) && (
-
- ) }
-
- { ! isConfirmationField &&
- this.hasInspectorControlSupport( 'id' ) && (
-
- ) }
-
-
- );
- }
-}
diff --git a/src/js/blocks/form-fields/reusable.js b/src/js/blocks/form-fields/reusable.js
deleted file mode 100644
index 820cdfab..00000000
--- a/src/js/blocks/form-fields/reusable.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Manage reusable block meta data
- *
- * @since Unknown
- * @version 2.0.0
- */
-
-// WP Deps.
-import { select, dispatch, subscribe } from '@wordpress/data';
-import { addFilter } from '@wordpress/hooks';
-
-// External Deps.
-import { some } from 'lodash';
-
-// Internal Deps.
-import { getFieldBlocks } from './checks';
-import { getCurrentPostType } from '../../util/';
-
-/**
- * Handle setting is_llms_field when editing a wp_block directly
- *
- * This subscribes to changes in the post_content and stores the meta
- * value depending on the presence of llms form field blocks.
- *
- * This handles setting the meta value when editing a reusable block
- * directly on a reusable block edit screen.
- *
- * @since 2.0.0
- */
-if ( 'wp_block' === getCurrentPostType() ) {
- let lastContent = '';
-
- subscribe( () => {
- const content = select( 'core/editor' ).getEditedPostContent();
-
- if ( 'undefined' === typeof content || content === lastContent ) {
- return;
- }
-
- lastContent = content;
-
- const val = content.includes( '
-[llms-user fake or=\\"test\\"][llms-user first_name or=\\"friend\\"][llms-user display_name] Ipsum
-"
-`;
-
-exports[`Admin/Shortcodes should filter the list 1`] = `
-Array [
- "Username",
- "First Name",
- "Last Name",
- "Display Name",
-]
-`;
-
-exports[`Admin/Shortcodes should filter the list 2`] = `
-Array [
- "Username",
- "Email Address",
- "First Name",
- "Last Name",
- "Display Name",
- "Address",
- "",
- "City",
- "Country",
- "State / Region",
- "Postal / Zip Code",
- "Phone Number",
-]
-`;
-
-exports[`Admin/Shortcodes should filter the list 3`] = `
-Array [
- "Username",
- "Email Address",
-]
-`;
-
-exports[`Admin/Shortcodes should filter the list 4`] = `
-Array [
- "Username",
- "Email Address",
- "First Name",
- "Last Name",
- "Display Name",
- "Address",
- "",
- "City",
- "Country",
- "State / Region",
- "Postal / Zip Code",
- "Phone Number",
-]
-`;
-
-exports[`Admin/Shortcodes should filter the list 5`] = `
-Array [
- "Email Address",
-]
-`;
-
-exports[`Admin/Shortcodes should filter the list 6`] = `
-Array [
- "Username",
- "Email Address",
- "First Name",
- "Last Name",
- "Display Name",
- "Address",
- "",
- "City",
- "Country",
- "State / Region",
- "Postal / Zip Code",
- "Phone Number",
-]
-`;
-
-exports[`Admin/Shortcodes should insert the shortcode 1`] = `
-"
-[llms-user display_name] Ipsum
-"
-`;
-
-exports[`Admin/Shortcodes should insert the shortcode with a default value 1`] = `
-"
-[llms-user first_name or=\\"friend\\"][llms-user display_name] Ipsum
-"
-`;
diff --git a/tests/e2e/tests/admin/form-document-settings.test.js b/tests/e2e/tests/admin/form-document-settings.test.js
deleted file mode 100644
index 5a2801d5..00000000
--- a/tests/e2e/tests/admin/form-document-settings.test.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Test Form post document sidebar
- *
- * @since 1.12.0
- * @version 1.12.0
- */
-
-import {
- getAllBlocks,
- insertBlock,
- openDocumentSettingsSidebar,
- selectBlockByClientId,
-} from '@wordpress/e2e-test-utils';
-
-import {
- click,
- clickElementByText,
- toggleOpenRegistration,
-} from '@lifterlms/llms-e2e-test-utils';
-
-import {
- blockSnapshotMatcher,
- openFormSettingsPanel,
- removeBlockByClientId,
- visitForm,
-} from '../../util';
-
-async function getAllBlockNames() {
- const blocks = await getAllBlocks();
- return blocks.map( ( { name } ) => name );
-}
-
-describe( 'Admin/FormsDocSidebar', () => {
-
- describe( 'LocationDisplay', () => {
-
- it ( 'should display the location when open registration is disabled', async () => {
-
- await toggleOpenRegistration( false );
-
- page.once( 'dialog', async dialog => await dialog.accept() ); // Leave page without saving.
-
- await visitForm( 'Register' );
- await openFormSettingsPanel();
-
- expect( await page.$eval( '.llms-forms-doc-settings .components-panel__row', el => el.textContent ) ).toMatchSnapshot();
-
- } );
-
- it ( 'should display the location with a link when open registration is enabled', async () => {
-
- await toggleOpenRegistration( true );
-
- page.on( 'dialog', async dialog => await dialog.accept() ); // Leave page without saving.
-
- await visitForm( 'Register' );
- await openFormSettingsPanel();
-
- expect( await page.$eval( '.llms-forms-doc-settings .components-panel__row a', el => el.textContent ) ).toMatchSnapshot();
-
- } );
-
- } );
-
- describe( 'TemplateRevert', () => {
-
- it ( 'should allow a form to be reverted to the default layout', async () => {
-
- await visitForm( 'Register' );
-
- // Add a new block.
- await insertBlock( 'Paragraph' );
- await page.keyboard.type( 'Lorem ipsum' );
-
- // Remove the last field block on screen.
- let blocks = await getAllBlocks();
- const lastBlock = blocks[ blocks.length - 2 ];
- await removeBlockByClientId( lastBlock.clientId );
-
- // Revert.
- await openFormSettingsPanel();
- await clickElementByText( 'Revert to Default', '.components-panel .components-button' );
-
- // Notice should display.
- await page.waitForSelector( '.components-notice.is-success' );
- expect( await page.$eval( '.components-notice.is-success .components-notice__content', el => el.innerHTML ) ).toMatchSnapshot();
-
- // Match block list.
- expect( await getAllBlockNames() ).toMatchSnapshot();
-
- // Undo the revert.
- await click( '.components-notice.is-success .components-notice__content button' );
-
- // Notice gets removed
- expect( await page.evaluate( () => document.querySelector( '.components-notice.is-success' ) ) ).toBeNull();
-
- await page.waitFor( 1000 );
-
- // Changes before the revert should be found.
- expect( await getAllBlockNames() ).toMatchSnapshot();
-
- } );
-
- } );
-
-
-} );
diff --git a/tests/e2e/tests/admin/forms-ready.test.js b/tests/e2e/tests/admin/forms-ready.test.js
deleted file mode 100644
index f2b86795..00000000
--- a/tests/e2e/tests/admin/forms-ready.test.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Test formsReady() events run on domReady()
- *
- * @since 1.12.0
- * @version 1.12.0
- */
-
-import {
- getAllBlocks,
- getAllBlockInserterItemTitles,
- insertBlock,
- openGlobalBlockInserter,
- openDocumentSettingsSidebar,
-} from '@wordpress/e2e-test-utils';
-
-import {
- click,
- clickElementByText,
-} from '@lifterlms/llms-e2e-test-utils';
-
-import {
- openFormSettingsPanel,
- publishAndSaveEntities,
- removeBlockByClientId,
- visitForm,
-} from '../../util';
-
-async function removeUserEmailBlock() {
-
- const blocks = await getAllBlocks();
- await removeBlockByClientId( blocks[0].clientId );
-
-}
-
-async function getAvailableSidebarPanelTitles() {
-
- return page.$$eval( '.components-panel .block-editor-block-inspector .components-panel__body-title', els => els.map( ( { textContent } ) => textContent ) );
-
-}
-
-describe( 'Admin/FormsReady', () => {
-
- it ( 'should disable the use of the "Draft" button', async () => {
-
- const draftBtnSelector = '.edit-post-layout button.editor-post-switch-to-draft';
-
- await visitForm();
-
- // On page load.
- await page.waitFor( 5 );
- expect( await page.$eval( draftBtnSelector, el => el.style.display ) ).toBe( 'none' );
-
- // Add a block.
- await insertBlock( 'Paragraph' );
- await page.waitFor( 5 );
- expect( await page.$eval( draftBtnSelector, el => el.style.display ) ).toBe( 'none' );
-
- // After updating.
- await publishAndSaveEntities();
- await page.waitFor( 500 );
- expect( await page.$eval( draftBtnSelector, el => el.style.display ) ).toBe( 'none' );
-
- // Revert the form so future snapshots don't fail.
- await openFormSettingsPanel();
- await clickElementByText( 'Revert to Default', '.components-panel .components-button' );
- await page.waitForSelector( '.components-notice.is-success' );
- await publishAndSaveEntities();
-
- } );
-
- it ( 'should disable the "Status & Visibility" sidebar panel', async () => {
-
- await visitForm();
-
- // On page load.
- await page.waitFor( 5 );
- expect( await page.$eval( '.edit-post-layout .components-panel__body.edit-post-post-status', el => el.style.display ) ).toBe( 'none' );
-
- // Open Sidebar
- await openDocumentSettingsSidebar();
- await page.waitFor( 5 );
- expect( await page.$eval( '.edit-post-layout .components-panel__body.edit-post-post-status', el => el.style.display ) ).toBe( 'none' );
-
- // Close & Open again.
- await openDocumentSettingsSidebar();
- await page.waitFor( 5 );
- await openDocumentSettingsSidebar();
- expect( await page.$eval( '.edit-post-layout .components-panel__body.edit-post-post-status', el => el.style.display ) ).toBe( 'none' );
-
- } );
-
- it ( 'should add a notice and disable post updating when user email field is deleted', async () => {
-
- page.on( 'dialog', dialog => dialog.accept() ); // Leave page without saving.
-
- await visitForm();
- await removeUserEmailBlock();
- await page.waitForSelector( '.components-notice.is-error' );
-
- expect( await page.$eval( '.components-notice.is-error .components-notice__content', el => el.innerHTML ) ).toMatchSnapshot();
-
- expect( await page.$eval( 'button.editor-post-publish-button', el => el.disabled ) ).toBe( true );
-
- } );
-
- it ( 'should restore the user email field when the "Restore" CTA is used in the notice', async () => {
-
- await visitForm();
- await removeUserEmailBlock();
- await page.waitForSelector( '.components-notice.is-error' );
-
- await click( '.components-notice.is-error .components-notice__content button' );
-
- // Notice gets removed
- await page.waitFor( 2000 );
- expect( await page.evaluate( () => document.querySelector( '.components-notice.is-error' ) ) ).toBeNull();
- const blocks = await getAllBlocks();
- expect( blocks[0].name ).toBe( 'llms/form-field-user-email' );
-
- // Can be updated.
- expect( await page.$eval( 'button.editor-post-publish-button', el => el.disabled ) ).toBe( false );
-
- } );
-
- it ( 'should deregister most WP core blocks', async () => {
-
- await visitForm();
-
- await openGlobalBlockInserter();
- expect( await getAllBlockInserterItemTitles() ).toMatchSnapshot();
-
- } );
-
- it ( 'should deregister voucher block on checkout and account edit forms', async () => {
-
- const forms = {
- 'Register': false,
- 'Edit Account Information': false,
- 'Billing Information': true,
- };
-
- for ( let form in forms ) {
-
- await visitForm( form );
-
- await openGlobalBlockInserter();
- expect( await getAllBlockInserterItemTitles() ).toMatchSnapshot();
-
- }
-
- } );
-
- it ( 'should deregister user login block on account edit forms', async () => {
-
- const forms = {
- 'Register': true,
- 'Edit Account Information': false,
- 'Billing Information': true,
- };
-
- for ( let form in forms ) {
-
- await visitForm( form );
-
- await openGlobalBlockInserter();
- expect( await getAllBlockInserterItemTitles() ).toMatchSnapshot();
-
- }
-
- } );
-
-
- const forms = {
- 'Register': false,
- 'Edit Account Information': false,
- 'Billing Information': true,
- };
-
- for ( let form in forms ) {
-
- const verb = forms[ form ] ? 'allow' : 'disable';
-
- it ( `should ${ verb } block-level visibility settings for the "${ form }" form`, async () => {
-
- await visitForm( form );
-
- await page.click( '.block-editor-block-list__layout .wp-block-llms-form-field-user-phone .llms-field > label' );
-
- await page.waitFor( 500 );
-
- const titles = await getAvailableSidebarPanelTitles();
- expect( titles.includes( 'Enrollment Visibility' ) ).toStrictEqual( forms[ form ] );
-
- } );
-
- }
-
-
-
-} );
diff --git a/tests/e2e/tests/admin/shortcodes.test.js b/tests/e2e/tests/admin/shortcodes.test.js
deleted file mode 100644
index ccc09f41..00000000
--- a/tests/e2e/tests/admin/shortcodes.test.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * Test shortcode inserter
- *
- * @since 2.0.0
- * @version 2.0.0
- */
-
-import {
- clickBlockAppender,
- getEditedPostContent,
- showBlockToolbar,
-} from '@wordpress/e2e-test-utils';
-
-import {
- click,
- clickElementByText,
- createPost,
-} from '@lifterlms/llms-e2e-test-utils';
-
-// CSS selectors.
-const TOOLBAR_SELECTOR = '.block-editor-block-contextual-toolbar',
- DROPDOWN_SELECTOR = '.components-dropdown-menu__menu-item',
- MODAL_SELCTOR = '.llms-shortcodes-modal';
-
-/**
- * Retrieve a list of the titles of all shortcodes in the inserter table.
- *
- * @since 2.0.0
- *
- * @return {string[]} List of shortcode titles.
- */
-async function getVisibleTitles() {
- return await page.$$eval( `${ MODAL_SELCTOR } .llms-table tbody tr td:first-child`, els => els.map( ( { textContent } ) => textContent ) );
-}
-
-/**
- * Retrieve a list of the shortcodes visible in the inserter table.
- *
- * @since 2.0.0
- *
- * @return {string[]} List of shortcodes.
- */
-async function getVisibleCodes() {
- return await page.$$eval( `${ MODAL_SELCTOR } .llms-table tbody tr td:nth-child(2)`, els => els.map( ( { textContent } ) => textContent ) );
-}
-
-/**
- * Clear the currently selected input
- *
- * @since 2.0.0
- *
- * @param {Integer} length Number of characters to remove.
- * @return {void}
- */
-async function clearSearch( length ) {
-
- for ( let i = 0; i < length; i++ ) {
- await page.keyboard.press('Backspace');
- }
-
-}
-
-/**
- * Filter the shortcode list by search query
- *
- * @since 2.0.0
- *
- * @param {string} query Search query.
- * @return {void}
- */
-async function filterList( query ) {
- await clickElementByText( 'Filter by label', `${ MODAL_SELCTOR } label` );
- await page.keyboard.type( query );
-}
-
-/**
- * Add a default value to the visible shortcodes
- *
- * @since 2.0.0
- *
- * @param {string} val Default value.
- * @return {void}
- */
-async function addDefaultValue( val ) {
- await clickElementByText( 'Default value', `${ MODAL_SELCTOR } label` );
- await page.keyboard.type( val );
-}
-
-/**
- * Close the inserter modal
- *
- * @since 2.0.0
- *
- * @return {void}
- */
-async function closeModal() {
- await click( `${ MODAL_SELCTOR } button[aria-label="Close dialog"]` );
-}
-
-describe( 'Admin/Shortcodes', () => {
-
- beforeAll( async() => {
-
- await createPost( 'post', 'Shortcodes' );
-
- await clickBlockAppender();
-
- await page.keyboard.type( 'Ipsum' );
- await showBlockToolbar();
-
- } );
-
- beforeEach( async () => {
-
- await page.waitForSelector( TOOLBAR_SELECTOR );
-
- await click( `${ TOOLBAR_SELECTOR } button.components-dropdown-menu__toggle[aria-label="More"]` );
- await page.waitFor( 500 );
- await clickElementByText( 'Shortcodes', DROPDOWN_SELECTOR );
-
- await page.waitForSelector( MODAL_SELCTOR );
-
- } );
-
- it ( 'should filter the list', async() => {
-
- const queries = [ 'name', 'user', 'email' ];
-
- for ( let i = 0; i < queries.length; i++ ) {
-
- const query = queries[ i ];
-
- await filterList( query );
- expect( await getVisibleTitles() ).toMatchSnapshot();
- await clearSearch( query.length );
- expect( await getVisibleTitles() ).toMatchSnapshot();
-
- }
-
- await closeModal();
-
- } );
-
- it ( 'should add a default value', async() => {
-
- await addDefaultValue( 'default' );
- expect( await getVisibleCodes() ).toMatchSnapshot();
-
- await clearSearch( 7 );
- expect( await getVisibleCodes() ).toMatchSnapshot();
-
- await closeModal();
-
- } );
-
-
- it ( 'should insert the shortcode', async() => {
-
- await filterList( 'display' );
- await click( `${ MODAL_SELCTOR } .llms-table tbody tr:first-child td:nth-child(3) button` );
-
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- } );
-
- it ( 'should insert the shortcode with a default value', async() => {
-
- await filterList( 'first' );
- await addDefaultValue( 'friend' );
- await click( `${ MODAL_SELCTOR } .llms-table tbody tr:first-child td:nth-child(3) button` );
-
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- } );
-
-
- it ( 'should allow custom shortcodes to be used', async() => {
-
- await filterList( 'fake' );
- await addDefaultValue( 'test' );
-
- // Shows the warning message.
- expect( await page.$eval( `${ MODAL_SELCTOR } .llms-error`, ( { textContent }) => textContent ) ).toMatchSnapshot();
-
- // Added to the list.
- expect( await getVisibleTitles() ).toMatchSnapshot();
- expect( await getVisibleCodes() ).toMatchSnapshot();
-
- // Inserted.
- await click( `${ MODAL_SELCTOR } .llms-table tbody tr:first-child td:nth-child(3) button` );
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- } );
-
-} );
diff --git a/tests/e2e/tests/block-visibility/__snapshots__/block-visibility.test.js.snap b/tests/e2e/tests/block-visibility/__snapshots__/block-visibility.test.js.snap
deleted file mode 100644
index 472bf3ee..00000000
--- a/tests/e2e/tests/block-visibility/__snapshots__/block-visibility.test.js.snap
+++ /dev/null
@@ -1,63 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`BlockVisibility Unsupported should not show visibility settings for "dynamic" blocks 1`] = `
-"
-Lorem ipsum
-
-
-"
-`;
-
-exports[`BlockVisibility Unsupported should not show visibility settings for the classic block 1`] = `
-"
-Lorem ipsum
-
-
-"
-`;
-
-exports[`BlockVisibility should do nothing with default values 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to enrolled users 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to enrolled users 2`] = `"This block is only visible to enrolled users "`;
-
-exports[`BlockVisibility should restrict a block to logged in users 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to logged in users 2`] = `"This block is only visible to logged in users "`;
-
-exports[`BlockVisibility should restrict a block to logged out users 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to logged out users 2`] = `"This block is only visible to logged out users "`;
-
-exports[`BlockVisibility should restrict a block to non-enrolled users 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to non-enrolled users 2`] = `"This block is only visible to non-enrolled users or visitors "`;
-
-exports[`BlockVisibility should restrict a block to users in specific courses and/or memberships 1`] = `
-"
-Lorem ipsum
-"
-`;
-
-exports[`BlockVisibility should restrict a block to users in specific courses and/or memberships 2`] = `"This block is only visible to enrolled users "`;
diff --git a/tests/e2e/tests/block-visibility/block-visibility.test.js b/tests/e2e/tests/block-visibility/block-visibility.test.js
deleted file mode 100644
index b8cb7321..00000000
--- a/tests/e2e/tests/block-visibility/block-visibility.test.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * Test formsReady() events run on domReady()
- *
- * @since 1.12.0
- * @version 1.12.0
- */
-
-import {
- clickBlockAppender,
- createNewPost,
- getEditedPostContent,
- insertBlock,
- findSidebarPanelWithTitle,
-} from '@wordpress/e2e-test-utils';
-
-import {
- fillField,
-} from '@lifterlms/llms-e2e-test-utils';
-
-// import {
-// clearBlocks,
-// visitForm,
-// } from '../../../util';
-
-const edRootSelector = '.block-editor-block-list__layout.is-root-container';
-
-describe( 'BlockVisibility', () => {
-
- beforeEach( async () => {
-
- await createNewPost();
-
- // Add a paragraph to test.
- await clickBlockAppender();
- await page.keyboard.type( 'Lorem ipsum' );
-
- page.once( 'dialog', async dialog => await dialog.accept() ); // Leave page without saving.
-
- } );
-
- it ( 'should do nothing with default values', async () => {
-
- // Element in the post content doesn't have any visibility attributes.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // The DOM should not be outputting any visibility elements in the preview/editor area.
- expect( await page.evaluate( ( selector ) => document.querySelector( selector ), `${ edRootSelector } .llms-block-visibility` ) ).toBeNull();
-
- } );
-
- it ( 'should restrict a block to enrolled users', async () => {
-
- await page.select( '.llms-visibility-select select', 'enrolled' );
-
- // Attributes added to the post content.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // Indicator is visible in the DOM.
- expect( await page.$eval( `${ edRootSelector } .llms-block-visibility .llms-block-visibility--indicator`, el => el.innerHTML ) ).toMatchSnapshot();
-
- } );
-
- it ( 'should restrict a block to non-enrolled users', async () => {
-
- await page.select( '.llms-visibility-select select', 'not_enrolled' );
-
- // Attributes added to the post content.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // Indicator is visible in the DOM.
- expect( await page.$eval( `${ edRootSelector } .llms-block-visibility .llms-block-visibility--indicator`, el => el.innerHTML ) ).toMatchSnapshot();
-
- } );
-
- it ( 'should restrict a block to users in specific courses and/or memberships', async () => {
-
- await page.select( '.llms-visibility-select select', 'enrolled' );
-
-
- await page.waitForSelector( '.llms-visibility-select--in select' );
- await page.select( '.llms-visibility-select--in select', 'list_all' );
-
- await fillField( '.llms-search--course .llms-search__input input[type="text"]', 'Quickstart' );
- await page.waitForSelector( '.llms-search--course .llms-search__menu' );
- await page.keyboard.press( 'Enter' );
-
- await page.waitFor( 1000 );
-
- // Attributes added to the post content.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // Indicator is visible in the DOM.
- expect( await page.$eval( `${ edRootSelector } .llms-block-visibility .llms-block-visibility--indicator`, el => el.innerHTML ) ).toMatchSnapshot();
-
- } );
-
- it ( 'should restrict a block to logged in users', async () => {
-
- await page.select( '.llms-visibility-select select', 'logged_in' );
-
- // Attributes added to the post content.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // Indicator is visible in the DOM.
- expect( await page.$eval( `${ edRootSelector } .llms-block-visibility .llms-block-visibility--indicator`, el => el.innerHTML ) ).toMatchSnapshot();
-
- } );
-
- it ( 'should restrict a block to logged out users', async () => {
-
- await page.select( '.llms-visibility-select select', 'logged_out' );
-
- // Attributes added to the post content.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // Indicator is visible in the DOM.
- expect( await page.$eval( `${ edRootSelector } .llms-block-visibility .llms-block-visibility--indicator`, el => el.innerHTML ) ).toMatchSnapshot();
-
- } );
-
- describe( 'Unsupported', () => {
-
- it ( 'should not show visibility settings for the classic block', async () => {
-
- await insertBlock( 'Classic' );
-
- // Element in the post content doesn't have any visibility attributes.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // The DOM should not be outputting any visibility elements in the preview/editor area.
- expect( await page.evaluate( ( selector ) => document.querySelector( selector ), `${ edRootSelector } .llms-block-visibility` ) ).toBeNull();
-
- } );
-
- it ( 'should not show visibility settings for "dynamic" blocks', async () => {
-
- await insertBlock( 'Archives' );
-
- // Element in the post content doesn't have any visibility attributes.
- expect( await getEditedPostContent() ).toMatchSnapshot();
-
- // The DOM should not be outputting any visibility elements in the preview/editor area.
- expect( await page.evaluate( ( selector ) => document.querySelector( selector ), `${ edRootSelector } .llms-block-visibility` ) ).toBeNull();
-
- } );
-
- } );
-
-
-
-} );
diff --git a/tests/e2e/tests/blocks/__snapshots__/fields.test.js.snap b/tests/e2e/tests/blocks/__snapshots__/fields.test.js.snap
deleted file mode 100644
index 35b301ad..00000000
--- a/tests/e2e/tests/blocks/__snapshots__/fields.test.js.snap
+++ /dev/null
@@ -1,1192 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Blocks/FormFields User Display Name/Editor can be created using the block inserter 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "display_name",
- "description": "",
- "field": "text",
- "html_attrs": Object {},
- "id": "display_name",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Display Name",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "display_name",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-display-name",
-}
-`;
-
-exports[`Blocks/FormFields User Display Name/Editor can be created using the block inserter 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "display_name",
- "id": "display_name",
- "isPersisted": true,
- "label": "Display Name",
- "name": "display_name",
-}
-`;
-
-exports[`Blocks/FormFields User Display Name/Editor can modify the description 1`] = `"Custom description"`;
-
-exports[`Blocks/FormFields User Display Name/Editor can modify the label 1`] = `"Custom Label Display Name"`;
-
-exports[`Blocks/FormFields User Display Name/Editor can modify the placeholder 1`] = `"Custom Placeholder"`;
-
-exports[`Blocks/FormFields User Email/Editor can add a confirmation field 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can add a confirmation field 2`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_email",
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Email Address",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address_confirm",
- "name": "email_address",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-email",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can add a confirmation field 3`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address",
- "name": "email_address_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can add a confirmation field 4`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_email",
- "id": "email_address",
- "isPersisted": true,
- "label": "Email Address",
- "name": "email_address",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can add a confirmation field 5`] = `
-Object {
- "clientId": Any,
- "data_store": false,
- "data_store_key": false,
- "id": "email_address_confirm",
- "label": "Confirm Custom Label Email Address",
- "name": "email_address_confirm",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can be created using the block inserter 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_email",
- "description": "",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "email_address",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-email",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can be created using the block inserter 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_email",
- "id": "email_address",
- "isPersisted": true,
- "label": "Email Address",
- "name": "email_address",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can modify the description 1`] = `"Custom description"`;
-
-exports[`Blocks/FormFields User Email/Editor can modify the label 1`] = `"Custom Label Email Address"`;
-
-exports[`Blocks/FormFields User Email/Editor can modify the placeholder 1`] = `"Custom Placeholder"`;
-
-exports[`Blocks/FormFields User Email/Editor can remove the confirmation field 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_email",
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Custom Label Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "email_address",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-email",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can remove the confirmation field 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_email",
- "id": "email_address",
- "isPersisted": true,
- "label": "Email Address",
- "name": "email_address",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "stacked",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 2`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_email",
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address_confirm",
- "name": "email_address",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-email",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 3`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address",
- "name": "email_address_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 4`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 5`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_email",
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Email Address",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address_confirm",
- "name": "email_address",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-email",
-}
-`;
-
-exports[`Blocks/FormFields User Email/Editor can toggle the group layout 6`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "email",
- "html_attrs": Object {},
- "id": "email_address_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Email Address",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "email_address",
- "name": "email_address_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can add a confirmation field 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "logged_out",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can add a confirmation field 2`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_login",
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Username",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login_confirm",
- "name": "user_login",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can add a confirmation field 3`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login",
- "name": "user_login_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can add a confirmation field 4`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_login",
- "id": "user_login",
- "isPersisted": true,
- "label": "Username",
- "name": "user_login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can add a confirmation field 5`] = `
-Object {
- "clientId": Any,
- "data_store": false,
- "data_store_key": false,
- "id": "user_login_confirm",
- "label": "Confirm Custom Label Username",
- "name": "user_login_confirm",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can be created using the block inserter 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_login",
- "description": "",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "logged_out",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "user_login",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can be created using the block inserter 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_login",
- "id": "user_login",
- "isPersisted": true,
- "label": "Username",
- "name": "user_login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can modify the description 1`] = `"Custom description"`;
-
-exports[`Blocks/FormFields User Login/Editor can modify the label 1`] = `"Custom Label Username"`;
-
-exports[`Blocks/FormFields User Login/Editor can modify the placeholder 1`] = `"Custom Placeholder"`;
-
-exports[`Blocks/FormFields User Login/Editor can remove the confirmation field 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_login",
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Custom Label Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "logged_out",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "user_login",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can remove the confirmation field 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_login",
- "id": "user_login",
- "isPersisted": true,
- "label": "Username",
- "name": "user_login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "stacked",
- "llms_visibility": "logged_out",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 2`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_login",
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login_confirm",
- "name": "user_login",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 3`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login",
- "name": "user_login_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 4`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "logged_out",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 5`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_login",
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Username",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login_confirm",
- "name": "user_login",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-login",
-}
-`;
-
-exports[`Blocks/FormFields User Login/Editor can toggle the group layout 6`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "text",
- "html_attrs": Object {},
- "id": "user_login_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Username",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "user_login",
- "name": "user_login_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "Custom Placeholder",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can add a confirmation field 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can add a confirmation field 2`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_pass",
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Password",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password_confirm",
- "meter": true,
- "meter_description": "A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.",
- "min_strength": "strong",
- "name": "password",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can add a confirmation field 3`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password",
- "name": "password_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can add a confirmation field 4`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_pass",
- "id": "password",
- "isPersisted": true,
- "label": "Password",
- "name": "password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can add a confirmation field 5`] = `
-Object {
- "clientId": Any,
- "data_store": false,
- "data_store_key": false,
- "id": "password_confirm",
- "label": "Confirm Custom Label Password",
- "name": "password_confirm",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can be created using the block inserter 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_pass",
- "description": "",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password_confirm",
- "meter": true,
- "meter_description": "A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.",
- "min_strength": "strong",
- "name": "password",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can be created using the block inserter 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_pass",
- "id": "password",
- "isPersisted": true,
- "label": "Password",
- "name": "password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can modify the description 1`] = `"Custom description"`;
-
-exports[`Blocks/FormFields User Password/Editor can modify the label 1`] = `"Custom Label Password"`;
-
-exports[`Blocks/FormFields User Password/Editor can remove the confirmation field 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_pass",
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Custom Label Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "meter": true,
- "meter_description": "A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.",
- "min_strength": "strong",
- "name": "password",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can remove the confirmation field 2`] = `
-Object {
- "clientId": Any,
- "data_store": "users",
- "data_store_key": "user_pass",
- "id": "password",
- "isPersisted": true,
- "label": "Password",
- "name": "password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 1`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "stacked",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 2`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "users",
- "data_store_key": "user_pass",
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password_confirm",
- "meter": true,
- "meter_description": "A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.",
- "min_strength": "strong",
- "name": "password",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 3`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password",
- "name": "password_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 4`] = `
-Object {
- "attributes": Object {
- "fieldLayout": "columns",
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-confirm-group",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 5`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": "users",
- "data_store_key": "user_pass",
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password",
- "isConfirmationControlField": true,
- "isConfirmationField": false,
- "label": "Custom Label Password",
- "label_show_empty": false,
- "last_column": false,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password_confirm",
- "meter": true,
- "meter_description": "A strong password is required with at least 8 characters. To make it stronger, use both upper and lower case letters, numbers, and symbols.",
- "min_strength": "strong",
- "name": "password",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-password",
-}
-`;
-
-exports[`Blocks/FormFields User Password/Editor can toggle the group layout 6`] = `
-Object {
- "attributes": Object {
- "columns": 6,
- "data_store": false,
- "data_store_key": false,
- "description": "Custom description",
- "field": "password",
- "html_attrs": Object {
- "minlength": 8,
- },
- "id": "password_confirm",
- "isConfirmationControlField": false,
- "isConfirmationField": true,
- "label": "Confirm Custom Label Password",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "off",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "password",
- "name": "password_confirm",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": true,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-text",
-}
-`;
-
-exports[`Blocks/FormFields User Phone/Editor can be created using the block inserter 1`] = `
-Object {
- "attributes": Object {
- "columns": 12,
- "data_store": "usermeta",
- "data_store_key": "llms_phone",
- "description": "",
- "field": "tel",
- "html_attrs": Object {},
- "id": "llms_phone",
- "isConfirmationControlField": false,
- "isConfirmationField": false,
- "label": "Phone Number",
- "label_show_empty": false,
- "last_column": true,
- "llms_visibility": "all",
- "llms_visibility_in": "",
- "llms_visibility_posts": "[]",
- "match": "",
- "name": "llms_phone",
- "options": Array [],
- "options_preset": "",
- "placeholder": "",
- "required": false,
- },
- "clientId": Any,
- "innerBlocks": Anything,
- "isValid": true,
- "name": "llms/form-field-user-phone",
-}
-`;
-
-exports[`Blocks/FormFields User Phone/Editor can be created using the block inserter 2`] = `
-Object {
- "clientId": Any,
- "data_store": "usermeta",
- "data_store_key": "llms_phone",
- "id": "llms_phone",
- "isPersisted": true,
- "label": "Phone Number",
- "name": "llms_phone",
-}
-`;
-
-exports[`Blocks/FormFields User Phone/Editor can modify the description 1`] = `"Custom description"`;
-
-exports[`Blocks/FormFields User Phone/Editor can modify the label 1`] = `"Custom Label Phone Number"`;
-
-exports[`Blocks/FormFields User Phone/Editor can modify the placeholder 1`] = `"Custom Placeholder"`;
diff --git a/tests/e2e/tests/blocks/fields.test.js b/tests/e2e/tests/blocks/fields.test.js
deleted file mode 100644
index 7ceec763..00000000
--- a/tests/e2e/tests/blocks/fields.test.js
+++ /dev/null
@@ -1,336 +0,0 @@
-import {
- getAllBlocks,
- insertBlock,
- selectBlockByClientId,
-} from '@wordpress/e2e-test-utils';
-
-import {
- click,
- clickElementByText,
- logoutUser,
- toggleOpenRegistration,
- visitPage,
-} from '@lifterlms/llms-e2e-test-utils';
-
-import {
- blockSnapshotMatcher,
- clearBlocks,
- visitForm,
-} from '../../util';
-
-
-const fieldSnapshotMatcher = {
- clientId: expect.any( String ),
-};
-
-/**
- * Utility function to retrieve the block being tested
- *
- * Before testing a block we clear all blocks so there will only ever
- * be a single block in the blocks list. This quickly pulls the list
- * and returns the first one.
- *
- * @since 2.0.0
- *
- * @return {Object} A WP_Block object.
- */
-async function getTestedBlock() {
- const blocks = await getAllBlocks();
- return blocks[0];
-}
-
-async function getLoadedBlocks() {
- return await page.evaluate( async() => {
- return wp.data.select( 'llms/user-info-fields' ).getLoadedFields();
- } );
-}
-
-async function getField( name ) {
- return await page.evaluate( ( _name ) => wp.data.select( 'llms/user-info-fields' ).getField( _name ), name );
-}
-
-async function testLabelProp() {
-
- const { clientId } = await getTestedBlock();
- await page.type( `#block-${ clientId } label.rich-text`, 'Custom Label ' );
-
- const { attributes } = await getTestedBlock();
- expect( attributes.label ).toMatchSnapshot();
-
-}
-
-async function testDescriptionProp() {
-
- const { clientId } = await getTestedBlock();
- await page.type( `#block-${ clientId } span.rich-text`, 'Custom description' );
-
- const { attributes } = await getTestedBlock();
- expect( attributes.description ).toMatchSnapshot();
-
-}
-
-async function testFieldColumns() {
-
- const
- selector = '.llms-field-width-select select',
- opts = await page.$$eval( `${ selector } option`, els => els.map( ( { value } ) => value ) );
-
- // Make sure the right options are available.
- expect( opts ).toEqual( [ '12', '9', '8', '6', '4', '3' ] );
-
- for ( let i = opts.length - 1; i >= 0; i-- ) {
-
- const cols = opts[ i ];
- await page.select( selector, cols );
-
- const { attributes } = await getTestedBlock();
- expect( attributes.columns ).toBe( parseInt( cols, 10 ) );
-
- }
-
-}
-
-async function testPlaceholderProp( editable = true ) {
-
- const
- { clientId } = await getTestedBlock(),
- selector = `#block-${ clientId } input`;
-
- if ( editable ) {
- await page.type( selector, 'Custom Placeholder' );
-
- const { attributes } = await getTestedBlock();
- expect( attributes.placeholder ).toMatchSnapshot();
-
- } else {
-
- expect( await page.$eval( selector, el => el.disabled ) ).toBe( true );
-
- }
-}
-
-async function testAddConfirmationProp( editable = true, fieldName = '' ) {
-
- if ( editable ) {
-
- await clickElementByText( 'Confirmation Field' );
-
- await page.waitFor( 2000 );
-
- const
- block = await getTestedBlock(),
- { innerBlocks } = block;
-
- // Group.
- expect( block ).toMatchSnapshot( blockSnapshotMatcher );
-
- // Main field.
- expect( innerBlocks[0] ).toMatchSnapshot( blockSnapshotMatcher );
-
- // Confirm field.
- expect( innerBlocks[1] ).toMatchSnapshot( blockSnapshotMatcher );
-
- // Test loading block via the llms/user-info-fields store.
- await page.waitFor( 1000 ); // Waiting for subscription watcher to catch up.
-
- // Main field.
- const loadedField = await getField( fieldName );
- expect( loadedField ).toMatchSnapshot( fieldSnapshotMatcher );
- expect( loadedField.clientId ).toBe( innerBlocks[0].clientId );
-
- // Confirm field.
- const loadedConfirmField = await getField( `${fieldName}_confirm` );
- expect( loadedConfirmField ).toMatchSnapshot( fieldSnapshotMatcher );
- expect( loadedConfirmField.clientId ).toBe( innerBlocks[1].clientId );
-
- } else {
- expect( await page.evaluate( () => document.querySelector( '.llms-confirmation-field-toggle' ) ) ).toBeNull();
- }
-
-}
-
-async function testDelConfirmationProp( fieldName ) {
-
- await clickElementByText( 'Remove confirmation field' );
-
- const
- block = await getTestedBlock(),
- { innerBlocks } = block;
-
- expect( block ).toMatchSnapshot( blockSnapshotMatcher );
- expect( innerBlocks ).toEqual( [] );
-
- // Test field data.
- await page.waitFor( 1000 ); // Waiting for subscription watcher to catch up.
- const loadedField = await getField( fieldName );
- expect( loadedField ).toMatchSnapshot( fieldSnapshotMatcher );
- expect( loadedField.clientId ).toBe( block.clientId );
-
- // Confirm field is gone.
- expect( await getField( `${ fieldName }_confirm` ) ).toBeNull();
-
-}
-
-async function testGroupLayout() {
-
- const { clientId } = await getTestedBlock();
- await selectBlockByClientId( clientId );
-
- const selections = [ 'Stacked', 'Columns' ];
-
- for ( let i = 0; i < selections.length; i++ ) {
-
- await clickElementByText( selections[ i ] );
-
- const
- block = await getTestedBlock(),
- { innerBlocks } = block;
-
- expect( block ).toMatchSnapshot( blockSnapshotMatcher );
-
- expect( innerBlocks[0] ).toMatchSnapshot( blockSnapshotMatcher );
- expect( innerBlocks[1] ).toMatchSnapshot( blockSnapshotMatcher );
- }
-
-}
-
-async function testRequiredProp( editable = true ) {
-
- if ( editable ) {
-
- await click( '.llms-required-field-toggle label' );
- let { attributes } = await getTestedBlock();
- expect( attributes.required ).toBe( true );
-
- await click( '.llms-required-field-toggle label' );
- ( { attributes } = await getTestedBlock() );
- expect( attributes.required ).toBe( false );
-
- } else {
- expect( await page.evaluate( () => document.querySelector( '.llms-required-field-toggle' ) ) ).toBeNull();
- }
-
-}
-
-
-
-// List of fields to run tests on.
-const fields = [
- {
- name: 'User Email',
- confirmation: true,
- required: false,
- placeholder: true,
- fieldName: 'email_address',
- },
- {
- name: 'User Password',
- confirmation: true,
- required: false,
- placeholder: false,
- fieldName: 'password',
- },
- {
- name: 'User Login',
- confirmation: true,
- required: false,
- placeholder: true,
- fieldName: 'user_login',
- },
- {
- name: 'User Display Name',
- confirmation: false,
- required: false,
- placeholder: true,
- fieldName: 'display_name',
- },
- {
- name: 'User Phone',
- confirmation: false,
- required: true,
- placeholder: true,
- fieldName: 'llms_phone',
- },
-
- /**
- * @todo Build a set of recursive tests to run all tests against each block within
- * a group of blocks.
- *
- * Add tests for Name & Address blocks that are made up entirely of innerBlocks
- *
- * Additionally the same set of tests for label, description, etc... should be run
- * against confirmation fields.
- *
- * Additional custom tests should be written for custom properties on the password field (meter toggling, length, and meter desc.).
- *
- * Additional tests should be run on the frontend too, maybe? Although this maybe redundant, assuming the phpunit tests
- * properly test output we shouldn't have to additionally write E2E tests to test the output of the field data...
- */
-];
-
-describe( 'Blocks/FormFields', () => {
-
- beforeAll( async () => {
-
- await visitForm();
- page.once( 'dialog', async dialog => await dialog.accept() ); // Leave page without saving.
-
- } );
-
-
- let i = 0;
- while ( i < fields.length ) {
-
- const field = fields[i];
-
- describe( `${ field.name }/Editor`, () => {
-
- beforeAll( async () => {
- await clearBlocks();
- await insertBlock( field.name );
- } );
-
- it ( 'can be created using the block inserter', async () => {
-
- // Test the block itself.
- const testedBlock = await getTestedBlock();
- expect( testedBlock ).toMatchSnapshot( blockSnapshotMatcher );
-
- // Test loading block via the llms/user-info-fields store.
- await page.waitFor( 1000 ); // Waiting for subscription watcher to catch up.
- const loadedField = await getField( field.fieldName );
- expect( loadedField ).toMatchSnapshot( fieldSnapshotMatcher );
- expect( loadedField.clientId ).toBe( testedBlock.clientId );
-
- } );
-
- it ( 'can modify the label', async () => await testLabelProp() );
- it ( 'can modify the description', async () => await testDescriptionProp() );
- it ( 'can modify the field columns width', async() => await testFieldColumns() )
-
- if ( field.placeholder ) {
- it ( 'can modify the placeholder', async () => await testPlaceholderProp( true ) );
- } else {
- it ( 'cannot modify the placeholder', async () => await testPlaceholderProp( false ) );
- }
-
- if ( field.confirmation ) {
- it ( 'can add a confirmation field', async () => await testAddConfirmationProp( true, field.fieldName ) );
- it ( 'can toggle the group layout', async() => await testGroupLayout() );
- it ( 'can remove the confirmation field', async() => await testDelConfirmationProp( field.fieldName ) );
- } else {
- it ( 'cannot add a confirmation field', async () => await testAddConfirmationProp( false, field.fieldName ) );
- }
-
- if ( field.required ) {
- it ( 'can control the field required attribute', async () => await testRequiredProp( true ) );
- } else {
- it ( 'cannot control the required attribute', async () => await testRequiredProp( false ) );
- }
-
- } );
-
- ++i;
- }
-
-} );
diff --git a/tests/e2e/util/block-snapshot-matcher.js b/tests/e2e/util/block-snapshot-matcher.js
deleted file mode 100644
index 67dba93a..00000000
--- a/tests/e2e/util/block-snapshot-matcher.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * A jest snapshot matcher used to match against a WP_Block object
- *
- * This matcher ensures that innerBlocks (which may vary) and the clientId
- * don't affect snapshots of the block object.
- *
- * @since 2.0.0
- *
- * @type {Object}
- */
-export default {
- clientId: expect.any( String ),
- innerBlocks: expect.anything(), // You'd think that `expect.any( Array )` would work but doesn't.
-};
diff --git a/tests/e2e/util/clear-blocks.js b/tests/e2e/util/clear-blocks.js
deleted file mode 100644
index 88a6457b..00000000
--- a/tests/e2e/util/clear-blocks.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { getAllBlocks } from '@wordpress/e2e-test-utils';
-
-/**
- * Select all blocks in the editor and then delete them
- *
- * @since 1.12.0
- *
- * @return {Void}
- */
-export default async () => {
- return page.evaluate( () => window.wp.data.dispatch( 'core/block-editor' ).removeBlocks( window.wp.data.select( 'core/block-editor' ).getBlocks().map( ( { clientId } ) => clientId ) ) );
-};
diff --git a/tests/e2e/util/index.js b/tests/e2e/util/index.js
deleted file mode 100644
index e18be421..00000000
--- a/tests/e2e/util/index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * E2E Utilities functions
- *
- * @package LifterLMS_Blocks/Tests/E2E/Utils
- *
- * @since 1.12.0
- * @version 2.0.0
- */
-
-import blockSnapshotMatcher from './block-snapshot-matcher';
-import clearBlocks from './clear-blocks';
-import openFormSettingsPanel from './open-form-settings-panel';
-import publishAndSaveEntities from './publish-and-save-entities';
-import removeBlockByClientId from './remove-block-by-client-id';
-import visitForm from './visit-form';
-
-export {
- blockSnapshotMatcher,
- clearBlocks,
- openFormSettingsPanel,
- publishAndSaveEntities,
- removeBlockByClientId,
- visitForm,
-};
diff --git a/tests/e2e/util/open-form-settings-panel.js b/tests/e2e/util/open-form-settings-panel.js
deleted file mode 100644
index 974bd197..00000000
--- a/tests/e2e/util/open-form-settings-panel.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { clickElementByText } from '@lifterlms/llms-e2e-test-utils';
-
-/**
- * Opens the "LifterLMS Form" document settings panel (sidebar) in the block editor
- *
- * @since 2.0.0
- *
- * @return {Object} Returns element selector for the opened panel.
- */
-export default async () => {
-
- await clickElementByText( 'Form', '.components-button.edit-post-sidebar__panel-tab' );
-
- const isOpen = await page.$eval( '.llms-forms-doc-settings', el => el.classList.contains( 'is-opened' ) );
-
- if ( ! isOpen ) {
- await clickElementByText( 'Form Settings', '.components-panel .components-button' );
- }
-
- return page.waitForSelector( '.components-panel__body.llms-forms-doc-settings.is-opened')
-
-}
diff --git a/tests/e2e/util/publish-and-save-entities.js b/tests/e2e/util/publish-and-save-entities.js
deleted file mode 100644
index bc12a90f..00000000
--- a/tests/e2e/util/publish-and-save-entities.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import {
- click,
-} from '@lifterlms/llms-e2e-test-utils';
-
-export default async () => {
-
- const entitiesSaveSelector = '.editor-entities-saved-states__save-button';
-
- // Clicks the "Update" button in the editor header bar.
- await page.click( '.editor-post-publish-button' );
-
- // Wait for the entities save button to show up.
- try {
-
- await page.waitForSelector( entitiesSaveSelector, { timeout: 2000 } );
-
- // If it doesn't, we don't have any entities to save and the first click attempt worked just fine.
- } catch ( e ) {
-
- // Wait for the snackbar to confirm the save (this is how the wp core publishPost() e2e test util works).
- return page.waitForSelector( '.components-snackbar' );
- }
-
- // Click the save entities button.
- return click( entitiesSaveSelector );
-
-};
diff --git a/tests/e2e/util/remove-block-by-client-id.js b/tests/e2e/util/remove-block-by-client-id.js
deleted file mode 100644
index 3306f73e..00000000
--- a/tests/e2e/util/remove-block-by-client-id.js
+++ /dev/null
@@ -1,8 +0,0 @@
-
-export default async ( clientId ) => {
-
- return page.evaluate( async ( cid ) => {
- return wp.data.dispatch( 'core/block-editor' ).removeBlock( cid );
- }, clientId );
-
-}
diff --git a/tests/e2e/util/visit-form.js b/tests/e2e/util/visit-form.js
deleted file mode 100644
index 72062ce5..00000000
--- a/tests/e2e/util/visit-form.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import {
- clickAndWait,
- dismissEditorWelcomeGuide,
-} from '@lifterlms/llms-e2e-test-utils';
-
-import { visitAdminPage } from '@wordpress/e2e-test-utils';
-
-/**
- * Visit the block editor for a requested form
- *
- * @since 1.12.0
- *
- * @param {String|Number} form The title or WP_Post ID of a form.
- * @return {void}
- */
-export default async ( form = 'Register' ) => {
-
- let
- page = 'edit.php',
- qs = 'post_type=llms_form';
-
- // If form is a WP_Post ID go right to the form.
- if ( ! isNaN( Number( form ) ) ) {
- await visitAdminPage( 'post.php', `post=${ form }&action=edit` );
- // Otherwise look it up from the post table by title
- } else {
- await visitAdminPage( 'edit.php', `s=${ form }&post_type=llms_form` );
- await clickAndWait( '#the-list tr:first-child a.row-title' );
- }
-
- await dismissEditorWelcomeGuide();
-
-};
diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php
deleted file mode 100644
index d96656a7..00000000
--- a/tests/phpunit/bootstrap.php
+++ /dev/null
@@ -1,65 +0,0 @@
-assets_dir = dirname( $this->tests_dir ) . '/assets/';
-
- if ( $this->plugin_main ) {
- require_once( $this->plugin_dir . '/' . $this->plugin_main );
- }
-
- if ( $this->use_core ) {
- define( 'LLMS_USE_PHP_SESSIONS', true );
- define( 'LLMS_PLUGIN_DIR', WP_PLUGIN_DIR . '/lifterlms/' );
- $this->load_plugin( 'lifterlms', 'lifterlms.php' );
- }
-
- $this->load_plugin( 'classic-editor', 'classic-editor.php' );
-
- }
-
-}
-
-global $llms_tests_bootstrap;
-$llms_tests_bootstrap = new LLMS_Blocks_Tests_Bootstrap();
-return $llms_tests_bootstrap;
diff --git a/tests/phpunit/framework/class-llms-blocks-unit-test-case.php b/tests/phpunit/framework/class-llms-blocks-unit-test-case.php
deleted file mode 100644
index 8db6d5d2..00000000
--- a/tests/phpunit/framework/class-llms-blocks-unit-test-case.php
+++ /dev/null
@@ -1,30 +0,0 @@
- 'classic',
- 'allow-users' => 'disallow',
- ) );
-
- update_option( 'classic-editor-replace', $settings['editor'] );
- update_option( 'classic-editor-allow-users', $settings['allow-users'] );
-
- }
-
-}
diff --git a/tests/phpunit/framework/functions-llms-blocks-test-mocks.php b/tests/phpunit/framework/functions-llms-blocks-test-mocks.php
deleted file mode 100644
index e16370f2..00000000
--- a/tests/phpunit/framework/functions-llms-blocks-test-mocks.php
+++ /dev/null
@@ -1,70 +0,0 @@
-val pairs to the global to manage options retrieved by et_get_option()
- * @since 1.3.4
- */
-global $llms_blocks_mock_et_options;
-$llms_blocks_mock_et_options = array();
-
-if ( ! function_exists( 'et_get_option' ) ) {
-
- /**
- * Mock the Divi et_get_option() method
- * @param string $option_name option key.
- * @param string $default default value when option not set.
- * @return mixed
- * @since 1.3.4
- * @version 1.3.4
- */
- function et_get_option( $option_name, $default = '' ) {
-
- global $llms_blocks_mock_et_options;
- if ( $llms_blocks_mock_et_options && isset( $llms_blocks_mock_et_options[ $option_name ] ) ) {
- return $llms_blocks_mock_et_options[ $option_name ];
- }
- return $default;
-
- }
-
-}
diff --git a/tests/phpunit/unit-tests/class-llms-blocks-test-assets.php b/tests/phpunit/unit-tests/class-llms-blocks-test-assets.php
deleted file mode 100644
index 4ac5ec6b..00000000
--- a/tests/phpunit/unit-tests/class-llms-blocks-test-assets.php
+++ /dev/null
@@ -1,108 +0,0 @@
-assertTrue( $main->assets instanceof LLMS_Assets );
-
- // Both scripts are defined.
- $this->assertTrue( $main->assets->register_script( 'llms-blocks-editor' ) );
- $this->assertTrue( $main->assets->register_style( 'llms-blocks-editor' ) );
-
- $this->assertEquals( 999, has_action( 'enqueue_block_editor_assets', array( $main, 'editor_assets' ) ) );
-
- $this->deregister_assets();
-
- }
-
- /**
- * Test editor_assets()
- *
- * @since 1.10.0
- *
- * @return void
- */
- public function test_editor_assets() {
-
- $main = new LLMS_Blocks_Assets();
- $this->deregister_assets();
-
- $this->assertAssetNotEnqueued( 'script', 'llms-blocks-editor' );
- $this->assertAssetNotEnqueued( 'style', 'llms-blocks-editor' );
-
- $main->editor_assets();
-
- $this->assertAssetIsEnqueued( 'script', 'llms-blocks-editor' );
- $this->assertAssetIsEnqueued( 'style', 'llms-blocks-editor' );
-
- }
-
- /**
- * Test backwards compat asset define and enqueue
- *
- * @since 2.0.0
- *
- * @return void
- */
- public function test_backwards_compat_assets() {
-
- wp_dequeue_script( 'llms-blocks-editor-bc' );
-
- global $wp_version;
- $temp = $wp_version;
-
- // Asset not defined during setup.
- $wp_version = '5.7.0';
- $main = new LLMS_Blocks_Assets();
- $this->assertFalse( array_key_exists( 'llms-blocks-editor-bc', LLMS_Unit_Test_Util::call_method( $main->assets, 'get_definitions', array( 'script' ) ) ) );
-
- $main->editor_assets();
- $this->assertAssetNotEnqueued( 'script', 'llms-blocks-editor-bc' );
-
- // Asset is defined during setup.
- $wp_version = '5.6.4';
- $main = new LLMS_Blocks_Assets();
- $this->assertTrue( array_key_exists( 'llms-blocks-editor-bc', LLMS_Unit_Test_Util::call_method( $main->assets, 'get_definitions', array( 'script' ) ) ) );
-
- $main->editor_assets();
- $this->assertAssetIsEnqueued( 'script', 'llms-blocks-editor-bc' );
-
- $wp_version = $temp;
-
- }
-
-}
diff --git a/tests/phpunit/unit-tests/class-llms-blocks-test-blocks.php b/tests/phpunit/unit-tests/class-llms-blocks-test-blocks.php
deleted file mode 100644
index 8f38f589..00000000
--- a/tests/phpunit/unit-tests/class-llms-blocks-test-blocks.php
+++ /dev/null
@@ -1,163 +0,0 @@
- 'llms-user-info-fields',
- 'title' => 'User Information',
- ),
- array(
- 'slug' => 'llms-custom-fields',
- 'title' => 'Custom User Information',
- ),
- array(
- 'slug' => 'llms-blocks',
- 'title' => 'LifterLMS Blocks',
- ),
- );
-
- $existing = array(
- 'slug' => 'fake-cat-slug',
- 'title' => 'Fake Cat Title',
- );
-
- $this->assertSame( $our_cats, $obj->add_block_category( array() ) );
- $this->assertSame( array( $our_cats[0], $our_cats[1], $existing, $our_cats[2] ), $obj->add_block_category( array( $existing ) ) );
-
- }
-
- /**
- * Ensure the WP core method get_block_categories() results in the `llms-blocks` category being added.
- *
- * @since 1.5.1
- *
- * @return void
- */
- public function test_add_block_category_integration() {
-
- $slugs = wp_list_pluck( get_block_categories( $this->factory->post->create_and_get() ), 'slug' );
- $this->assertTrue( in_array( 'llms-blocks', $slugs, true ) );
-
- }
-
- /**
- * Test the admin_print_scripts() method.
- *
- * @since 1.5.1
- * @since 2.0.0 Force using block editor.
- *
- * @return void
- */
- public function test_admin_print_scripts() {
-
- $obj = new LLMS_Blocks();
-
- // no current screen.
- $this->assertOutputEmpty( array( $obj, 'admin_print_scripts' ) );
-
- // Don't Display.
- foreach ( array( 'dashboard', 'options-general', 'tools', 'users-new', 'plugin-editor', 'edit-page' ) as $screen ) {
- set_current_screen( $screen );
- $this->assertOutputEmpty( array( $obj, 'admin_print_scripts' ) );
- }
-
- // Make sure we use the block editor.
- add_filter( 'use_block_editor_for_post', '__return_true' );
- add_filter( 'use_block_editor_for_post_type', '__return_true' );
-
- // Display
- foreach ( array( 'post', 'page', 'course', 'llms_membership' ) as $screen ) {
- set_current_screen( $screen );
- // This is where "is_block_editor" is actually set.
- get_current_screen()->is_block_editor(true);
- $this->assertOutputContains( '