Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0c8c50a
feat: implement job registry and abstract job class for asynchronous …
Kallyan01 May 28, 2026
63765d0
feat: implement JobScheduler class for managing job lifecycle with Ac…
Kallyan01 May 29, 2026
ceb2729
refactor: remove JsonSerializable implementation from AbstractJob class
Kallyan01 May 29, 2026
7025672
feat: implement job scheduling system with ReindexJob and SyncJob for…
Kallyan01 May 29, 2026
93f5a14
feat: enhanced job management and UI for reindexing process
Kallyan01 May 29, 2026
8db0f9a
feat: add remote job status endpoint, permission checks for job manag…
Kallyan01 May 29, 2026
fccfaf0
feat: enhance job management with timestamp and error handling in Syn…
Kallyan01 Jun 1, 2026
5e96011
feat: improve job handling and error logging in ReindexJob and JobSch…
Kallyan01 Jun 1, 2026
ca7c471
feat: increase default batch size from 10 to 30 in ReindexJob and rel…
Kallyan01 Jun 1, 2026
5fc6823
feat: enhance reindexing process with improved state management and b…
Kallyan01 Jun 2, 2026
e1ad000
feat: add pagination support to job history and fixed batch counts bu…
Kallyan01 Jun 3, 2026
029ebe2
feat: update retry logic and transient key for reindex state management
Kallyan01 Jun 3, 2026
73403b3
test: add tests for reindex status endpoint and handle active reindex…
Kallyan01 Jun 4, 2026
e779c51
feat: enhance history details view with improved styling and interaction
Kallyan01 Jun 4, 2026
baae961
feat: Improved remote job retry functionality and enhance job failure…
Kallyan01 Jun 4, 2026
4fed97f
fix: split composer install to avoid Strauss token validation failure…
Copilot Jun 8, 2026
b53fc73
feat: enhance job status rendering with support for text display type
Kallyan01 Jun 4, 2026
1a7442c
test: added unit tests for job registry, reindex job, sync job, and j…
Kallyan01 Jun 5, 2026
36e493c
fix: job cancellation issues resolved
Kallyan01 Jun 9, 2026
0200407
fix: resolve SiteIndexableEntities test failures, strauss CI issue, a…
Kallyan01 Jun 10, 2026
648dc8e
refactor: moved job history to custom table and code quality improvem…
Kallyan01 Jun 15, 2026
95d3369
fix: handled wrong batch-count edgecase and added few logic improvements
Kallyan01 Jun 17, 2026
96e3435
fix: addressed the fine name feedback and improved code quality, remo…
Kallyan01 Jun 17, 2026
d3e7dbf
revert: composer and ci file
Kallyan01 Jun 17, 2026
3d26cc8
test: updated job_rest_controller tests
Kallyan01 Jun 18, 2026
0b7d744
revert: reverted changes on ci file reusable-phpstan.yml
Kallyan01 Jun 18, 2026
45f76b6
tests: fixed test case failure caused by stale data
Kallyan01 Jun 18, 2026
e4d1f09
docs: update stale docblock comments
Kallyan01 Jun 19, 2026
3b6eb29
test: resolved failing testcases
Kallyan01 Jun 19, 2026
cdb6f2d
fix: resolved import and linting issue
Kallyan01 Jun 19, 2026
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
453 changes: 0 additions & 453 deletions assets/src/components/SiteIndexableEntities.tsx

This file was deleted.

34 changes: 34 additions & 0 deletions assets/src/components/SiteIndexableEntities/BatchRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import JobStatusBadge from './JobStatusBadge';
import type { JobStatus } from './types';

interface BatchRowProps {
child: JobStatus;
idx: number;
}

const BatchRow = ( { child, idx }: BatchRowProps ) => (
<div className="onesearch-batch-row">
<span className="onesearch-batch-label">
{ sprintf(
/* translators: %d: batch number */
__( 'Batch %d', 'onesearch' ),
idx + 1
) }
</span>
<JobStatusBadge status={ child.status } size="small" />
{ child.error && (
<span className="onesearch-batch-error">
{ child.error.substring( 0, 80 ) }
</span>
) }
</div>
);

export default BatchRow;
64 changes: 64 additions & 0 deletions assets/src/components/SiteIndexableEntities/EntitySiteCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { __experimentalText as Text } from '@wordpress/components';

Check warning on line 5 in assets/src/components/SiteIndexableEntities/EntitySiteCard.tsx

View workflow job for this annotation

GitHub Actions / CSS/JS Lint / JS Lint & TypeScript

Use `Text` from `@wordpress/ui` instead
/**
* Internal dependencies
*/
import MultiSelectChips from '../MultiSelectChips';
import type { PostTypeOption } from '../SiteSearchSettings';
import { toMultiSelectOptions } from './utils';

interface EntitySiteCardProps {
siteName: string;
siteUrl: string;
options: PostTypeOption[] | undefined;
selectedValues: string[];
disabled: boolean;
isBrand?: boolean;
onChange: ( values: string[] ) => void;
}

const EntitySiteCard = ( {
siteName,
siteUrl,
options,
selectedValues,
disabled,
isBrand = false,
onChange,
}: EntitySiteCardProps ) => (
<div
className={ `onesearch-entity-site${
isBrand ? ' onesearch-entity-brand' : ''
}` }
>
<div className="onesearch-entity-site-header">
<h3 className="onesearch-entity-site-name">{ siteName }</h3>
<p className="onesearch-entity-site-url">{ siteUrl }</p>
</div>
{ ! options ? (
<Text variant="muted">
{ __(
'No entities to select. Please check site configuration',
'onesearch'
) }
</Text>
) : (
<div className="onesearch-entity-selector">
<MultiSelectChips
placeholder={ __( 'Select entities…', 'onesearch' ) }
options={ toMultiSelectOptions( options ) }
value={ selectedValues }
onChange={ onChange }
valueField="slug"
labelField="label"
disabled={ disabled }
/>
</div>
) }
</div>
);

export default EntitySiteCard;
180 changes: 180 additions & 0 deletions assets/src/components/SiteIndexableEntities/HistoryDetailsView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { Button, __experimentalText as Text } from '@wordpress/components';

Check warning on line 5 in assets/src/components/SiteIndexableEntities/HistoryDetailsView.tsx

View workflow job for this annotation

GitHub Actions / CSS/JS Lint / JS Lint & TypeScript

Use `Text` from `@wordpress/ui` instead
/**
* Internal dependencies
*/
import type { JobStatus, SiteJobState } from './types';
import BatchRow from './BatchRow';
import JobStatusBadge from './JobStatusBadge';
import { getHistorySites } from './utils';

interface HistoryDetailsViewProps {
selectedHistoryJob: JobStatus;
historyDetails: SiteJobState[];
historyDetailsLoading: boolean;
hasFailedHistoryDetails: boolean;
retryingHistoryJob: boolean;
currentSiteUrl: string;
onBack: () => void;
onRetry: () => void;
}

const HistoryDetailsView = ( {
selectedHistoryJob,
historyDetails,
historyDetailsLoading,
hasFailedHistoryDetails,
retryingHistoryJob,
currentSiteUrl,
onBack,
onRetry,
}: HistoryDetailsViewProps ) => {
const historySites = getHistorySites( selectedHistoryJob, currentSiteUrl );
const totalBatches = historySites.reduce(
( sum, site ) => sum + ( site.batch_count || 0 ),
0
);

return (
<div className="onesearch-history-details-view">
<div className="onesearch-history-details-toolbar">
<Button
variant="tertiary"
size="default"
onClick={ onBack }
className="onesearch-history-details-back"
>
‹ { __( 'Back', 'onesearch' ) }
</Button>
{ ( hasFailedHistoryDetails || retryingHistoryJob ) && (
<Button
variant="primary"
size="small"
onClick={ onRetry }
isBusy={ retryingHistoryJob }
disabled={ retryingHistoryJob }
>
{ retryingHistoryJob
? __( 'Retrying…', 'onesearch' )
: __( 'Retry Failed Batches', 'onesearch' ) }
</Button>
) }
</div>

<div className="onesearch-history-details-summary">
<div>
<span>{ __( 'Sites', 'onesearch' ) }</span>
<strong>{ historySites.length }</strong>
</div>
<div>
<span>{ __( 'Batches', 'onesearch' ) }</span>
<strong>
{ totalBatches ||
selectedHistoryJob.children_total ||
selectedHistoryJob.progress_total }
</strong>
</div>
<div>
<span>{ __( 'Status', 'onesearch' ) }</span>
<JobStatusBadge
status={ selectedHistoryJob.status }
size="small"
type="text"
/>
</div>
</div>

{ selectedHistoryJob.error && (
<div className="onesearch-job-error">
{ selectedHistoryJob.error }
</div>
) }

<div
className={ `onesearch-history-details-content${
historyDetailsLoading
? ' onesearch-history-details-content--loading'
: ''
}` }
>
{ historyDetailsLoading && (
<div className="onesearch-history-details-loading">
<span className="onesearch-reindex-spinner" />
<Text variant="muted">
{ __( 'Loading job details…', 'onesearch' ) }
</Text>
</div>
) }

{ ! historyDetailsLoading && (
<div className="onesearch-history-details-sites">
{ historyDetails.map( ( state ) => (
<div
key={ state.site.site_url }
className="onesearch-history-details-site"
>
<div className="onesearch-history-details-site-header">
<div>
<strong>
{ state.site.site_name }
</strong>
<Text variant="muted">
{ state.site.site_url }
</Text>
</div>
<div className="onesearch-history-details-site-meta">
<Text variant="muted">
{ sprintf(
/* translators: %d: batch count */
__( '%d batches', 'onesearch' ),
state.site.batch_count ||
state.children.length
) }
</Text>
{ state.reindexJob && (
<JobStatusBadge
status={
state.reindexJob.status
}
size="small"
/>
) }
</div>
</div>

{ state.children.length > 0 ? (
<div className="onesearch-batch-list">
{ state.children.map(
( child, idx ) => (
<BatchRow
key={ child.id }
child={ child }
idx={ idx }
/>
)
) }
</div>
) : (
<Text
variant="muted"
className="onesearch-history-details-empty"
>
{ __(
'No batch details available.',
'onesearch'
) }
</Text>
) }
</div>
) ) }
</div>
) }
</div>
</div>
);
};

export default HistoryDetailsView;
102 changes: 102 additions & 0 deletions assets/src/components/SiteIndexableEntities/HistoryPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Button } from '@wordpress/components';

interface HistoryPaginationProps {
historyPage: number;
historyTotalPages: number;
onPageChange: ( page: number ) => void;
}

const HistoryPagination = ( {
historyPage,
historyTotalPages,
onPageChange,
}: HistoryPaginationProps ) => {
if ( historyTotalPages <= 1 ) {
return null;
}

const pages: ( number | string )[] = [];
const delta = 2;
const last = historyTotalPages;

pages.push( 1 );

const rangeStart = Math.max( 2, historyPage - delta );
const rangeEnd = Math.min( last - 1, historyPage + delta );

if ( rangeStart > 2 ) {
pages.push( '…' );
}
for ( let i = rangeStart; i <= rangeEnd; i++ ) {
pages.push( i );
}
if ( rangeEnd < last - 1 ) {
pages.push( '…' );
}
if ( last > 1 ) {
pages.push( last );
}

const handlePageClick = ( page: number ) => {
if ( page === historyPage || page < 1 || page > last ) {
return;
}
onPageChange( page );
};

return (
<div className="onesearch-history-pagination">
<Button
variant="tertiary"
size="small"
disabled={ historyPage <= 1 }
onClick={ () => handlePageClick( historyPage - 1 ) }
aria-label={ __( 'Previous page', 'onesearch' ) }
>
</Button>
{ pages.map( ( p, idx ) => {
if ( typeof p === 'string' ) {
return (
<span
key={ `ellipsis-${ idx }` }
className="onesearch-history-pagination-ellipsis"
>
</span>
);
}
return (
<Button
key={ p }
variant={ p === historyPage ? 'primary' : 'tertiary' }
size="small"
onClick={ () => handlePageClick( p ) }
className={
p === historyPage
? 'onesearch-history-pagination-current'
: ''
}
>
{ p }
</Button>
);
} ) }
<Button
variant="tertiary"
size="small"
disabled={ historyPage >= last }
onClick={ () => handlePageClick( historyPage + 1 ) }
aria-label={ __( 'Next page', 'onesearch' ) }
>
</Button>
</div>
);
};

export default HistoryPagination;
Loading
Loading