From a614fbe2a4931bb7c456daa88aec1dbbe4a4f676 Mon Sep 17 00:00:00 2001 From: Kirtan Gajjar <8456197+kirtangajjar@users.noreply.github.com> Date: Sun, 4 Aug 2024 10:25:39 +0530 Subject: [PATCH 1/4] Update push ajax endpoint --- assets/js/push.js | 2 +- includes/push-ui.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/push.js b/assets/js/push.js index 4846c8185..ecec1b291 100755 --- a/assets/js/push.js +++ b/assets/js/push.js @@ -356,7 +356,7 @@ jQuery( window ).on( 'load', () => { distributorPushWrapper.classList.add( 'loaded' ); const data = { - action: 'dt_load_connections', + action: 'dt_load_connections_push', loadConnectionsNonce: dt.loadConnectionsNonce, postId: dt.postId, }; diff --git a/includes/push-ui.php b/includes/push-ui.php index db071c1a4..9d741f11c 100644 --- a/includes/push-ui.php +++ b/includes/push-ui.php @@ -23,7 +23,7 @@ function() { add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_scripts' ); add_filter( 'amp_dev_mode_element_xpaths', __NAMESPACE__ . '\add_element_xpaths' ); add_filter( 'script_loader_tag', __NAMESPACE__ . '\add_dev_mode_to_assets', 10, 2 ); - add_action( 'wp_ajax_dt_load_connections', __NAMESPACE__ . '\get_connections' ); + add_action( 'wp_ajax_dt_load_connections_push', __NAMESPACE__ . '\get_connections' ); add_action( 'wp_ajax_dt_push', __NAMESPACE__ . '\ajax_push' ); add_action( 'admin_bar_menu', __NAMESPACE__ . '\menu_button', 999 ); add_action( 'wp_footer', __NAMESPACE__ . '\menu_content', 10, 1 ); From 8e2f4a8b04414d74fcb4258464c9ccae43c33317 Mon Sep 17 00:00:00 2001 From: Kirtan Gajjar <8456197+kirtangajjar@users.noreply.github.com> Date: Sun, 4 Aug 2024 10:27:05 +0530 Subject: [PATCH 2/4] Add search functionality in pull ui screen --- assets/css/admin-pull-table.scss | 71 +++++++++++++++++ assets/js/admin-pull.js | 130 +++++++++++++++++++++++++++---- includes/pull-ui.php | 114 ++++++++++++++++----------- 3 files changed, 256 insertions(+), 59 deletions(-) diff --git a/assets/css/admin-pull-table.scss b/assets/css/admin-pull-table.scss index a5d37a417..32786cb55 100644 --- a/assets/css/admin-pull-table.scss +++ b/assets/css/admin-pull-table.scss @@ -32,3 +32,74 @@ list-style: disc; padding-left: 20px; } + +.searchable-select { + position: relative; + display: inline-block; + width: 300px; + vertical-align: top; +} + +.searchable-select__input-container { + display: flex; + align-items: center; + box-shadow: 0 0 0 transparent; + border-radius: 4px; + border: 1px solid #8c8f94; + background-color: #fff; + color: #2c3338; + cursor: text; + overflow: hidden; +} + +.searchable-select__input { + flex-grow: 1; + border: none; + padding: 8px; + outline: none; + border: none !important; + width: 100%; + + &:focus { + outline: none; + border: none !important; + box-shadow: none !important; + } +} + +.searchable-select__icon { + padding: 8px; + background-color: #f0f0f0; + cursor: pointer; +} + +.searchable-select__input-container:focus-within { + border-color: #007bff; +} + +.searchable-select__dropdown { + position: absolute; + top: 100%; + left: 0; + right: 0; + border: 1px solid #ccc; + border-top: none; + max-height: 200px; + overflow-y: auto; + background-color: white; + display: none; + font-size: small; +} + +.searchable-select__item { + padding: 8px; + cursor: pointer; +} + +.searchable-select__item:hover { + background-color: #f0f0f0; +} + +.searchable-select__item.selected { + background-color: #e0e0e0; +} diff --git a/assets/js/admin-pull.js b/assets/js/admin-pull.js index 3de9f9255..8cbb657c7 100755 --- a/assets/js/admin-pull.js +++ b/assets/js/admin-pull.js @@ -3,10 +3,13 @@ import '../css/admin-pull-table.scss'; import jQuery from 'jquery'; import { addQueryArgs } from '@wordpress/url'; import { __ } from '@wordpress/i18n'; +import _ from 'underscore'; const { document } = window; -const chooseConnection = document.getElementById( 'pull_connections' ); +const chooseConnection = document.getElementsByClassName( + 'searchable-select__input' +)[ 0 ]; const choosePostType = document.getElementById( 'pull_post_type' ); const choosePostTypeBtn = document.getElementById( 'pull_post_type_submit' ); const searchField = document.getElementById( 'post-search-input' ); @@ -15,15 +18,6 @@ const form = document.getElementById( 'posts-filter' ); const asDraftCheckboxes = document.querySelectorAll( '[name=dt_as_draft]' ); const pullLinks = document.querySelectorAll( '.distributor_page_pull .pull a' ); -jQuery( chooseConnection ).on( 'change', ( event ) => { - document.location = - event.currentTarget.options[ - event.currentTarget.selectedIndex - ].getAttribute( 'data-pull-url' ); - - document.body.className += ' ' + 'dt-loading'; -} ); - if ( chooseConnection && choosePostType && form ) { if ( choosePostTypeBtn ) { jQuery( choosePostTypeBtn ).on( 'click', ( event ) => { @@ -84,10 +78,7 @@ if ( chooseConnection && choosePostType && form ) { const getURL = () => { const postType = choosePostType.options[ choosePostType.selectedIndex ].value; - const baseURL = - chooseConnection.options[ chooseConnection.selectedIndex ].getAttribute( - 'data-pull-url' - ); + const baseURL = chooseConnection.getAttribute( 'data-pull-url' ); let status = 'new'; if ( -1 < ` ${ form.className } `.indexOf( ' status-skipped ' ) ) { @@ -98,3 +89,114 @@ const getURL = () => { return `${ baseURL }&pull_post_type=${ postType }&status=${ status }`; }; + +document.addEventListener( 'DOMContentLoaded', async function () { + const container = document.querySelector( '.searchable-select' ); + const inputContainer = container.querySelector( + '.searchable-select__input-container' + ); + const input = container.querySelector( '.searchable-select__input' ); + const icon = container.querySelector( + '.searchable-select__input-container > .dashicons-arrow-down' + ); + const dropdown = container.querySelector( '.searchable-select__dropdown' ); + + const itemss = await fetch( '/wp-admin/admin-ajax.php', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: 'action=dt_load_connections_pull', + } ) + .then( ( response ) => response.json() ) + .then( ( data ) => { + return data.data; + } ); + + function htmlDecode( inputText ) { + const doc = new DOMParser().parseFromString( inputText, 'text/html' ); + return doc.documentElement.textContent; + } + + function setInputDefault() { + const params = new URL( document.location.toString() ).searchParams; + const connection_id = params.get( 'connection_id' ); + + if ( connection_id ) { + const connection = itemss.find( + ( item ) => item.id == connection_id ); + + if ( connection ) { + input.value = connection.name; + input.setAttribute( + 'data-pull-url', + htmlDecode( connection.pull_url ) + ); + } + } + } + + setInputDefault(); + + function createDropdownItems( items ) { + dropdown.innerHTML = ''; + items.forEach( ( item ) => { + const div = document.createElement( 'div' ); + div.classList.add( 'searchable-select__item' ); + div.textContent = item.name; + div.setAttribute( 'data-url', item.url ); + + div.addEventListener( 'click', () => { + input.value = item.name; + input.setAttribute( + 'data-pull-url', + htmlDecode( item.pull_url ) + // item.pull_url + ); + document.location = getURL(); + + hideDropdown(); + } ); + dropdown.appendChild( div ); + } ); + } + + function showDropdown() { + createDropdownItems( itemss ); + dropdown.style.display = 'block'; + } + + function hideDropdown() { + dropdown.style.display = 'none'; + } + + function filterItems( searchTerm ) { + const filteredItems = itemss.filter( ( item ) => + item.toLowerCase().includes( searchTerm.toLowerCase() ) + ); + createDropdownItems( filteredItems ); + } + + inputContainer.addEventListener( 'click', function () { + input.focus(); + showDropdown(); + } ); + + icon.addEventListener( 'click', function ( event ) { + event.stopPropagation(); + input.focus(); + showDropdown(); + } ); + + input.addEventListener( 'input', function () { + filterItems( this.value ); + } ); + + input.addEventListener( 'focus', showDropdown ); + + document.addEventListener( 'click', function ( event ) { + if ( ! container.contains( event.target ) ) { + hideDropdown(); + } + } ); +} ); diff --git a/includes/pull-ui.php b/includes/pull-ui.php index 5261b3a34..d91d94a0a 100644 --- a/includes/pull-ui.php +++ b/includes/pull-ui.php @@ -21,6 +21,7 @@ function setup() { function() { add_action( 'admin_menu', __NAMESPACE__ . '\action_admin_menu' ); add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\admin_enqueue_scripts' ); + add_action( 'wp_ajax_dt_load_connections_pull', __NAMESPACE__ . '\get_connections' ); add_action( 'load-distributor_page_pull', __NAMESPACE__ . '\setup_list_table' ); add_filter( 'set-screen-option', __NAMESPACE__ . '\set_screen_option', 10, 3 ); } @@ -425,51 +426,14 @@ function dashboard() { ?> - +
+
+ + +
+
+
+ pull_post_type = ''; @@ -624,3 +588,63 @@ function output_pull_errors() { get_registered()['networkblog'] ) ) { + $sites = \Distributor\InternalConnections\NetworkSiteConnection::get_available_authorized_sites( 'pull' ); + + foreach ( $sites as $site_array ) { + $internal_connection = new \Distributor\InternalConnections\NetworkSiteConnection( $site_array['site'] ); + + $connections[] = [ + 'id' => $internal_connection->site->blog_id, + 'name' => untrailingslashit( $internal_connection->site->domain . $internal_connection->site->path ), + 'url' => untrailingslashit( preg_replace( '#(https?:\/\/|www\.)#i', '', get_site_url( $internal_connection->site->blog_id ) ) ), + 'pull_url' => esc_url( admin_url( 'admin.php?page=pull&connection_type=internal&connection_id=' . $internal_connection->site->blog_id ) ), + 'type' => 'internal', + ]; + } + } + + $external_connections = new \WP_Query( + array( + 'post_type' => 'dt_ext_connection', + 'fields' => 'ids', + 'no_found_rows' => true, + 'posts_per_page' => -1, + ) + ); + + foreach ( $external_connections->posts as $external_connection_id ) { + $external_connection_type = get_post_meta( $external_connection_id, 'dt_external_connection_type', true ); + + if ( empty( \Distributor\Connections::factory()->get_registered()[ $external_connection_type ] ) ) { + continue; + } + + $external_connection_status = get_post_meta( $external_connection_id, 'dt_external_connections', true ); + + if ( empty( $external_connection_status ) || empty( $external_connection_status['can_get'] ) ) { + continue; + } + + $external_connection = \Distributor\ExternalConnection::instantiate( $external_connection_id ); + + if ( ! is_wp_error( $external_connection ) ) { + $connections[] = [ + 'id' => $external_connection->id, + 'name' => $external_connection->name, + 'url' => $external_connection->base_url, + 'pull_url' => esc_url( admin_url( 'admin.php?page=pull&connection_type=external&connection_id=' . $external_connection->id ) ), + 'type' => 'external', + ]; + } + } + + wp_send_json_success( $connections ); +} From 6432dc27e2099463ea9efd0d89cf58b0548a5eae Mon Sep 17 00:00:00 2001 From: Kirtan Gajjar <8456197+kirtangajjar@users.noreply.github.com> Date: Sun, 4 Aug 2024 10:35:16 +0530 Subject: [PATCH 3/4] Fix linting --- assets/js/admin-pull.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/js/admin-pull.js b/assets/js/admin-pull.js index 8cbb657c7..de91e283b 100755 --- a/assets/js/admin-pull.js +++ b/assets/js/admin-pull.js @@ -124,7 +124,8 @@ document.addEventListener( 'DOMContentLoaded', async function () { if ( connection_id ) { const connection = itemss.find( - ( item ) => item.id == connection_id ); + ( item ) => item.id === connection_id + ); if ( connection ) { input.value = connection.name; From d08608f1efa85c49ad5b6be73d5d6d0e6d486883 Mon Sep 17 00:00:00 2001 From: Kirtan Gajjar <8456197+kirtangajjar@users.noreply.github.com> Date: Sun, 4 Aug 2024 10:40:19 +0530 Subject: [PATCH 4/4] Fix other linting issues --- assets/js/admin-pull.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assets/js/admin-pull.js b/assets/js/admin-pull.js index de91e283b..53708e905 100755 --- a/assets/js/admin-pull.js +++ b/assets/js/admin-pull.js @@ -3,7 +3,6 @@ import '../css/admin-pull-table.scss'; import jQuery from 'jquery'; import { addQueryArgs } from '@wordpress/url'; import { __ } from '@wordpress/i18n'; -import _ from 'underscore'; const { document } = window; @@ -114,7 +113,7 @@ document.addEventListener( 'DOMContentLoaded', async function () { } ); function htmlDecode( inputText ) { - const doc = new DOMParser().parseFromString( inputText, 'text/html' ); + const doc = new DOMParser().parseFromString( inputText, 'text/html' ); // eslint-disable-line no-undef return doc.documentElement.textContent; }