diff --git a/includes/core/utilities/class-date-time-helpers.php b/includes/core/utilities/class-date-time-helpers.php
index 44db5b6..d11182f 100644
--- a/includes/core/utilities/class-date-time-helpers.php
+++ b/includes/core/utilities/class-date-time-helpers.php
@@ -47,9 +47,9 @@ public static function get_formatted_relative_date_time( $date = null ) {
/* translators: 1: Date, 2: Time. */
esc_html_x( '%1$s at %2$s', 'date at time', 'visual-regression-tests' ),
/* translators: Date format. See https://www.php.net/manual/datetime.format.php */
- date_format( $date, esc_html_x( 'Y/m/d', 'date format', 'visual-regression-tests' ) ),
+ static::extract_date( $date ),
/* translators: Time format. See https://www.php.net/manual/datetime.format.php */
- date_format( $date, esc_html_x( 'g:i a', 'time format', 'visual-regression-tests' ) )
+ static::extract_time( $date )
);
return '' . $formatted_date . '';
}
@@ -67,4 +67,31 @@ private static function date_from_gmt( $date ) {
return $date;
}
+
+ private static function extract_date($inputDate) {
+ // Get today's date at midnight
+ $today = new DateTime('today');
+
+ // Clone input date and set time to midnight
+ $comparisonDate = clone $inputDate;
+ $comparisonDate->setTime(0, 0, 0);
+
+ // Calculate the difference in days
+ $differenceInSeconds = $comparisonDate->getTimestamp() - $today->getTimestamp();
+ $differenceInDays = (int) round($differenceInSeconds / (60 * 60 * 24));
+
+ // Determine if the date is today, tomorrow, or yesterday
+ if ($differenceInDays === 0) {
+ return __('Today', 'visual-regression-testing');
+ } elseif ($differenceInDays === 1) {
+ return __('Tomorrow', 'visual-regression-testing');
+ } elseif ($differenceInDays === -1) {
+ return __('Yesterday', 'visual-regression-testing');
+ }
+ return $inputDate->format('D, Y/m/d');
+ }
+
+ private static function extract_time($inputDate) {
+ return $inputDate->setTimezone(wp_timezone())->format('g:i a');
+ }
}
diff --git a/includes/features/class-admin.php b/includes/features/class-admin.php
index 69cb7aa..f96eab5 100644
--- a/includes/features/class-admin.php
+++ b/includes/features/class-admin.php
@@ -18,7 +18,7 @@ public function __construct() {
* Add main menu where other sub menus can be added to.
*/
public function add_main_menu() {
- $count = Alert::get_total_items();
+ $count = Alert::get_total_items_grouped_by_test_run();
add_menu_page(
'VRTs',
diff --git a/includes/features/class-test-runs-page.php b/includes/features/class-test-runs-page.php
index ac06949..fb4f2d8 100644
--- a/includes/features/class-test-runs-page.php
+++ b/includes/features/class-test-runs-page.php
@@ -21,10 +21,12 @@ public function __construct() {
* Add submenu.
*/
public function add_submenu_page() {
+ $count = Alert::get_total_items_grouped_by_test_run();
+
$submenu_page = add_submenu_page(
'vrts',
__( 'Runs', 'visual-regression-tests' ),
- __( 'Runs', 'visual-regression-tests' ),
+ $count ? esc_html__( 'Runs', 'visual-regression-tests' ) . ' ' . esc_html( $count ) . '' : esc_html__( 'Runs', 'visual-regression-tests' ),
'manage_options',
'vrts-runs',
[ $this, 'render_page' ],
diff --git a/includes/list-tables/class-test-runs-list-table.php b/includes/list-tables/class-test-runs-list-table.php
index 6de0202..9f14464 100644
--- a/includes/list-tables/class-test-runs-list-table.php
+++ b/includes/list-tables/class-test-runs-list-table.php
@@ -81,8 +81,7 @@ public function get_columns() {
*/
public function get_sortable_columns() {
$sortable_columns = [
- 'title' => [ 'title', true ],
- 'status' => false,
+ 'title' => [ 'finished_at', true ],
'trigger' => [ 'trigger', true ],
];
@@ -147,7 +146,7 @@ public function prepare_items() {
$order = isset( $_REQUEST['order'] ) && 'asc' === $_REQUEST['order'] ? 'ASC' : 'DESC';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It's the list order by parameter.
- $order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'finished_at';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- It's the list search query parameter.
$filter_status_query = isset( $_REQUEST['status'] ) && '' !== $_REQUEST['status'] ? sanitize_text_field( wp_unslash( $_REQUEST['status'] ) ) : null;
diff --git a/includes/list-tables/class-test-runs-queue-list-table.php b/includes/list-tables/class-test-runs-queue-list-table.php
index 2139a5f..90ee9d0 100644
--- a/includes/list-tables/class-test-runs-queue-list-table.php
+++ b/includes/list-tables/class-test-runs-queue-list-table.php
@@ -243,7 +243,7 @@ public function column_status( $item ) {
);
} else {
$class = 'waiting';
- $text = esc_html__( 'Scheduled', 'visual-regression-tests' );
+ $text = esc_html__( 'Pending', 'visual-regression-tests' );
$instructions = sprintf(
'%2$s | %4$s',
// translators: %s: number of tests.
diff --git a/includes/models/class-alert.php b/includes/models/class-alert.php
index 6c0cc17..fe98139 100644
--- a/includes/models/class-alert.php
+++ b/includes/models/class-alert.php
@@ -291,6 +291,59 @@ public static function get_total_items( $filter_status_query = null, $test_run_i
return (int) $wpdb->get_var( $query );
}
+ /**
+ * Get total test items from database
+ *
+ * @param int $filter_status_query the id of status.
+ * @param int $test_run_id the id of the test run.
+ *
+ * @return array
+ */
+ public static function get_total_items_grouped_by_test_run( $filter_status_query = null ) {
+ global $wpdb;
+
+ $alerts_table = Alerts_Table::get_table_name();
+
+ // 0 = Open
+ // 1 = Archived.
+ // 2 = False Positive.
+ switch ( $filter_status_query ?? null ) {
+ case 'archived':
+ $alert_states = [ 1, 2 ];
+ break;
+ case 'all':
+ $alert_states = [];
+ break;
+ default:
+ $alert_states = [ 0 ];
+ break;
+ }
+ if ( ! empty( $alert_states ) ) {
+ $alert_states_placeholders = implode( ', ', array_fill( 0, count( $alert_states ), '%d' ) );
+
+ $status_where = $wpdb->prepare(
+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- It's ok.
+ "WHERE alert_state IN ($alert_states_placeholders)",
+ $alert_states
+ );
+ } else {
+ $status_where = 'WHERE 1=1';
+ }
+
+ $where = "{$status_where} AND test_run_id IS NOT NULL";
+
+
+ $query = "
+ SELECT COUNT(DISTINCT test_run_id) FROM $alerts_table
+ $where
+ ";
+
+ // var_dump($query);die();
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- It's prepared above
+ return (int) $wpdb->get_var( $query );
+ }
+
/**
* Update alert status.
diff --git a/includes/models/class-test-run.php b/includes/models/class-test-run.php
index f26fe36..8743f8c 100644
--- a/includes/models/class-test-run.php
+++ b/includes/models/class-test-run.php
@@ -46,7 +46,7 @@ public static function get_items( $args = [], $return_count = false ) {
}
}
- $whitelist_orderby = [ 'id', 'title' ];
+ $whitelist_orderby = [ 'id', 'title', 'started_at', 'finished_at', 'trigger' ];
$whitelist_order = [ 'ASC', 'DESC' ];
$orderby = in_array( $args['orderby'], $whitelist_orderby, true ) ? $args['orderby'] : 'id';
@@ -55,7 +55,7 @@ public static function get_items( $args = [], $return_count = false ) {
if ( 'status' === $orderby ) {
$orderby = "ORDER BY calculated_status $order, calculated_date $order";
} else {
- $orderby = "ORDER BY $orderby $order";
+ $orderby = "ORDER BY `$orderby` $order";
}
$limit = $args['number'] > 100 ? 100 : $args['number'];
@@ -307,9 +307,9 @@ public static function get_trigger_title( $test_run ) {
$trigger_titles = [
'manual' => __( 'Manual', 'visual-regression-tests' ),
- 'scheduled' => __( 'Scheduled', 'visual-regression-tests' ),
+ 'scheduled' => __( 'Schedule', 'visual-regression-tests' ),
'api' => __( 'API', 'visual-regression-tests' ),
- 'update' => __( 'WordPress', 'visual-regression-tests' ),
+ 'update' => __( 'Update', 'visual-regression-tests' ),
];
return $trigger_titles[ $test_run->trigger ] ?? __( 'Unknown', 'visual-regression-tests' );
@@ -469,7 +469,7 @@ public static function get_status_data( $test_run ) {
break;
case 'scheduled':
$class = 'waiting';
- $text = esc_html__( 'Scheduled', 'visual-regression-tests' );
+ $text = esc_html__( 'Pending', 'visual-regression-tests' );
$instructions .= sprintf(
'%2$s',
esc_url( admin_url( 'admin.php?page=vrts-settings' ) ),