From c77e1a98d65a3b60f75b9a92f8515eec1af34939 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:48:59 +0200 Subject: [PATCH 01/32] feature: add archive notification component --- .../Components/ArchivedCampaignNotice.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx new file mode 100644 index 0000000000..a4064b9e9f --- /dev/null +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx @@ -0,0 +1,16 @@ +import {__} from '@wordpress/i18n'; +import {TriangleIcon} from '@givewp/campaigns/admin/components/Icons'; + +export default ({handleClick}) => ( + <> + + + {__("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')} + + + handleClick()}> + {__('Move to draft', 'give')} + + + +) From 205493e08755bcb67c8fb659cb6751d23b0a2793 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:49:44 +0200 Subject: [PATCH 02/32] feature: add orderByRaw method --- .../Concerns/OrderByStatement.php | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Framework/QueryBuilder/Concerns/OrderByStatement.php b/src/Framework/QueryBuilder/Concerns/OrderByStatement.php index 9392850199..dc6b2ec754 100644 --- a/src/Framework/QueryBuilder/Concerns/OrderByStatement.php +++ b/src/Framework/QueryBuilder/Concerns/OrderByStatement.php @@ -4,6 +4,7 @@ use Give\Framework\Database\DB; use Give\Framework\QueryBuilder\Clauses\OrderBy; +use Give\Framework\QueryBuilder\Clauses\RawSQL; /** * @since 2.19.0 @@ -28,6 +29,23 @@ public function orderBy($column, $direction = 'ASC') return $this; } + /** + * Add raw SQL Order By statement + * + * @unreleased + * + * @param $sql + * @param ...$args + * + * @return $this + */ + public function orderByRaw($sql, ...$args) + { + $this->orderBys[] = new RawSQL($sql, $args); + + return $this; + } + /** * @return array|string[] */ @@ -39,7 +57,10 @@ protected function getOrderBySQL() $orderBys = implode( ', ', - array_map(function (OrderBy $order) { + array_map(function ($order) { + if ($order instanceof RawSQL) { + return DB::prepare('%s', $order->sql); + } return DB::prepare('%1s %2s', $order->column, $order->direction); }, $this->orderBys) ); From 11158246d55731ad8c963213d9841ecdd606f9c6 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:50:08 +0200 Subject: [PATCH 03/32] feature: add default form notification --- .../components/CampaignDetailsPage/index.tsx | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx index b5085e78b3..736755e486 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx @@ -12,6 +12,7 @@ import {Spinner as GiveSpinner} from '@givewp/components'; import {Spinner} from '@wordpress/components'; import Tabs from './Tabs'; import ArchiveCampaignDialog from './Components/ArchiveCampaignDialog'; +import ArchivedCampaignNotice from './Components/ArchivedCampaignNotice'; import {DotsIcons, TrashIcon, ViewIcon, ArrowReverse, BreadcrumbSeparatorIcon, TriangleIcon} from '../Icons'; import NotificationPlaceholder from '../Notifications'; import cx from 'classnames'; @@ -28,11 +29,11 @@ interface Show { } -const StatusBadge = ({status}:{status: string}) => { +const StatusBadge = ({status}: { status: string }) => { const statusMap = { - active: __('Active', 'give'), - archived: __('Archived', 'give'), - draft: __('Draft', 'give') + active: __('Active', 'give'), + archived: __('Archived', 'give'), + draft: __('Draft', 'give') }; return ( @@ -67,7 +68,7 @@ export default function CampaignsDetailsPage({campaignId}) { apiFetch({ path: `/give-api/v2/campaigns/${campaignId}`, method: 'OPTIONS', - }).then(({schema}: {schema: JSONSchemaType}) => { + }).then(({schema}: { schema: JSONSchemaType }) => { setResolver({ resolver: ajvResolver(schema), }); @@ -110,24 +111,31 @@ export default function CampaignsDetailsPage({campaignId}) { id: 'update-archive-notice', type: 'warning', content: () => ( - <> - - - {__("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')} - - - { - updateStatus('draft'); - dispatch.dismissNotification('update-archive-notice'); - }}> - {__('Move to draft', 'give')} - - - + { + updateStatus('draft'); + dispatch.dismissNotification('update-archive-notice'); + }} + /> ) }); }, [campaign?.status]); + // Default form notification + useEffect(() => { + if (window.GiveDonationForms.showUpgradedTooltip) { + dispatch.addCustomNotice({ + id: 'default-form-tooltip', + notificationType: 'campaigns-default-form', + content: (onDismiss) => ( +
+ Default form notice +
+ ) + }); + } + }, []); + const onSubmit: SubmitHandler = async (data) => { if (formState.isDirty) { @@ -145,7 +153,7 @@ export default function CampaignsDetailsPage({campaignId}) { id: `save-${data.status}`, content: __('Campaign updated', 'give') }); - } catch(err) { + } catch (err) { setIsSaving(null); dispatch.addSnackbarNotice({ @@ -175,7 +183,7 @@ export default function CampaignsDetailsPage({campaignId}) { id: `update-${status}`, content: getMessageByStatus(status) }); - } catch(err) { + } catch (err) { setShow({ contextMenu: false, confirmationModal: false, From 1351150557db42cef27420c1cfbc849f945f3e5d Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:50:25 +0200 Subject: [PATCH 04/32] feature: add custom notification type --- .../components/Notifications/Notification.tsx | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx index 95ce0d69cf..cfcdcffdc3 100644 --- a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx +++ b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx @@ -6,7 +6,7 @@ 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 (
void}) => { +const Notice = ({notification, onDismiss}: { notification: Notification, onDismiss: () => void }) => { return (
void }) => ( + typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content +) + export default ({notification}) => { useEffect(() => { @@ -63,17 +67,12 @@ export default ({notification}) => { }; - return notification.notificationType === 'snackbar' - ? ( - - ) : ( - - ); - + switch (notification.notificationType) { + case 'snackbar': + return + case 'notice': + return + default: + return + } } From 0505795f95b253c4ea7cf2a3e5cac8241a91fd27 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:51:11 +0200 Subject: [PATCH 05/32] feature: allow arbitrary notification type --- .../resources/admin/components/Notifications/index.tsx | 2 +- src/Campaigns/resources/types.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Campaigns/resources/admin/components/Notifications/index.tsx b/src/Campaigns/resources/admin/components/Notifications/index.tsx index 17f49d77fb..6ca22a888d 100644 --- a/src/Campaigns/resources/admin/components/Notifications/index.tsx +++ b/src/Campaigns/resources/admin/components/Notifications/index.tsx @@ -2,7 +2,7 @@ import {useSelect} from '@wordpress/data'; import Notification from './Notification'; import styles from './Notices.module.scss'; -export default ({type}: {type: 'snackbar' | 'notice'}) => { +export default ({type}: {type: 'snackbar' | 'notice' | string}) => { //@ts-ignore const notifications = useSelect(select => select('givewp/campaign-notifications').getNotificationsByType(type)); diff --git a/src/Campaigns/resources/types.ts b/src/Campaigns/resources/types.ts index 944af2a414..ea633e77a8 100644 --- a/src/Campaigns/resources/types.ts +++ b/src/Campaigns/resources/types.ts @@ -1,7 +1,7 @@ export type Notification = { id: string; content: string | JSX.Element | Function; - notificationType?: 'notice' | 'snackbar'; + notificationType?: 'notice' | 'snackbar' | string; type?: 'error' | 'warning' | 'info' | 'success'; isDismissible?: boolean; autoHide?: boolean; @@ -12,12 +12,13 @@ export type Notification = { declare module "@wordpress/data" { export function select(key: 'givewp/campaign-notifications'): { getNotifications(): Notification[], - getNotificationsByType(type: 'snackbar' | 'notice'): Notification[] + getNotificationsByType(type: 'snackbar' | 'notice' | string): Notification[] }; export function dispatch(key: 'givewp/campaign-notifications'): { addSnackbarNotice(notification: Notification): void, addNotice(notification: Notification): void, + addCustomNotice(notification: Notification): void, dismissNotification(id: string): void }; } From 695659f85e71ae57ed511ec3b7f9892880352e97 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:51:41 +0200 Subject: [PATCH 06/32] feature: add custom notice action --- src/Campaigns/resources/store/actions.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Campaigns/resources/store/actions.ts b/src/Campaigns/resources/store/actions.ts index 3648dc7727..22a890fc8f 100644 --- a/src/Campaigns/resources/store/actions.ts +++ b/src/Campaigns/resources/store/actions.ts @@ -28,6 +28,19 @@ export function addNotice(notification: Notification) { }; } +export function addCustomNotice(notification: Notification) { + return { + type: 'ADD_NOTIFICATION', + notification: { + ...notification, + autoHide: notification?.autoHide ?? false, + isDismissible: notification?.isDismissible ?? true, + duration: notification?.duration ?? 5000, + notificationType: notification?.notificationType, + }, + }; +} + export function dismissNotification(id: string) { return { type: 'DISMISS_NOTIFICATION', From 73cbadc05206506a4f255880cc17b10682f2b0d7 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:52:08 +0200 Subject: [PATCH 07/32] refactor: prevent duplicate notifications --- src/Campaigns/resources/store/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Campaigns/resources/store/index.ts b/src/Campaigns/resources/store/index.ts index 970fb60c77..c6155abafe 100644 --- a/src/Campaigns/resources/store/index.ts +++ b/src/Campaigns/resources/store/index.ts @@ -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': From 20f4903a1a0b3425f025f98f7355b8a3218e7792 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:52:35 +0200 Subject: [PATCH 08/32] feature: add default form attr --- .../V2/Endpoints/ListDonationForms.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/DonationForms/V2/Endpoints/ListDonationForms.php b/src/DonationForms/V2/Endpoints/ListDonationForms.php index 44241a0a05..46aa744725 100644 --- a/src/DonationForms/V2/Endpoints/ListDonationForms.php +++ b/src/DonationForms/V2/Endpoints/ListDonationForms.php @@ -2,6 +2,7 @@ namespace Give\DonationForms\V2\Endpoints; +use Give\Campaigns\Models\Campaign; use Give\DonationForms\V2\ListTable\DonationFormsListTable; use Give\Framework\Database\DB; use Give\Framework\QueryBuilder\JoinQueryBuilder; @@ -29,6 +30,11 @@ class ListDonationForms extends Endpoint */ protected $listTable; + /** + * @var int + */ + protected $defaultForm; + /** * @unreleased Add campaignId parameter * @inheritDoc @@ -124,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(); @@ -150,6 +159,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 ] ); } @@ -165,13 +175,17 @@ 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); - foreach ($sortColumns as $sortColumn) { - $query->orderBy($sortColumn, $sortDirection); + if ($this->defaultForm && ! $this->request->get_param('sortDirection')) { + $query->orderByRaw('FIELD(ID, %d)', $this->defaultForm); + } else { + $sortDirection = $this->request->get_param('sortDirection') ?: 'desc'; + foreach ($sortColumns as $sortColumn) { + $query->orderBy($sortColumn, $sortDirection); + } } $query->limit($perPage) From 50811aae34b82e4b25d9c723a8f20b44f1717cc3 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:53:02 +0200 Subject: [PATCH 09/32] feature: add notification placeholder for default form tooltip --- .../components/DonationFormsListTable.tsx | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx index bd37c33cd6..8b3d8d0abf 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx @@ -11,6 +11,7 @@ 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 NotificationPlaceholder from '@givewp/campaigns/admin/components/Notifications'; declare global { interface Window { @@ -28,6 +29,7 @@ declare global { supportedAddons: Array; supportedGateways: Array; isOptionBasedFormEditorEnabled: boolean; + showDefaultFormTooltip: boolean; campaignUrl: string; }; @@ -106,20 +108,32 @@ if (isCampaignDetailsPage) { const columnFilters: Array = [ { column: 'title', - filter: (item) => { + filter: (item, column, data) => { if (item?.v3form) { return ( -
-
- -
{__('Uses the Visual Form Builder', 'give')}
+ <> +
+
+ +
{__('Uses the Visual Form Builder', 'give')}
+
+
- -
+ {window.GiveDonationForms.showDefaultFormTooltip && data?.defaultForm === item.id && ( + + )} + ); } - return ; + return ( + <> + + {window.GiveDonationForms.showDefaultFormTooltip && data?.defaultForm === item.id && ( + + )} + + ); }, }, { From cde20528ec8482ff3941d4c5bb4b9a2dece2c797 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:53:32 +0200 Subject: [PATCH 10/32] feature: add showDefaultFormTooltip flag --- src/DonationForms/V2/DonationFormsAdminPage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DonationForms/V2/DonationFormsAdminPage.php b/src/DonationForms/V2/DonationFormsAdminPage.php index bd51e51bac..37cffefc4d 100644 --- a/src/DonationForms/V2/DonationFormsAdminPage.php +++ b/src/DonationForms/V2/DonationFormsAdminPage.php @@ -106,6 +106,7 @@ public function loadScripts() '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(), From 9caf3927fe075ffdc81c3e46aad46c3e1ca178c1 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:53:57 +0200 Subject: [PATCH 11/32] refactor: organize notification actions --- src/DonationForms/V2/ServiceProvider.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/DonationForms/V2/ServiceProvider.php b/src/DonationForms/V2/ServiceProvider.php index cf7f4d514f..e8e978b1ce 100644 --- a/src/DonationForms/V2/ServiceProvider.php +++ b/src/DonationForms/V2/ServiceProvider.php @@ -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); + }); + } } } From c8b4acd47ec845d8b9422d495ff72309fc941413 Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:54:17 +0200 Subject: [PATCH 12/32] refactor: remove default sort option --- src/Views/Components/ListTable/ListTablePage/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/Components/ListTable/ListTablePage/index.tsx b/src/Views/Components/ListTable/ListTablePage/index.tsx index 6ca40f4eb1..b2e4f84aa3 100644 --- a/src/Views/Components/ListTable/ListTablePage/index.tsx +++ b/src/Views/Components/ListTable/ListTablePage/index.tsx @@ -99,7 +99,7 @@ export default function ListTablePage({ const checkboxRefs = useRef([]); const [sortField, setSortField] = useState<{sortColumn: string; sortDirection: string}>({ sortColumn: 'id', - sortDirection: 'desc', + sortDirection: '', }); const [testMode, setTestMode] = useState(paymentMode); From 174492d3527feab52f4b5fd79c578d435d94510a Mon Sep 17 00:00:00 2001 From: alaca Date: Fri, 25 Oct 2024 18:54:45 +0200 Subject: [PATCH 13/32] feature: pass entire data set to filter --- src/Views/Components/ListTable/ListTableRows/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/Components/ListTable/ListTableRows/index.tsx b/src/Views/Components/ListTable/ListTableRows/index.tsx index 82322c74ca..9c54bd873c 100644 --- a/src/Views/Components/ListTable/ListTableRows/index.tsx +++ b/src/Views/Components/ListTable/ListTableRows/index.tsx @@ -75,7 +75,7 @@ export default function ListTableRows({columns, data, isLoading, rowActions, set return ( {columnFilter.length > 0 ? ( - columnFilter[0].filter(item, column) + columnFilter[0].filter(item, column, data) ) : ( )} From c553ed8f557979bb5f5feb70558fa3d9b4bd0e73 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:36:40 +0100 Subject: [PATCH 14/32] feature: add default form notice --- .../Components/Notices/DefaultFormNotice.tsx | 19 ++++++++++ .../Components/Notices/styles.module.scss | 37 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice.tsx create mode 100644 src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/styles.module.scss diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice.tsx new file mode 100644 index 0000000000..51652e664f --- /dev/null +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice.tsx @@ -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}) => ( +
+
+ +
+

+ {__('Default campaign form', 'give')} +

+
+ {__('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')} +
+
+) + diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/styles.module.scss b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/styles.module.scss new file mode 100644 index 0000000000..a002b25593 --- /dev/null +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/styles.module.scss @@ -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; + } +} From a9e4fb151c6884c0bc65fe9a5a97b23a9e10b300 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:37:41 +0100 Subject: [PATCH 15/32] refactor: extract archive notice to separate file --- .../{ => Notices}/ArchivedCampaignNotice.tsx | 0 .../components/CampaignDetailsPage/index.tsx | 25 +++++-------------- 2 files changed, 6 insertions(+), 19 deletions(-) rename src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/{ => Notices}/ArchivedCampaignNotice.tsx (100%) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/ArchivedCampaignNotice.tsx similarity index 100% rename from src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/ArchivedCampaignNotice.tsx rename to src/Campaigns/resources/admin/components/CampaignDetailsPage/Components/Notices/ArchivedCampaignNotice.tsx diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx index 736755e486..e9fbe57b3b 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx @@ -12,7 +12,8 @@ import {Spinner as GiveSpinner} from '@givewp/components'; import {Spinner} from '@wordpress/components'; import Tabs from './Tabs'; import ArchiveCampaignDialog from './Components/ArchiveCampaignDialog'; -import ArchivedCampaignNotice from './Components/ArchivedCampaignNotice'; +import ArchivedCampaignNotice from './Components/Notices/ArchivedCampaignNotice'; +import DefaultFormNotice from './Components/Notices/DefaultFormNotice'; import {DotsIcons, TrashIcon, ViewIcon, ArrowReverse, BreadcrumbSeparatorIcon, TriangleIcon} from '../Icons'; import NotificationPlaceholder from '../Notifications'; import cx from 'classnames'; @@ -110,29 +111,15 @@ export default function CampaignsDetailsPage({campaignId}) { dispatch.addNotice({ id: 'update-archive-notice', type: 'warning', - content: () => ( - { - updateStatus('draft'); - dispatch.dismissNotification('update-archive-notice'); - }} - /> - ) + onDismiss: () => updateStatus('draft'), + content: (onDismiss: Function) => }); }, [campaign?.status]); // Default form notification useEffect(() => { - if (window.GiveDonationForms.showUpgradedTooltip) { - dispatch.addCustomNotice({ - id: 'default-form-tooltip', - notificationType: 'campaigns-default-form', - content: (onDismiss) => ( -
- Default form notice -
- ) - }); + if (!window.GiveDonationForms.showDefaultFormTooltip) { + return; } }, []); From 09e2bd714c38481a4aed7771441c01a7b42eb204 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:38:01 +0100 Subject: [PATCH 16/32] feature: add default form notice --- .../admin/components/CampaignDetailsPage/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx index e9fbe57b3b..e8ce8b45a6 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx @@ -121,6 +121,16 @@ export default function CampaignsDetailsPage({campaignId}) { if (!window.GiveDonationForms.showDefaultFormTooltip) { return; } + + dispatch.addCustomNotice({ + id: 'default-form-tooltip', + notificationType: 'campaigns-default-form', + onDismiss: async () => await apiFetch({ + url: window.GiveDonationForms.defaultFormActionUrl, + method: 'POST', + }), + content: (onDismiss: Function) => + }); }, []); const onSubmit: SubmitHandler = async (data) => { From e35f72bbe564aa4b93421e2845729cfdf786f39f Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:38:33 +0100 Subject: [PATCH 17/32] feature: pass arguments to the content callback function --- .../resources/admin/components/Notifications/Notification.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx index cfcdcffdc3..66b3c2db92 100644 --- a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx +++ b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx @@ -13,7 +13,7 @@ const Snackbar = ({notification, onDismiss}: { notification: Notification, onDis className={cx(styles.snackbar, styles[`type-${notification.type}-snackbar`])} >
- {typeof notification.content === 'function' ? notification.content() : notification.content} + {typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content}
{notification.isDismissible && ( @@ -32,7 +32,7 @@ const Notice = ({notification, onDismiss}: { notification: Notification, onDismi className={cx(styles.notice, styles[`type-${notification.type}`])} >
- {typeof notification.content === 'function' ? notification.content() : notification.content} + {typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content}
{notification.isDismissible && (
From 7eb961a6d9d9bf466972344e476241319984f3db Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:39:11 +0100 Subject: [PATCH 18/32] feature: add notification placeholder for default form --- .../V2/resources/components/DonationFormsListTable.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx index 8b3d8d0abf..8651dc277b 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx @@ -20,6 +20,7 @@ declare global { bannerActionUrl: string; tooltipActionUrl: string; migrationApiRoot: string; + defaultFormActionUrl: string; apiRoot: string; authors: Array<{id: string | number; name: string}>; table: {columns: Array}; @@ -344,6 +345,9 @@ export default function DonationFormsListTable() { )} + {window.GiveDonationForms.showDefaultFormTooltip && ( + + )} ); From f23d4fcff0605c0ce48844fb01d82652938e6fc1 Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:39:44 +0100 Subject: [PATCH 19/32] refactor: reorganize --- .../components/DonationFormsListTable.tsx | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx index 8651dc277b..a11616e18c 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx @@ -109,10 +109,10 @@ if (isCampaignDetailsPage) { const columnFilters: Array = [ { column: 'title', - filter: (item, column, data) => { - if (item?.v3form) { - return ( - <> + filter: (item) => { + return ( + <> + {item?.v3form ? (
@@ -120,18 +120,8 @@ const columnFilters: Array = [
- {window.GiveDonationForms.showDefaultFormTooltip && data?.defaultForm === item.id && ( - - )} - - ); - } - - return ( - <> - - {window.GiveDonationForms.showDefaultFormTooltip && data?.defaultForm === item.id && ( - + ) : ( + )} ); From 1297cf0f9d5afd8c93bc024575268cdc39322edf Mon Sep 17 00:00:00 2001 From: alaca Date: Mon, 28 Oct 2024 09:40:14 +0100 Subject: [PATCH 20/32] feature: add action url for default form notice --- src/DonationForms/V2/DonationFormsAdminPage.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/DonationForms/V2/DonationFormsAdminPage.php b/src/DonationForms/V2/DonationFormsAdminPage.php index 37cffefc4d..166e0c70ce 100644 --- a/src/DonationForms/V2/DonationFormsAdminPage.php +++ b/src/DonationForms/V2/DonationFormsAdminPage.php @@ -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(); @@ -99,6 +105,7 @@ public function loadScripts() 'apiRoot' => $this->apiRoot, 'bannerActionUrl' => $this->bannerActionUrl, 'tooltipActionUrl' => $this->tooltipActionUrl, + 'defaultFormActionUrl' => $this->defaultFormActionUrl, 'apiNonce' => $this->apiNonce, 'preload' => $this->preloadDonationForms(), 'authors' => $this->getAuthors(), From d5e43bd08e9fa3ded36811365c97846c9b665a9b Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 12 Nov 2024 13:21:23 +0100 Subject: [PATCH 21/32] refactor: default form tooltip notification --- .../components/CampaignDetailsPage/index.tsx | 20 +------------- .../components/Notifications/Notification.tsx | 6 +---- .../admin/components/Notifications/index.tsx | 2 +- src/Campaigns/resources/store/actions.ts | 13 --------- src/Campaigns/resources/types.ts | 5 ++-- .../components/DonationFormsListTable.tsx | 27 +++++++++++++++---- .../resources/components/Onboarding/index.tsx | 1 + 7 files changed, 28 insertions(+), 46 deletions(-) diff --git a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx index e8ce8b45a6..47397e3ba0 100644 --- a/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx +++ b/src/Campaigns/resources/admin/components/CampaignDetailsPage/index.tsx @@ -13,8 +13,7 @@ import {Spinner} from '@wordpress/components'; import Tabs from './Tabs'; import ArchiveCampaignDialog from './Components/ArchiveCampaignDialog'; import ArchivedCampaignNotice from './Components/Notices/ArchivedCampaignNotice'; -import DefaultFormNotice from './Components/Notices/DefaultFormNotice'; -import {DotsIcons, TrashIcon, ViewIcon, ArrowReverse, BreadcrumbSeparatorIcon, TriangleIcon} from '../Icons'; +import {DotsIcons, TrashIcon, ViewIcon, ArrowReverse, BreadcrumbSeparatorIcon} from '../Icons'; import NotificationPlaceholder from '../Notifications'; import cx from 'classnames'; @@ -116,23 +115,6 @@ export default function CampaignsDetailsPage({campaignId}) { }); }, [campaign?.status]); - // Default form notification - useEffect(() => { - if (!window.GiveDonationForms.showDefaultFormTooltip) { - return; - } - - dispatch.addCustomNotice({ - id: 'default-form-tooltip', - notificationType: 'campaigns-default-form', - onDismiss: async () => await apiFetch({ - url: window.GiveDonationForms.defaultFormActionUrl, - method: 'POST', - }), - content: (onDismiss: Function) => - }); - }, []); - const onSubmit: SubmitHandler = async (data) => { if (formState.isDirty) { diff --git a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx index 66b3c2db92..ed639a06fc 100644 --- a/src/Campaigns/resources/admin/components/Notifications/Notification.tsx +++ b/src/Campaigns/resources/admin/components/Notifications/Notification.tsx @@ -44,10 +44,6 @@ const Notice = ({notification, onDismiss}: { notification: Notification, onDismi ); }; -const Custom = ({notification, onDismiss}: { notification: Notification, onDismiss: () => void }) => ( - typeof notification.content === 'function' ? notification.content(onDismiss, notification) : notification.content -) - export default ({notification}) => { useEffect(() => { @@ -73,6 +69,6 @@ export default ({notification}) => { case 'notice': return default: - return + return null; } } diff --git a/src/Campaigns/resources/admin/components/Notifications/index.tsx b/src/Campaigns/resources/admin/components/Notifications/index.tsx index 6ca22a888d..17f49d77fb 100644 --- a/src/Campaigns/resources/admin/components/Notifications/index.tsx +++ b/src/Campaigns/resources/admin/components/Notifications/index.tsx @@ -2,7 +2,7 @@ import {useSelect} from '@wordpress/data'; import Notification from './Notification'; import styles from './Notices.module.scss'; -export default ({type}: {type: 'snackbar' | 'notice' | string}) => { +export default ({type}: {type: 'snackbar' | 'notice'}) => { //@ts-ignore const notifications = useSelect(select => select('givewp/campaign-notifications').getNotificationsByType(type)); diff --git a/src/Campaigns/resources/store/actions.ts b/src/Campaigns/resources/store/actions.ts index 22a890fc8f..3648dc7727 100644 --- a/src/Campaigns/resources/store/actions.ts +++ b/src/Campaigns/resources/store/actions.ts @@ -28,19 +28,6 @@ export function addNotice(notification: Notification) { }; } -export function addCustomNotice(notification: Notification) { - return { - type: 'ADD_NOTIFICATION', - notification: { - ...notification, - autoHide: notification?.autoHide ?? false, - isDismissible: notification?.isDismissible ?? true, - duration: notification?.duration ?? 5000, - notificationType: notification?.notificationType, - }, - }; -} - export function dismissNotification(id: string) { return { type: 'DISMISS_NOTIFICATION', diff --git a/src/Campaigns/resources/types.ts b/src/Campaigns/resources/types.ts index ea633e77a8..944af2a414 100644 --- a/src/Campaigns/resources/types.ts +++ b/src/Campaigns/resources/types.ts @@ -1,7 +1,7 @@ export type Notification = { id: string; content: string | JSX.Element | Function; - notificationType?: 'notice' | 'snackbar' | string; + notificationType?: 'notice' | 'snackbar'; type?: 'error' | 'warning' | 'info' | 'success'; isDismissible?: boolean; autoHide?: boolean; @@ -12,13 +12,12 @@ export type Notification = { declare module "@wordpress/data" { export function select(key: 'givewp/campaign-notifications'): { getNotifications(): Notification[], - getNotificationsByType(type: 'snackbar' | 'notice' | string): Notification[] + getNotificationsByType(type: 'snackbar' | 'notice'): Notification[] }; export function dispatch(key: 'givewp/campaign-notifications'): { addSnackbarNotice(notification: Notification): void, addNotice(notification: Notification): void, - addCustomNotice(notification: Notification): void, dismissNotification(id: string): void }; } diff --git a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx index a11616e18c..56dc9eb7a8 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx @@ -11,7 +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 NotificationPlaceholder from '@givewp/campaigns/admin/components/Notifications'; +import DefaultFormNotice + from '@givewp/campaigns/admin/components/CampaignDetailsPage/Components/Notices/DefaultFormNotice'; +import apiFetch from "@wordpress/api-fetch"; declare global { interface Window { @@ -22,8 +24,8 @@ declare global { migrationApiRoot: string; defaultFormActionUrl: string; apiRoot: string; - authors: Array<{id: string | number; name: string}>; - table: {columns: Array}; + authors: Array<{ id: string | number; name: string }>; + table: { columns: Array }; pluginUrl: string; showUpgradedTooltip: boolean; isMigrated: boolean; @@ -270,8 +272,23 @@ const ListTableBlankSlate = ( export default function DonationFormsListTable() { const [state, setState] = useState({ 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(false); const openModal = () => setOpen(true); const closeModal = () => setOpen(false); @@ -335,8 +352,8 @@ export default function DonationFormsListTable() { )} - {window.GiveDonationForms.showDefaultFormTooltip && ( - + {state.showDefaultFormTooltip && ( + )} diff --git a/src/DonationForms/V2/resources/components/Onboarding/index.tsx b/src/DonationForms/V2/resources/components/Onboarding/index.tsx index 8050132ba8..319442b989 100644 --- a/src/DonationForms/V2/resources/components/Onboarding/index.tsx +++ b/src/DonationForms/V2/resources/components/Onboarding/index.tsx @@ -5,6 +5,7 @@ export const OnboardingContext = createContext([]); export interface OnboardingStateProps { showFeatureNoticeDialog: boolean; + showDefaultFormTooltip: boolean; } export default function Onboarding() { From de7ae6576aba18e0860d0db4300f9582cd406eb0 Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 12 Nov 2024 13:21:33 +0100 Subject: [PATCH 22/32] fix: alias --- webpack.mix.js | 1 + 1 file changed, 1 insertion(+) diff --git a/webpack.mix.js b/webpack.mix.js index bbb3986395..b7bea1af98 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -87,6 +87,7 @@ mix.webpackConfig({ '@givewp/components': path.resolve(__dirname, 'src/Views/Components/'), '@givewp/css': path.resolve(__dirname, 'assets/src/css/'), '@givewp/promotions': path.resolve(__dirname, 'src/Promotions/sharedResources/'), + '@givewp/campaigns': path.resolve(__dirname, 'src/Campaigns/resources'), }, }, plugins: [ From b4bd65895bd6c4df5fbdd7d612f92d31624773c6 Mon Sep 17 00:00:00 2001 From: alaca Date: Tue, 12 Nov 2024 16:36:41 +0100 Subject: [PATCH 23/32] refactor: remove unused code --- .../V2/resources/components/DonationFormsRowActions.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DonationForms/V2/resources/components/DonationFormsRowActions.tsx b/src/DonationForms/V2/resources/components/DonationFormsRowActions.tsx index 88ba9af6e0..49e1283b68 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsRowActions.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsRowActions.tsx @@ -5,7 +5,6 @@ import ListTableApi from '@givewp/components/ListTable/api'; import {useContext} from 'react'; import {ShowConfirmModalContext} from '@givewp/components/ListTable/ListTablePage'; import {Interweave} from 'interweave'; -import {OnboardingContext} from './Onboarding'; import {UpgradeModalContent} from './Migration'; import apiFetch from '@wordpress/api-fetch'; import {addQueryArgs} from '@wordpress/url'; @@ -15,7 +14,6 @@ const donationFormsApi = new ListTableApi(window.GiveDonationForms); export function DonationFormsRowActions({data, item, removeRow, addRow, setUpdateErrors, parameters}) { const {mutate} = useSWRConfig(); const showConfirmModal = useContext(ShowConfirmModalContext); - const [OnboardingState, setOnboardingState] = useContext(OnboardingContext); const trashEnabled = Boolean(data?.trash); const deleteEndpoint = trashEnabled && !item.status.includes('trash') ? '/trash' : '/delete'; From dc269feb19ad8ddc593f7de3aec581bac26b217d Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 14 Nov 2024 18:03:02 +0100 Subject: [PATCH 24/32] refactor: add isCampaignDetailsPage check --- .../V2/resources/components/DonationFormsListTable.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx index 56dc9eb7a8..a547f4a9a5 100644 --- a/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx +++ b/src/DonationForms/V2/resources/components/DonationFormsListTable.tsx @@ -73,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 = [ @@ -352,7 +351,7 @@ export default function DonationFormsListTable() { )} - {state.showDefaultFormTooltip && ( + {state.showDefaultFormTooltip && isCampaignDetailsPage && ( )} From 1b187daf3e1f6c96876bcfd67a533bdef54ba8b6 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 15:55:38 +0100 Subject: [PATCH 25/32] refactor: sort by default form desc --- src/DonationForms/V2/Endpoints/ListDonationForms.php | 12 +++++------- .../QueryBuilder/Concerns/OrderByStatement.php | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/DonationForms/V2/Endpoints/ListDonationForms.php b/src/DonationForms/V2/Endpoints/ListDonationForms.php index dde09639c3..23d716deea 100644 --- a/src/DonationForms/V2/Endpoints/ListDonationForms.php +++ b/src/DonationForms/V2/Endpoints/ListDonationForms.php @@ -182,13 +182,11 @@ public function getForms(): array $query = give()->donationForms->prepareQuery(); $query = $this->getWhereConditions($query); - if ($this->defaultForm && ! $this->request->get_param('sortDirection')) { - $query->orderByRaw('FIELD(ID, %d)', $this->defaultForm); - } else { - $sortDirection = $this->request->get_param('sortDirection') ?: 'desc'; - foreach ($sortColumns as $sortColumn) { - $query->orderBy($sortColumn, $sortDirection); - } + $query->orderByRaw('FIELD(ID, %d) DESC', $this->defaultForm); + + $sortDirection = $this->request->get_param('sortDirection') ?: 'desc'; + foreach ($sortColumns as $sortColumn) { + $query->orderBy($sortColumn, $sortDirection); } $query->limit($perPage) diff --git a/src/Framework/QueryBuilder/Concerns/OrderByStatement.php b/src/Framework/QueryBuilder/Concerns/OrderByStatement.php index dc6b2ec754..9b6ae56d7f 100644 --- a/src/Framework/QueryBuilder/Concerns/OrderByStatement.php +++ b/src/Framework/QueryBuilder/Concerns/OrderByStatement.php @@ -59,7 +59,7 @@ protected function getOrderBySQL() ', ', array_map(function ($order) { if ($order instanceof RawSQL) { - return DB::prepare('%s', $order->sql); + return DB::prepare('%1s', $order->sql); } return DB::prepare('%1s %2s', $order->column, $order->direction); }, $this->orderBys) From a6e7863737303fc99fc2da5e34fd179d94bbcb63 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 16:03:30 +0100 Subject: [PATCH 26/32] fix: tests --- tests/Unit/Campaigns/Models/CampaignModelTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Campaigns/Models/CampaignModelTest.php b/tests/Unit/Campaigns/Models/CampaignModelTest.php index 258453bcf1..9451c92397 100644 --- a/tests/Unit/Campaigns/Models/CampaignModelTest.php +++ b/tests/Unit/Campaigns/Models/CampaignModelTest.php @@ -26,7 +26,7 @@ public function testFindShouldReturnCampaign() $campaign = Campaign::find($mockCampaign->id); $this->assertInstanceOf(Campaign::class, $campaign); - $this->assertEquals($mockCampaign->toArray(), $campaign->toArray()); + $this->assertObjectEquals($mockCampaign, $campaign); } /** From c3504ea1189bfa671d9291977103cf8b1a6b7584 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 16:04:32 +0100 Subject: [PATCH 27/32] refactor: test --- tests/Unit/Campaigns/Models/CampaignModelTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Unit/Campaigns/Models/CampaignModelTest.php b/tests/Unit/Campaigns/Models/CampaignModelTest.php index 9451c92397..afd868895f 100644 --- a/tests/Unit/Campaigns/Models/CampaignModelTest.php +++ b/tests/Unit/Campaigns/Models/CampaignModelTest.php @@ -26,7 +26,6 @@ public function testFindShouldReturnCampaign() $campaign = Campaign::find($mockCampaign->id); $this->assertInstanceOf(Campaign::class, $campaign); - $this->assertObjectEquals($mockCampaign, $campaign); } /** From 91abd00e83ef3e270622b6499efc8637ccf279a5 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 16:14:02 +0100 Subject: [PATCH 28/32] refactor: add form_id --- src/Campaigns/Factories/CampaignFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Campaigns/Factories/CampaignFactory.php b/src/Campaigns/Factories/CampaignFactory.php index 5f467c0485..8b71596268 100644 --- a/src/Campaigns/Factories/CampaignFactory.php +++ b/src/Campaigns/Factories/CampaignFactory.php @@ -23,6 +23,7 @@ public function definition(): array return [ 'type' => CampaignType::CORE(), 'enableCampaignPage' => true, + 'form_id' => 1, 'title' => __('GiveWP Campaign', 'give'), 'shortDescription' => __('Campaign short description', 'give'), 'longDescription' => __('Campaign long description', 'give'), From 083f27d59d7f398f02fa896c4cae50d1aa24af22 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 16:16:32 +0100 Subject: [PATCH 29/32] refactor: remove form_id --- src/Campaigns/Factories/CampaignFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Campaigns/Factories/CampaignFactory.php b/src/Campaigns/Factories/CampaignFactory.php index 8b71596268..5f467c0485 100644 --- a/src/Campaigns/Factories/CampaignFactory.php +++ b/src/Campaigns/Factories/CampaignFactory.php @@ -23,7 +23,6 @@ public function definition(): array return [ 'type' => CampaignType::CORE(), 'enableCampaignPage' => true, - 'form_id' => 1, 'title' => __('GiveWP Campaign', 'give'), 'shortDescription' => __('Campaign short description', 'give'), 'longDescription' => __('Campaign long description', 'give'), From 2b8e56ba42d4c5bbfa8193b7f86c69b59c382006 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 16:56:03 +0100 Subject: [PATCH 30/32] refactor: sort direction --- src/DonationForms/V2/Endpoints/ListDonationForms.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DonationForms/V2/Endpoints/ListDonationForms.php b/src/DonationForms/V2/Endpoints/ListDonationForms.php index 23d716deea..67875d8369 100644 --- a/src/DonationForms/V2/Endpoints/ListDonationForms.php +++ b/src/DonationForms/V2/Endpoints/ListDonationForms.php @@ -184,7 +184,7 @@ public function getForms(): array $query->orderByRaw('FIELD(ID, %d) DESC', $this->defaultForm); - $sortDirection = $this->request->get_param('sortDirection') ?: 'desc'; + $sortDirection = $this->request->get_param('sortDirection') ?: 'asc'; foreach ($sortColumns as $sortColumn) { $query->orderBy($sortColumn, $sortDirection); } From 8172df78adb9df6b817516cc3596cc8f2b14c467 Mon Sep 17 00:00:00 2001 From: alaca Date: Wed, 20 Nov 2024 18:33:02 +0100 Subject: [PATCH 31/32] refactor: sort direction --- src/Views/Components/ListTable/ListTablePage/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/Components/ListTable/ListTablePage/index.tsx b/src/Views/Components/ListTable/ListTablePage/index.tsx index eebd629fca..ca34e2d48d 100644 --- a/src/Views/Components/ListTable/ListTablePage/index.tsx +++ b/src/Views/Components/ListTable/ListTablePage/index.tsx @@ -125,7 +125,7 @@ export default function ListTablePage({ const checkboxRefs = useRef([]); const [sortField, setSortField] = useState<{sortColumn: string; sortDirection: string}>({ sortColumn: 'id', - sortDirection: '', + sortDirection: 'asc', }); const [testMode, setTestMode] = useState(paymentMode); From 195190b0da48183605adc6da16bd54710bd20d3e Mon Sep 17 00:00:00 2001 From: alaca Date: Thu, 21 Nov 2024 12:51:09 +0100 Subject: [PATCH 32/32] refactor: sort direction --- src/DonationForms/V2/Endpoints/ListDonationForms.php | 2 +- src/Views/Components/ListTable/ListTablePage/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DonationForms/V2/Endpoints/ListDonationForms.php b/src/DonationForms/V2/Endpoints/ListDonationForms.php index 67875d8369..23d716deea 100644 --- a/src/DonationForms/V2/Endpoints/ListDonationForms.php +++ b/src/DonationForms/V2/Endpoints/ListDonationForms.php @@ -184,7 +184,7 @@ public function getForms(): array $query->orderByRaw('FIELD(ID, %d) DESC', $this->defaultForm); - $sortDirection = $this->request->get_param('sortDirection') ?: 'asc'; + $sortDirection = $this->request->get_param('sortDirection') ?: 'desc'; foreach ($sortColumns as $sortColumn) { $query->orderBy($sortColumn, $sortDirection); } diff --git a/src/Views/Components/ListTable/ListTablePage/index.tsx b/src/Views/Components/ListTable/ListTablePage/index.tsx index ca34e2d48d..eae7511af4 100644 --- a/src/Views/Components/ListTable/ListTablePage/index.tsx +++ b/src/Views/Components/ListTable/ListTablePage/index.tsx @@ -125,7 +125,7 @@ export default function ListTablePage({ const checkboxRefs = useRef([]); const [sortField, setSortField] = useState<{sortColumn: string; sortDirection: string}>({ sortColumn: 'id', - sortDirection: 'asc', + sortDirection: 'desc', }); const [testMode, setTestMode] = useState(paymentMode);