diff --git a/src/FormBuilder/ViewModels/FormBuilderViewModel.php b/src/FormBuilder/ViewModels/FormBuilderViewModel.php index 3eea00928e..b3fa40ea25 100644 --- a/src/FormBuilder/ViewModels/FormBuilderViewModel.php +++ b/src/FormBuilder/ViewModels/FormBuilderViewModel.php @@ -87,12 +87,18 @@ public function isRecurringEnabled(): bool /** * @since 3.0.0 */ - public function getGoalTypeOption(string $value, string $label, string $description): array + public function getGoalTypeOption( + string $value, + string $label, + string $description, + bool $isCurrency = false + ): array { return [ 'value' => $value, 'label' => $label, 'description' => $description, + 'isCurrency' => $isCurrency, ]; } @@ -105,7 +111,8 @@ public function getGoalTypeOptions(): array $this->getGoalTypeOption( GoalType::AMOUNT, __('Amount Raised', 'give'), - __('The total amount raised for the form', 'give') + __('The total amount raised for the form', 'give'), + true ), $this->getGoalTypeOption( GoalType::DONATIONS, @@ -124,7 +131,8 @@ public function getGoalTypeOptions(): array $this->getGoalTypeOption( GoalType::AMOUNT_FROM_SUBSCRIPTIONS, __('Subscription Amount Raised', 'give'), - __('The total amount raised for the form through subscriptions', 'give') + __('The total amount raised for the form through subscriptions', 'give'), + true ), $this->getGoalTypeOption( GoalType::SUBSCRIPTIONS, diff --git a/src/FormBuilder/resources/js/form-builder/src/App.tsx b/src/FormBuilder/resources/js/form-builder/src/App.tsx index 2a2897cfe0..fbbc5a739f 100644 --- a/src/FormBuilder/resources/js/form-builder/src/App.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/App.tsx @@ -3,7 +3,6 @@ import BlockEditorContainer from './containers/BlockEditorContainer'; import {FormStateProvider} from './stores/form-state'; import {Storage} from './common'; import defaultBlocks from './blocks.json'; -import Feedback from '@givewp/form-builder/feedback'; import {BlockInstance} from '@wordpress/blocks'; import './App.scss'; import FormBuilderErrorBoundary from '@givewp/form-builder/errors/FormBuilderErrorBounday'; @@ -55,7 +54,6 @@ export default function App() { - diff --git a/src/FormBuilder/resources/js/form-builder/src/blocks/elements/paragraph/Edit.tsx b/src/FormBuilder/resources/js/form-builder/src/blocks/elements/paragraph/Edit.tsx index 927f34493e..5f9a9b85a0 100644 --- a/src/FormBuilder/resources/js/form-builder/src/blocks/elements/paragraph/Edit.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/blocks/elements/paragraph/Edit.tsx @@ -1,7 +1,6 @@ import {BlockEditProps} from '@wordpress/blocks'; -import {RichText, InspectorControls} from '@wordpress/block-editor'; +import {RichText} from '@wordpress/block-editor'; import {__} from '@wordpress/i18n'; -import {PanelBody, PanelRow, TextareaControl, TextControl} from "@wordpress/components"; export default function Edit({attributes, setAttributes}: BlockEditProps) { const {content} = attributes; @@ -15,17 +14,6 @@ export default function Edit({attributes, setAttributes}: BlockEditProps) { onChange={(content) => setAttributes({content})} placeholder={__('Enter some text', 'give')} /> - - - - setAttributes({content})} - /> - - - ); } diff --git a/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts b/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts index 557ff8a253..d15ace1536 100644 --- a/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts +++ b/src/FormBuilder/resources/js/form-builder/src/common/getWindowData.ts @@ -14,6 +14,7 @@ type GoalTypeOption = { value: string; label: string; description: string; + isCurrency: boolean; }; /** diff --git a/src/FormBuilder/resources/js/form-builder/src/containers/HeaderContainer.tsx b/src/FormBuilder/resources/js/form-builder/src/containers/HeaderContainer.tsx index 8bafdfa08a..6883e8f54e 100644 --- a/src/FormBuilder/resources/js/form-builder/src/containers/HeaderContainer.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/containers/HeaderContainer.tsx @@ -1,8 +1,8 @@ import React, {useState} from 'react'; import {EditIcon, GiveIcon} from '../components/icons'; -import {drawerRight, moreVertical, external} from '@wordpress/icons'; +import {drawerRight, external, moreVertical} from '@wordpress/icons'; import {setFormSettings, setTransferState, useFormState, useFormStateDispatch} from '../stores/form-state'; -import {Button, Dropdown, MenuGroup, MenuItem, TextControl} from '@wordpress/components'; +import {Button, Dropdown, ExternalLink, MenuGroup, MenuItem, TextControl} from '@wordpress/components'; import {__} from '@wordpress/i18n'; import {Header} from '../components'; import {getWindowData, Storage} from '../common'; @@ -11,9 +11,10 @@ import {setIsDirty} from '@givewp/form-builder/stores/form-state/reducer'; import revertMissingBlocks from '@givewp/form-builder/common/revertMissingBlocks'; import {Markup} from 'interweave'; import {InfoModal, ModalType} from '../components/modal'; -import {setEditorMode, useEditorState, useEditorStateDispatch} from "@givewp/form-builder/stores/editor-state"; -import EditorMode from "@givewp/form-builder/types/editorMode"; -import {useDispatch} from "@wordpress/data"; +import {setEditorMode, useEditorState, useEditorStateDispatch} from '@givewp/form-builder/stores/editor-state'; +import EditorMode from '@givewp/form-builder/types/editorMode'; +import {useDispatch} from '@wordpress/data'; +import {cleanForSlug} from '@wordpress/url'; const Logo = () => (
(
); -const HeaderContainer = ({ - SecondarySidebarButtons = null, - showSidebar, - toggleShowSidebar, - }) => { +/** + * @unreleased dispatch page slug from form title on initial publish. + */ +const HeaderContainer = ({SecondarySidebarButtons = null, showSidebar, toggleShowSidebar}) => { const {blocks, settings: formSettings, isDirty, transfer} = useFormState(); const {formTitle} = formSettings; @@ -54,6 +54,7 @@ const HeaderContainer = ({ const isPublished = 'publish' === formSettings.formStatus; const {isMigratedForm, isTransferredForm} = window.migrationOnboardingData; const {createSuccessNotice} = useDispatch('core/notices'); + const { formPage: {permalink}, } = getWindowData(); @@ -72,7 +73,12 @@ const HeaderContainer = ({ setErrorMessage(error.message); }) .then(({formTitle, pageSlug}: FormSettings) => { - dispatch(setFormSettings({formTitle, pageSlug})); + dispatch( + setFormSettings({ + formTitle, + pageSlug, + }) + ); dispatch(setIsDirty(false)); setSaving(null); showOnSaveNotice(formStatus); @@ -82,22 +88,25 @@ const HeaderContainer = ({ const showOnSaveNotice = (formStatus: string) => { if ('draft' === formStatus) { createSuccessNotice(__('Draft saved.', 'give'), { - type: 'snackbar' + type: 'snackbar', }); } else { - const notice = 'publish' === formStatus && formSettings.formStatus !== 'draft' - ? __('Form updated.', 'give') - : __('Form published.', 'give') + const notice = + 'publish' === formStatus && formSettings.formStatus !== 'draft' + ? __('Form updated.', 'give') + : __('Form published.', 'give'); createSuccessNotice(notice, { type: 'snackbar', - actions: [{ - label: __('View form', 'give'), - url: permalink - }] + actions: [ + { + label: __('View form', 'give'), + url: permalink, + }, + ], }); } - } + }; const {mode} = useEditorState(); const dispatchEditorState = useEditorStateDispatch(); @@ -108,7 +117,7 @@ const HeaderContainer = ({ if (EditorMode.design === mode) { dispatchEditorState(setEditorMode(EditorMode.schema)); } - } + }; // @ts-ignore return ( @@ -126,7 +135,7 @@ const HeaderContainer = ({ borderRadius: '4px', display: 'flex', gap: 'var(--givewp-spacing-2)', - padding: 'var(--givewp-spacing-3) var(--givewp-spacing-4)' + padding: 'var(--givewp-spacing-3) var(--givewp-spacing-4)', }} onClick={() => toggleEditorMode()} icon={EditIcon} @@ -140,7 +149,10 @@ const HeaderContainer = ({ dispatch(setFormSettings({formTitle}))} + onChange={(formTitle) => { + !isPublished && dispatch(setFormSettings({pageSlug: cleanForSlug(formTitle)})); + dispatch(setFormSettings({formTitle})); + }} /> } contentRight={ @@ -154,16 +166,11 @@ const HeaderContainer = ({ {isSaving && 'draft' === isSaving ? __('Saving...', 'give') : 'draft' === formSettings.formStatus - ? __('Save as Draft', 'give') - : __('Switch to Draft', 'give')} + ? __('Save as Draft', 'give') + : __('Switch to Draft', 'give')} {isPublished && ( - - ); -}; - -export default FeedbackButton; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/FeedbackIcon.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/FeedbackIcon.tsx deleted file mode 100644 index 743afd9098..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/FeedbackIcon.tsx +++ /dev/null @@ -1,21 +0,0 @@ -const FeedbackIcon = () => { - return ( - - - - - ); -}; - -export default FeedbackIcon; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/index.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/index.tsx deleted file mode 100644 index 18676b01f1..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/index.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, {useEffect, useState} from 'react'; -import {__} from '@wordpress/i18n'; -import Container from './Container'; -import FeedbackButton from './FeedbackButton'; - -import {Container as PopupContainer, Content as PopupContent, Header as PopupHeader} from './popup'; -import {ExternalLink} from '@wordpress/components'; - -const feedbackUrl = 'https://docs.givewp.com/nextgenfeedback'; - -const HIDE_FEEDBACK = 'givewpNextGenHideFeedback'; - -const Feedback = () => { - const [hidden, setHidden] = useState(false); - const closeCallback = () => { - setHidden(true); - localStorage.setItem(HIDE_FEEDBACK, 'true'); - }; - - useEffect(() => { - setHidden(!!localStorage.getItem(HIDE_FEEDBACK)); - }, []); - - // @ts-ignore - return ( - - {!hidden && ( - - - -
- - {__( - 'Let us know what you think about the form builder to help improve the product experience.', - 'give' - )} - -
-
- - {__('Provide Feedback', 'give')} - -
-
-
- )} - setHidden(!hidden)}>{__('Feedback', 'give')} -
- ); -}; - -export default Feedback; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/CloseIcon.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/CloseIcon.tsx deleted file mode 100644 index 186bcd2ccc..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/CloseIcon.tsx +++ /dev/null @@ -1,9 +0,0 @@ -const CloseIcon = (props) => { - return ( - - - - ); -}; - -export default CloseIcon; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Container.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Container.tsx deleted file mode 100644 index 2d20d9c6c8..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Container.tsx +++ /dev/null @@ -1,22 +0,0 @@ -const Container = ({children}) => { - return ( -
- {children} -
- ); -} - -export default Container; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Content.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Content.tsx deleted file mode 100644 index 6d6b5cd8d8..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Content.tsx +++ /dev/null @@ -1,18 +0,0 @@ -const Content = ({children}) => { - return ( -
- {children} -
- ); -} - -export default Content; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Header.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Header.tsx deleted file mode 100644 index 755c625cc3..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/Header.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import {Button, Icon} from '@wordpress/components'; -import CloseIcon from './CloseIcon'; -import HeaderIcon from './HeaderIcon'; - -const Header = ({title, closeCallback}) => { - return ( -
-
- - {title} -
-
- ); -}; - -export default Header; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/HeaderIcon.tsx b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/HeaderIcon.tsx deleted file mode 100644 index 2b2e6233c8..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/HeaderIcon.tsx +++ /dev/null @@ -1,11 +0,0 @@ -const HeaderIcon = (props) => { - return ( - - - - - - ) -} - -export default HeaderIcon; diff --git a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/index.ts b/src/FormBuilder/resources/js/form-builder/src/feedback/popup/index.ts deleted file mode 100644 index 65a0f0cae9..0000000000 --- a/src/FormBuilder/resources/js/form-builder/src/feedback/popup/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Container from './Container' -import Header from './Header' -import Content from './Content' - -export { - Container, - Header, - Content, -} diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/donation-goal/index.tsx b/src/FormBuilder/resources/js/form-builder/src/settings/donation-goal/index.tsx index 4304686b89..c31b5b18af 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/donation-goal/index.tsx +++ b/src/FormBuilder/resources/js/form-builder/src/settings/donation-goal/index.tsx @@ -10,6 +10,7 @@ import { } from '@wordpress/components'; import debounce from 'lodash.debounce'; import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData'; +import {CurrencyControl} from '@givewp/form-builder/components/CurrencyControl'; const {goalTypeOptions} = getFormBuilderWindowData(); @@ -69,12 +70,21 @@ const DonationGoalSettings = () => { /> - dispatch(setFormSettings({goalAmount})), 100)} - /> + {selectedGoalType.isCurrency ? ( + dispatch(setFormSettings({goalAmount})), 500)} + /> + ) : ( + dispatch(setFormSettings({goalAmount}))} + /> + )} )} diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/index.js b/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/index.js index 5afba19143..63787779e3 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/index.js +++ b/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/index.js @@ -3,12 +3,18 @@ import {__} from '@wordpress/i18n'; import {setFormSettings, useFormState, useFormStateDispatch} from '@givewp/form-builder/stores/form-state'; import {isFormPageEnabled, PageSlugControl} from './page-slug'; +import {cleanForSlug} from '@wordpress/url'; +/** + * @unreleased dispatch page slug from form title on initial publish. + */ const FormSummarySettings = () => { const { - settings: {formTitle}, + settings: {formTitle, pageSlug, formStatus}, } = useFormState(); const dispatch = useFormStateDispatch(); + const isPublished = 'publish' === formStatus; + const isTitleSlug = !isPublished && cleanForSlug(formTitle) === pageSlug; return ( @@ -16,12 +22,15 @@ const FormSummarySettings = () => { dispatch(setFormSettings({formTitle}))} + onChange={(formTitle) => { + !isPublished && dispatch(setFormSettings({pageSlug: cleanForSlug(formTitle)})); + dispatch(setFormSettings({formTitle})); + }} /> {!!isFormPageEnabled && ( - + )} diff --git a/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/page-slug.js b/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/page-slug.js index 6a9bd12b81..a6dacd3973 100644 --- a/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/page-slug.js +++ b/src/FormBuilder/resources/js/form-builder/src/settings/form-summary/page-slug.js @@ -1,81 +1,85 @@ import {Button, Dropdown, ExternalLink, TextControl} from '@wordpress/components'; import {close, Icon} from '@wordpress/icons'; -import {setFormSettings, useFormState, useFormStateDispatch} from '@givewp/form-builder/stores/form-state'; +import {setFormSettings, useFormStateDispatch} from '@givewp/form-builder/stores/form-state'; import {getWindowData} from '@givewp/form-builder/common'; import {cleanForSlug, safeDecodeURIComponent} from '@wordpress/url'; -import {useCallback, useState} from '@wordpress/element'; +import {__} from '@wordpress/i18n'; + +import {useCallback, useEffect, useState} from 'react'; const { formPage: {isEnabled, permalink, rewriteSlug}, } = getWindowData(); /** + * @unreleased pass page slug from parent component to support form title as initial slug. * @since 3.0.0 * @see https://github.com/WordPress/gutenberg/blob/a8c5605f5dd077a601aefce6f58409f54d7d4447/packages/editor/src/components/post-slug/index.js */ -const PageSlugControl = () => { - const { - settings: {pageSlug}, - } = useFormState(); +const PageSlugControl = ({pageSlug}) => { const dispatch = useFormStateDispatch(); - const [editedSlug, setEditedSlug] = useState(safeDecodeURIComponent(pageSlug)); + const [editedSlug, setEditedSlug] = useState(safeDecodeURIComponent(pageSlug)); + + useEffect(() => { + setEditedSlug(safeDecodeURIComponent(pageSlug)); + }, [pageSlug]); - const updateSlug = useCallback(() => { - const cleanEditedSlug = cleanForSlug(editedSlug); - setEditedSlug(cleanEditedSlug); + const updateSlug = useCallback(() => { + const cleanEditedSlug = cleanForSlug(editedSlug); + setEditedSlug(cleanEditedSlug); - if (cleanEditedSlug !== pageSlug) { - dispatch(setFormSettings({pageSlug: cleanEditedSlug})); - } - }, [pageSlug, editedSlug, dispatch]); + if (cleanEditedSlug !== pageSlug) { + dispatch(setFormSettings({pageSlug: cleanEditedSlug})); + } + }, [pageSlug, editedSlug, dispatch]); - return ( - !!isEnabled && ( - ( - null} - onClick={onToggle} - aria-expanded={isOpen} - /> - )} - renderContent={({onClose}) => ( -
-
- {'URL'} - -
- { - setEditedSlug(newPageSlug); - }} - help={'The last part of the URL.'} - onBlur={() => updateSlug()} - /> -
- View Page -
- - {sprintf('%s/%s', rewriteSlug, editedSlug)} - -
- )} - /> - ) - ); + return ( + !!isEnabled && ( + ( + null} + onClick={onToggle} + aria-expanded={isOpen} + /> + )} + renderContent={({onClose}) => ( +
+
+ {__('URL', 'give')} + +
+ { + setEditedSlug(newPageSlug); + }} + help={__('The last part of the URL.', 'give')} + onBlur={() => updateSlug()} + /> +
+ View Page +
+ + {sprintf('%s/%s', rewriteSlug, editedSlug)} + +
+ )} + /> + ) + ); }; export default PageSlugControl; diff --git a/src/FormBuilder/resources/js/form-builder/src/styles/_block-editor.scss b/src/FormBuilder/resources/js/form-builder/src/styles/_block-editor.scss index 1e959c3eed..6134d4d67c 100644 --- a/src/FormBuilder/resources/js/form-builder/src/styles/_block-editor.scss +++ b/src/FormBuilder/resources/js/form-builder/src/styles/_block-editor.scss @@ -214,4 +214,6 @@ background-color: white; } - +.givewp-support-link.components-external-link > svg { + display: none; /* Hide included icon, in favor of menu item icon. */ +}