Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Default form tooltip #7590

Merged
merged 35 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c77e1a9
feature: add archive notification component
alaca Oct 25, 2024
205493e
feature: add orderByRaw method
alaca Oct 25, 2024
1115824
feature: add default form notification
alaca Oct 25, 2024
1351150
feature: add custom notification type
alaca Oct 25, 2024
0505795
feature: allow arbitrary notification type
alaca Oct 25, 2024
695659f
feature: add custom notice action
alaca Oct 25, 2024
73cbadc
refactor: prevent duplicate notifications
alaca Oct 25, 2024
20f4903
feature: add default form attr
alaca Oct 25, 2024
50811aa
feature: add notification placeholder for default form tooltip
alaca Oct 25, 2024
cde2052
feature: add showDefaultFormTooltip flag
alaca Oct 25, 2024
9caf392
refactor: organize notification actions
alaca Oct 25, 2024
c8b4acd
refactor: remove default sort option
alaca Oct 25, 2024
174492d
feature: pass entire data set to filter
alaca Oct 25, 2024
c553ed8
feature: add default form notice
alaca Oct 28, 2024
a9e4fb1
refactor: extract archive notice to separate file
alaca Oct 28, 2024
09e2bd7
feature: add default form notice
alaca Oct 28, 2024
e35f72b
feature: pass arguments to the content callback function
alaca Oct 28, 2024
7eb961a
feature: add notification placeholder for default form
alaca Oct 28, 2024
f23d4fc
refactor: reorganize
alaca Oct 28, 2024
1297cf0
feature: add action url for default form notice
alaca Oct 28, 2024
733ffdf
Merge branch 'epic/campaigns' into feature/tooltip-component-GIVE-1341
kjohnson Nov 11, 2024
d5e43bd
refactor: default form tooltip notification
alaca Nov 12, 2024
de7ae65
fix: alias
alaca Nov 12, 2024
b4bd658
refactor: remove unused code
alaca Nov 12, 2024
dc269fe
refactor: add isCampaignDetailsPage check
alaca Nov 14, 2024
c9177cb
Merge branch 'refs/heads/epic/campaigns' into feature/tooltip-compone…
alaca Nov 19, 2024
1b187da
refactor: sort by default form desc
alaca Nov 20, 2024
a6e7863
fix: tests
alaca Nov 20, 2024
c3504ea
refactor: test
alaca Nov 20, 2024
91abd00
refactor: add form_id
alaca Nov 20, 2024
083f27d
refactor: remove form_id
alaca Nov 20, 2024
2b8e56b
refactor: sort direction
alaca Nov 20, 2024
8172df7
refactor: sort direction
alaca Nov 20, 2024
195190b
refactor: sort direction
alaca Nov 21, 2024
9fa2985
Merge branch 'refs/heads/epic/campaigns' into feature/tooltip-compone…
alaca Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {__} from '@wordpress/i18n';
import {TriangleIcon} from '@givewp/campaigns/admin/components/Icons';

export default ({handleClick}) => (
<>
<TriangleIcon />
<span>
{__("Your campaign is currently archived. You can view the campaign details but won't be able to make any changes until it's moved out of archive.", 'give')}
</span>
<strong>
<a href="#" onClick={() => handleClick()}>
{__('Move to draft', 'give')}
</a>
</strong>
</>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {__} from '@wordpress/i18n';
import {CloseIcon} from "@givewp/campaigns/admin/components/Icons";

import styles from './styles.module.scss'

export default ({handleClick}) => (
<div className={styles.tooltip}>
<div className={styles.close} onClick={handleClick}>
<CloseIcon />
</div>
<h3>
{__('Default campaign form', 'give')}
</h3>
<div className={styles.content}>
{__('The default form will always appear at the top of this list. Your campaign page and blocks will collect donations through this form by default. You can change it at any time.', 'give')}
</div>
</div>
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.tooltip {
position: absolute;
top: 420px; // hacky but I can't think of any other way as the entire list table is wrapped in an element that has the overflow property set
left: 100px;
z-index: 9;
width: 377px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: 16px;
padding: 16px 24px 24px;
border-radius: 8px;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
border: solid 2px #6b7280;
background-color: #fff;

.close {
cursor: pointer;
position: absolute;
right: 13px;
top: 13px;
}

h3 {
padding: 0;
margin: 0;
font-size: 16px;
color: #060c1a;
}

.content {
font-size: 14px;
color: #1f2937;
font-weight: normal;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {Spinner} from '@wordpress/components';
import Tabs from './Tabs';
import ArchiveCampaignDialog from './Components/ArchiveCampaignDialog';
import {ArrowReverse, BreadcrumbSeparatorIcon, DotsIcons, TrashIcon, TriangleIcon, ViewIcon} from '../Icons';
import ArchivedCampaignNotice from './Components/Notices/ArchivedCampaignNotice';
import NotificationPlaceholder from '../Notifications';
import cx from 'classnames';

Expand Down Expand Up @@ -110,28 +111,8 @@ export default function CampaignsDetailsPage({campaignId}) {
dispatch.addNotice({
id: 'update-archive-notice',
type: 'warning',
content: () => (
<>
<TriangleIcon />
<span>
{__(
"Your campaign is currently archived. You can view the campaign details but won't be able to make any changes until it's moved out of archive.",
'give'
)}
</span>
<strong>
<a
href="#"
onClick={() => {
updateStatus('draft');
dispatch.dismissNotification('update-archive-notice');
}}
>
{__('Move to draft', 'give')}
</a>
</strong>
</>
),
onDismiss: () => updateStatus('draft'),
content: (onDismiss: Function) => <ArchivedCampaignNotice handleClick={onDismiss} />
});
}, [campaign?.status]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import {CloseIcon} from '../Icons';

import styles from './Notices.module.scss';

const Snackbar = ({notification, onDismiss}: {notification: Notification, onDismiss: () => void}) => {
const Snackbar = ({notification, onDismiss}: { notification: Notification, onDismiss: () => void }) => {
return (

<div
className={cx(styles.snackbar, styles[`type-${notification.type}-snackbar`])}
>
<div>
{typeof notification.content === 'function' ? notification.content() : notification.content}
{typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content}
</div>
{notification.isDismissible && (
<a href="#" onClick={onDismiss}>
Expand All @@ -25,14 +25,14 @@ const Snackbar = ({notification, onDismiss}: {notification: Notification, onDism
);
};

const Notice = ({notification, onDismiss}: {notification: Notification, onDismiss: () => void}) => {
const Notice = ({notification, onDismiss}: { notification: Notification, onDismiss: () => void }) => {
return (

<div
className={cx(styles.notice, styles[`type-${notification.type}`])}
>
<div className={styles.notificationContent}>
{typeof notification.content === 'function' ? notification.content() : notification.content}
{typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content}
</div>
{notification.isDismissible && (
<a href="#" onClick={onDismiss}>
Expand Down Expand Up @@ -63,17 +63,12 @@ export default ({notification}) => {
};


return notification.notificationType === 'snackbar'
? (
<Snackbar
notification={notification}
onDismiss={onDismiss}
/>
) : (
<Notice
notification={notification}
onDismiss={onDismiss}
/>
);

switch (notification.notificationType) {
case 'snackbar':
return <Snackbar notification={notification} onDismiss={onDismiss} />
case 'notice':
return <Notice notification={notification} onDismiss={onDismiss} />
default:
return null;
}
}
5 changes: 4 additions & 1 deletion src/Campaigns/resources/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export const store = createReduxStore('givewp/campaign-notifications', {
reducer(state = [], action) {
switch (action.type) {
case 'ADD_NOTIFICATION':
state.push(action.notification);
const notificationExist = state.filter((notification: { id: string }) => notification.id === action.notification.id);
if (!notificationExist.length) {
state.push(action.notification);
}
return state;

case 'DISMISS_NOTIFICATION':
Expand Down
8 changes: 8 additions & 0 deletions src/DonationForms/V2/DonationFormsAdminPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ class DonationFormsAdminPage
*/
protected $migrationApiRoot;

/**
* @var string
*/
protected $defaultFormActionUrl;

public function __construct()
{
$this->apiRoot = esc_url_raw(rest_url('give-api/v2/admin/forms'));
$this->bannerActionUrl = admin_url('admin-ajax.php?action=givewp_show_onboarding_banner');
$this->tooltipActionUrl = admin_url('admin-ajax.php?action=givewp_show_upgraded_tooltip');
$this->defaultFormActionUrl = admin_url('admin-ajax.php?action=givewp_show_default_form_tooltip');
$this->migrationApiRoot = esc_url_raw(rest_url('give-api/v2/admin/forms/migrate'));
$this->apiNonce = wp_create_nonce('wp_rest');
$this->adminUrl = admin_url();
Expand Down Expand Up @@ -99,13 +105,15 @@ public function loadScripts()
'apiRoot' => $this->apiRoot,
'bannerActionUrl' => $this->bannerActionUrl,
'tooltipActionUrl' => $this->tooltipActionUrl,
'defaultFormActionUrl' => $this->defaultFormActionUrl,
'apiNonce' => $this->apiNonce,
'preload' => $this->preloadDonationForms(),
'authors' => $this->getAuthors(),
'table' => give(DonationFormsListTable::class)->toArray(),
'adminUrl' => $this->adminUrl,
'pluginUrl' => GIVE_PLUGIN_URL,
'showUpgradedTooltip' => !get_user_meta(get_current_user_id(), 'givewp-show-upgraded-tooltip', true),
'showDefaultFormTooltip' => !get_user_meta(get_current_user_id(), 'givewp-show-default-form-tooltip', true),
'supportedAddons' => $this->getSupportedAddons(),
'supportedGateways' => $this->getSupportedGateways(),
'isOptionBasedFormEditorEnabled' => OptionBasedFormEditor::isEnabled(),
Expand Down
13 changes: 12 additions & 1 deletion src/DonationForms/V2/Endpoints/ListDonationForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class ListDonationForms extends Endpoint
*/
protected $listTable;

/**
* @var int
*/
protected $defaultForm;

/**
* @unreleased Add campaignId parameter
* @inheritDoc
Expand Down Expand Up @@ -125,6 +130,9 @@ public function handleRequest(WP_REST_Request $request): WP_REST_Response
{
$this->request = $request;
$this->listTable = give(DonationFormsListTable::class);
$this->defaultForm = $this->request->get_param('campaignId')
? Campaign::find((int)$this->request->get_param('campaignId'))->defaultForm()->id
: 0;

$forms = $this->getForms();
$totalForms = $this->getTotalFormsCount();
Expand Down Expand Up @@ -154,6 +162,7 @@ public function handleRequest(WP_REST_Request $request): WP_REST_Response
'totalItems' => $totalForms,
'totalPages' => $totalPages,
'trash' => defined('EMPTY_TRASH_DAYS') && EMPTY_TRASH_DAYS > 0,
'defaultForm' => $this->defaultForm
]
);
}
Expand All @@ -169,11 +178,13 @@ public function getForms(): array
$page = $this->request->get_param('page');
$perPage = $this->request->get_param('perPage');
$sortColumns = $this->listTable->getSortColumnById($this->request->get_param('sortColumn') ?: 'id');
$sortDirection = $this->request->get_param('sortDirection') ?: 'desc';

$query = give()->donationForms->prepareQuery();
$query = $this->getWhereConditions($query);

$query->orderByRaw('FIELD(ID, %d) DESC', $this->defaultForm);

$sortDirection = $this->request->get_param('sortDirection') ?: 'asc';
foreach ($sortColumns as $sortColumn) {
$query->orderBy($sortColumn, $sortDirection);
}
Expand Down
17 changes: 11 additions & 6 deletions src/DonationForms/V2/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@ public function boot()
Hooks::addAction('submitpost_box', DonationFormsAdminPage::class, 'renderMigrationGuideBox');
Hooks::addAction('admin_enqueue_scripts', DonationFormsAdminPage::class, 'loadMigrationScripts');

add_action('wp_ajax_givewp_show_onboarding_banner', static function () {
add_user_meta(get_current_user_id(), 'givewp-show-onboarding-banner', time(), true);
});
// Dismiss notices
$noticeActions = [
'givewp_show_onboarding_banner' => 'show-onboarding-banner',
'givewp_show_upgraded_tooltip' => 'show-upgraded-tooltip',
'givewp_show_default_form_tooltip' => 'show-default-form-tooltip',
];

add_action('wp_ajax_givewp_show_upgraded_tooltip', static function () {
add_user_meta(get_current_user_id(), 'givewp-show-upgraded-tooltip', time(), true);
});
foreach ($noticeActions as $action => $metaKey) {
add_action("wp_ajax_{$action}", static function () use ($metaKey) {
add_user_meta(get_current_user_id(), "givewp-{$metaKey}", time(), true);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import InterweaveSSR from '@givewp/components/ListTable/InterweaveSSR';
import BlankSlate from '@givewp/components/ListTable/BlankSlate';
import {CubeIcon} from '@givewp/components/AdminUI/Icons';
import AddCampaignFormModal from './AddCampaignFormModal';
import DefaultFormNotice
from '@givewp/campaigns/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice';
import apiFetch from "@wordpress/api-fetch";

declare global {
interface Window {
Expand All @@ -19,15 +22,17 @@ declare global {
bannerActionUrl: string;
tooltipActionUrl: string;
migrationApiRoot: string;
defaultFormActionUrl: string;
apiRoot: string;
authors: Array<{id: string | number; name: string}>;
table: {columns: Array<object>};
authors: Array<{ id: string | number; name: string }>;
table: { columns: Array<object> };
pluginUrl: string;
showUpgradedTooltip: boolean;
isMigrated: boolean;
supportedAddons: Array<string>;
supportedGateways: Array<string>;
isOptionBasedFormEditorEnabled: boolean;
showDefaultFormTooltip: boolean;
campaignUrl: string;
};

Expand Down Expand Up @@ -68,8 +73,7 @@ const donationStatus = [

const urlParams = new URLSearchParams(window.location.search);

const isCampaignDetailsPage =
urlParams.get('id') && urlParams.get('page') && 'give-campaigns' === urlParams.get('page');
const isCampaignDetailsPage = urlParams.get('id') && 'give-campaigns' === urlParams.get('page');
const campaignId = urlParams.get('id');

const donationFormsFilters: Array<FilterConfig> = [
Expand Down Expand Up @@ -107,19 +111,21 @@ const columnFilters: Array<ColumnFilterConfig> = [
{
column: 'title',
filter: (item) => {
if (item?.v3form) {
return (
<div className={styles.migratedForm}>
<div className={styles.tooltipContainer}>
<CubeIcon />
<div className={styles.tooltip}>{__('Uses the Visual Form Builder', 'give')}</div>
return (
<>
{item?.v3form ? (
<div className={styles.migratedForm}>
<div className={styles.tooltipContainer}>
<CubeIcon />
<div className={styles.tooltip}>{__('Uses the Visual Form Builder', 'give')}</div>
</div>
<Interweave attributes={{className: 'interweave'}} content={item?.title} />
</div>
) : (
<Interweave attributes={{className: 'interweave'}} content={item?.title} />
</div>
);
}

return <Interweave attributes={{className: 'interweave'}} content={item?.title} />;
)}
</>
);
},
},
{
Expand Down Expand Up @@ -265,8 +271,23 @@ const ListTableBlankSlate = (
export default function DonationFormsListTable() {
const [state, setState] = useState<OnboardingStateProps>({
showFeatureNoticeDialog: false,
showDefaultFormTooltip: window.GiveDonationForms.showDefaultFormTooltip,
});

const handleDefaultFormTooltipDismiss = () => {
apiFetch({
url: window.GiveDonationForms.defaultFormActionUrl,
method: 'POST',
}).then(() => {
setState((prevState) => {
return {
...prevState,
showDefaultFormTooltip: false
}
});
})
}

const [isOpen, setOpen] = useState<boolean>(false);
const openModal = () => setOpen(true);
const closeModal = () => setOpen(false);
Expand Down Expand Up @@ -330,6 +351,9 @@ export default function DonationFormsListTable() {
</a>
</>
)}
{state.showDefaultFormTooltip && isCampaignDetailsPage && (
<DefaultFormNotice handleClick={handleDefaultFormTooltipDismiss} />
)}
</ListTablePage>
</OnboardingContext.Provider>
);
Expand Down
Loading
Loading