plugins/woocommerce/client/admin/docs/examples/activity-panel-inbox.md
Right now, installing and activating WooCommerce and a few extensions quickly results in a cascade of notices vying for the store administrator’s attention (and pushing whatever wp-admin content they were trying to get to on a page down, way down.)
As part of the Dashboard and Analytics improvements coming to WooCommerce, we’re going to do something a bit dramatic to try and clean up this notice-palooza.
First, we’re splitting up notices into two broad categories.
The first category is what we’re calling “Store Alerts” - similar to the notices you have today, these notices are present at the top of administration pages and will look something like this:
But unlike today’s notices, this part of the UI will be reserved for “priority” messages to the administrator - things like version and security updates and critical errors. What sort of errors are “critical errors”? Well, things like a payment gateway that has stopped working because its connection is down, or when the store is set for physical product support but no shipping methods are defined.
The second category is what we’re focusing on in this example - and what we expect the vast majority of extension developers will want to extend - we call it the “Activity Panel Inbox.” It will look something like this:
This section is dedicated to informational content coming from multiple sources such as WooCommerce core, WooCommerce.com Subscription management, extensions activity and store achievements. This section was also envisioned to display more insightful content in the future, e.g. content that could help with the day to day tasks of managing and optimizing a store.
Each notice or “note” has a type represented by an icon (Gridicon), a title, content, a timestamp and one or two actions (action title + link).
Extensions can add their own notes via the data stores we’ll be covering below, but first: some constraints.
There are some constraints extensions should follow when working with the inbox:
So, enough rules - let’s get into how to code this up. And surprise, no JavaScript is necessary - you can work with the inbox exclusively through PHP -- the inbox front-end is React based, sure, but it draws all its data from a couple of new database tables and the PHP based REST API (and that’s where you can work with notes).
Here’s a short example plugin that adds a new activity panel inbox note on plugin activation, and removes it on deactivation:
<?php
/**
* Plugin Name: WooCommerce Activity Panel Inbox Example Plugin One
* Plugin URI: https://woocommerce.com/
* Description: An example plugin.
* Author: Automattic
* Author URI: https://woocommerce.com/
* Text Domain: wapi-example-one
* Version: 1.0.1
*/
use Automattic\WooCommerce\Admin\Notes\Notes as Notes;
use Automattic\WooCommerce\Admin\Notes\Note as Note;
class WooCommerce_Activity_Panel_Inbox_Example_Plugin_One {
const NOTE_NAME = 'wapi-example-plugin-one';
/**
* Adds a note to the merchant' inbox.
*/
public static function add_activity_panel_inbox_welcome_note() {
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ) {
return;
}
if ( ! class_exists( 'WC_Data_Store' ) ) {
return;
}
$data_store = WC_Data_Store::load( 'admin-note' );
// First, see if we've already created this kind of note so we don't do it again.
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
foreach( (array) $note_ids as $note_id ) {
$note = Notes::get_note( $note_id );
$content_data = $note->get_content_data();
if ( property_exists( $content_data, 'getting_started' ) ) {
return;
}
}
// Otherwise, add the note
$activated_time = current_time( 'timestamp', 0 );
$activated_time_formatted = date( 'F jS', $activated_time );
$note = new Note();
$note->set_title( __( 'Getting Started', 'wapi-example-plugin-one' ) );
$note->set_content(
sprintf(
/* translators: a date, e.g. November 1st */
__( 'Plugin activated on %s.', 'wapi-example-plugin-one' ),
$activated_time_formatted
)
);
$note->set_content_data( (object) array(
'getting_started' => true,
'activated' => $activated_time,
'activated_formatted' => $activated_time_formatted,
) );
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
$note->set_name( self::NOTE_NAME );
$note->set_source( 'wapi-example-plugin-one' );
$note->set_layout('plain');
$note->set_image('');
// This example has two actions. A note can have 0 or 1 as well.
$note->add_action(
'settings',
__( 'Open Settings', 'wapi-example-plugin-one' ),
'?page=wc-settings&tab=general'
);
$note->add_action(
'settings',
__( 'Learn More', 'wapi-example-plugin-one' ),
'https://github.com/woocommerce/woocommerce-admin/tree/main/docs'
);
$note->save();
}
/**
* Removes any notes this plugin created.
*/
public static function remove_activity_panel_inbox_notes() {
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ) {
return;
}
Notes::delete_notes_with_name( self::NOTE_NAME );
}
}
function wapi_example_one_activate() {
WooCommerce_Activity_Panel_Inbox_Example_Plugin_One::add_activity_panel_inbox_welcome_note();
}
register_activation_hook( __FILE__, 'wapi_example_one_activate' );
function wapi_example_one_deactivate() {
WooCommerce_Activity_Panel_Inbox_Example_Plugin_One::remove_activity_panel_inbox_notes();
}
register_deactivation_hook( __FILE__, 'wapi_example_one_deactivate' );
Here’s a short example plugin that updates an activity panel inbox note:
<?php
/**
* Plugin Name: WooCommerce Activity Panel Inbox Example Plugin Two
* Plugin URI: https://woocommerce.com/
* Description: An example plugin.
* Author: Automattic
* Author URI: https://woocommerce.com/
* Text Domain: wapi-example-plugin-two
* Version: 1.0.0
*/
use Automattic\WooCommerce\Admin\Notes\Notes as Notes;
use Automattic\WooCommerce\Admin\Notes\Note as Note;
class WooCommerce_Activity_Panel_Inbox_Example_Plugin_Two {
const NOTE_NAME = 'wapi-example-plugin-two';
/**
* Adds a note to the merchant' inbox.
*/
public static function add_or_update_activity_panel_inbox_note() {
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ) {
return;
}
if ( ! class_exists( 'WC_Data_Store' ) ) {
return;
}
$data_store = WC_Data_Store::load( 'admin-note' );
// First, see if we've already created our note so we don't do it again.
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
if ( empty( $note_ids ) ) {
$note = new Note();
$note->set_title( __( 'Domain Renewal Coming Up', 'wapi-example-plugin-two' ) );
} else {
$note = Notes::get_note( $note_ids[0] );
}
$expires_in_days = rand( 2, 365 );
$note->set_content(
sprintf(
/* translators: a number of days, e.g. 100 */
__( 'Your domain expires in %d days.', 'wapi-example-plugin-wto' ),
$expires_in_days
)
);
$note->set_content_data( (object) array(
'expires_in_days' => $expires_in_days,
) );
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
$note->set_name( self::NOTE_NAME );
$note->set_layout('plain');
$note->set_image('');
$note->set_source( 'wapi-example-plugin-two' );
// This example has no actions. A note can have 1 or 2 as well.
$note->save();
}
/**
* Removes any notes this plugin created.
*/
public static function remove_activity_panel_inbox_notes() {
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ) {
return;
}
Notes::delete_notes_with_name( self::NOTE_NAME );
}
}
function admin_init() {
WooCommerce_Activity_Panel_Inbox_Example_Plugin_Two::add_or_update_activity_panel_inbox_note();
}
add_action( 'admin_init', 'admin_init' );
function wapi_example_two_deactivate() {
WooCommerce_Activity_Panel_Inbox_Example_Plugin_Two::remove_activity_panel_inbox_notes();
}
register_deactivation_hook( __FILE__, 'wapi_example_two_deactivate' );
A limited set of note fields can be updated over the REST API: status and date_reminder.
This is just the tip of the iceberg for possibilities for your own extensions to WooCommerce. Check out the new sales record notes and the settings notes in the woocommerce-admin code itself for other examples of working with this fun new feature.