Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add REST and datastore APIs for audience settings #8176

Closed
37 tasks done
techanvil opened this issue Jan 25, 2024 · 14 comments
Closed
37 tasks done

Add REST and datastore APIs for audience settings #8176

techanvil opened this issue Jan 25, 2024 · 14 comments
Labels
Module: Analytics Google Analytics module related issues P1 Medium priority Type: Enhancement Improvement of an existing feature

Comments

@techanvil
Copy link
Collaborator

techanvil commented Jan 25, 2024

Feature Description

Add REST and datastore APIs for audience settings. This essentially means the following REST endpoints:

  • GET audience-settings
  • POST audience-settings

And the following datastore selectors and actions (including additional Redux infra as needed):

  • getConfiguredAudiences()
  • haveConfiguredAudiencesChanged()
  • setConfiguredAudiences()
  • isAudienceSegmentationWidgetHidden()
  • setAudienceSegmentationWidgetHidden()
  • saveAudienceSettings()

See REST infrastructure and datastore configuration in the design doc.


Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

REST API Endpoints Implementation

  • Implement the GET audience-settings endpoint in the analytics-4 module to fetch user settings for audiences. This endpoint should return an object containing the following:
    • configuredAudiences: An array, with a default value of null.
    • isAudienceSegmentationWidgetHidden: A boolean, with a default value of false.
  • Implement the POST audience-settings endpoint in the analytics-4 module to update user settings for audiences. This endpoint should accept an object that may contain the configuredAudiences array and the isAudienceSegmentationWidgetHidden boolean value, and update the corresponding settings.

Datastore Implementation

  • Implement getConfiguredAudiences() selector in the analytics-4 partial datastore. This selector should retrieve the configuredAudiences array from the GET audience-settings endpoint.
  • Implement haveConfiguredAudiencesChanged() in the analytics-4 partial datastore to check if the local state for the configured audiences has changed.
  • Implement setConfiguredAudiences( audienceResourceNames ) in the analytics-4 partial datastore to set the local state of the configured audiences.
  • Implement isAudienceSegmentationWidgetHidden() selector in the analytics-4 partial datastore. This selector should retrieve the current value of the isAudienceSegmentationWidgetHidden setting via the GET audience-settings endpoint.
  • Implement setAudienceSegmentationWidgetHidden( isWidgetHidden ) action in the analytics-4 partial datastore. This action should update the local state of the isAudienceSegmentationWidgetHidden setting.
  • Implement saveAudienceSettings() action in the analytics-4 partial datastore. This action should persist the local state of the audience settings via the POST audience-settings endpoint.

Implementation Brief

REST API Endpoints

In includes/Modules/Analytics_4:

  • Create new class Audience_Settings that extends User_Setting class with the following:
    • It should largely mirror the Key_Metrics_Settings class.
    • Replace the OPTION CONSTANT with the value googlesitekit_audience_settings.
    • Replace isWidgetHidden with isAudienceSegmentationWidgetHidden and widgetSlugs with configuredAudiences.

In includes/Modules/Analytics_4.php:

  • In the get_datapoint_definitions() method within the audienceSegmentation feature flag enabled block:
    • Add a new GET:audience-settings endpoint to fetch audience user settings.
    • Add a new POST:audience-settings endpoint to update audience user settings.
  • In the create_data_request() method:
    • Add a case for the new GET:audience-settings endpoint to fetch audience user settings.
      • Use the Audience_Settings::get() method to retrieve the googlesitekit_audience_settings option.
      • Return the configuredAudiences and isAudienceSegmentationWidgetHidden settings.
    • Add a case for the new POST:audience-settings endpoint to update the user settings for audiences.
      • Validate the request data and ensure the configuredAudiences is an array and isAudienceSegmentationWidgetHidden is a boolean.
      • Use the Audience_Settings::merge() method to update the googlesitekit_audience_settings option.
      • Return the updated configuredAudiences and isAudienceSegmentationWidgetHidden settings.

Fetch Stores

  • Create a new file named audience-settings.js within the assets/js/modules/analytics-4/datastore/ directory.
  • Utilize createFetchStore to establish fetch stores for the GET audience-settings and POST audience-settings endpoints. These stores will handle fetching and updating the audience settings from the REST API.
  • These can share the same reducer using the createReducer function from the Immer library. It should set both the audienceSettings.settings and audienceSettings.savedSettings properties in the state.
    • For GET audience-settings:
      • Define a base name, such as getAudienceSettings.
      • The store should manage to fetch the audience settings, including configuredAudiences and isAudienceSegmentationWidgetHidden.
    • For POST audience-settings:
      • Define a base name, such as saveAudienceSettings.
      • Validate the request data and ensure the configuredAudiences is an array and isAudienceSegmentationWidgetHidden is a boolean.

Base Initial State

  • Add audienceSettings to the initial state with the value of an empty object.
  • Eventually, the audienceSettings object will contain settings and savedSettings properties.

Resolvers

  • Implement a resolver for *getAudienceSettings() to ensure that the audience settings are fetched from the server when the data is not already present in the state.
  • The resolver should check the existing state to determine if the fetch has already occurred to prevent unnecessary network requests.

Selectors

  • getAudienceSettings(): This selector should return the audienceSettings.settings state.
  • getConfiguredAudiences(): Use the getAudienceSettings selector to retrieve the configuredAudiences array from the audience settings.
  • isAudienceSegmentationWidgetHidden(): Use the getAudienceSettings selector to retrieve the isAudienceSegmentationWidgetHidden setting from the audience settings.
  • haveConfiguredAudiencesChanged(): This selector should return the result of a comparison between the settings and savedSettings properties of the audienceSettings state.

Actions

  • setConfiguredAudiences( audienceResourceNames ): This action should locally update the list of configured audiences of the audienceSettings.settings state.
  • setAudienceSegmentationWidgetHidden( isWidgetHidden ): This action should locally update the isAudienceSegmentationWidgetHidden setting of the audienceSettings.settings state.
  • saveAudienceSettings(): This action should call the fetch store-generated fetchSaveAudienceSettings action with the current audienceSettings.settings state.

Test Coverage

  • Add tests for the Audience_Settings class methods.
  • Unit tests should be created for the new selectors and actions.

QA Brief

  • Make sure you have Site Kit set up with Google Analytics 4.
  • Ensure the audienceSegmentation feature flag is enabled.
  • Open the developer tools in your browser and navigate to the console tab.
  • Execute the following newly added audience settings actions and selectors in the console.

Actions

Action: setConfiguredAudiences( audienceResourceNames: Array<string> )

  1. Execute the action by running the following command:

    googlesitekit.data.dispatch('modules/analytics-4').setConfiguredAudiences( [ 'audienceResourceName1', 'audienceResourceName2' ] )
  2. Verify that the action has updated the client-side state correctly.

  3. Run the selector to double-check:

    googlesitekit.data.select('modules/analytics-4').getConfiguredAudiences()

    It should return the updated array.

Action: setAudienceSegmentationWidgetHidden( isWidgetHidden: boolean )

  1. Execute the action by running the following command:

    googlesitekit.data.dispatch('modules/analytics-4').setAudienceSegmentationWidgetHidden( true )
  2. Verify that the action has updated the client-side state correctly.

  3. Run the selector to double-check:

    googlesitekit.data.select('modules/analytics-4').isAudienceSegmentationWidgetHidden()

    It should return the updated boolean value.

Action: saveAudienceSettings()

  1. Execute the action by running the following command:

    googlesitekit.data.dispatch('modules/analytics-4').saveAudienceSettings()
  2. Check the network tab for a POST request to audience-settings and verify that the request payload contains the correct data if the state has changed.

Selectors

Selector: getAudienceSettings(): Object

  1. Execute the selector:

    googlesitekit.data.select('modules/analytics-4').getAudienceSettings()
  2. Verify that it either returns the correct object with configuredAudiences and isAudienceSegmentationWidgetHidden properties or triggers a network request to fetch the audience settings.

Selector: getConfiguredAudiences(): Array<string>

  1. Execute the selector:

    googlesitekit.data.select('modules/analytics-4').getConfiguredAudiences()
  2. Verify that it returns the array of configured audience resource names or an empty array.

Selector: isAudienceSegmentationWidgetHidden(): boolean

  1. Execute the selector:

    googlesitekit.data.select('modules/analytics-4').isAudienceSegmentationWidgetHidden()
  2. Verify that it returns the boolean value of isAudienceSegmentationWidgetHidden.

Selector: haveConfiguredAudiencesChanged(): boolean

  1. Execute the selector:

    googlesitekit.data.select('modules/analytics-4').haveConfiguredAudiencesChanged()
  2. Verify that it returns a boolean value indicating whether the configuredAudiences have changed.

Changelog entry

  • Introduce infrastructure for managing Audience settings.
@techanvil techanvil added Module: Analytics Google Analytics module related issues P1 Medium priority Type: Enhancement Improvement of an existing feature labels Jan 25, 2024
@hussain-t hussain-t assigned hussain-t and unassigned hussain-t Jan 29, 2024
@eugene-manuilov eugene-manuilov self-assigned this Jan 30, 2024
@eugene-manuilov
Copy link
Collaborator

  • A new GET audience-settings endpoint should be implemented to fetch user settings for audiences in the analytics-4 module. This endpoint should return an object containing the key isAudienceSegmentationWidgetHidden with a boolean value. The default value for this key should be false.

@hussain-t, I think the default value should be the one selected by the primary admin (module owner), right? See the design doc:

When the feature has been set up, all subsequent users (i.e. view-only and secondary admin users)
will see the audience selection of the primary admin until they make a change themselves. After this
point, their own settings will take precedence and there will be no way to revert to the primary
admin’s settings.

https://docs.google.com/document/d/1MGD5Djy6AeeZC4zBtHqS-lQEWD9jw0kf-IIWw-jLCFU/edit?tab=t.0#heading=h.q4hnjsnlu3ha

@techanvil
Copy link
Collaborator Author

@eugene-manuilov @hussain-t actually, per-user settings are fine here.

For one thing this setting was not intended to follow the primary admin's.

More importantly to be aware of though, is we're actually removing this primary/secondary user settings aspect altogether due to complications with that approach.

Instead, we are going to take the approach where each user's settings are initialised according to some logic and don't attempt to follow a root setting at all (see this comment thread on the design doc).

I will be updating the design doc soon, apologies for the confusion in the meantime!

@eugene-manuilov
Copy link
Collaborator

eugene-manuilov commented Jan 30, 2024

Ok, thanks, @techanvil. So the default value should be neither false nor the primary admin's selection, but the value set in the Analytics settings, right? Then how is it going to work for the beginning, when nobody has selected it yet?

For example, if I am the first one who selects to show the feature, then my user settings will be updated as well as the Analytics settings, right? But then, if I decide to turn it off, then it will be turned off only for me and all other users will continue seeing it, right? So, to turn it off for all users, everyone will need to go to the settings and manually turn it off for themselves?

@techanvil
Copy link
Collaborator Author

@eugene-manuilov, I think the default value should be false - it's similar to the isWidgetHidden Key Metrics setting which is a user setting:

protected function get_default() {
return array(
'widgetSlugs' => array(),
'isWidgetHidden' => false,
);
}

This KM setting already works in the same way - each (admin) user controls their own setting, there's no way to toggle it for all users.

There is admittedly a bit of a functionality gap for view-only users - both for Audience Segmentation, and for KM as it stands. I have raised this with Mariya in a thread on the design doc. Seeing as KM already works like this I suspect we'll continue as specced for the most part, but it might be worth waiting for her thoughts on this before we finalise the AC here.

@techanvil
Copy link
Collaborator Author

Update: Due to ongoing changes to the design doc, we may well want to expand the scope of this issue to include the additional configuredAudiences setting.

Let's hold off until this additional thread on the design doc is also resolved.

@techanvil
Copy link
Collaborator Author

techanvil commented Jan 31, 2024

Update: With Evan having approved the changes, and Mariya already having given her general approval for the direction (so really just needing to sign off on the details), it's clear we will be including configuredAudiences in these settings and not continuing with the previous specced two tier settings approach.

Therefore, I have updated the datastore configuration in the design doc, and updated the Feature Description for this issue accordingly. @hussain-t, please note that the definition for setAudienceSegmentationWidgetHidden() has changed as a result for consistency with the configuredAudiences related functions. The GET:audience-settings endpoint definition has also been tweaked to include configuredAudiences.

Although there are still a few last details to approve in the threads linked in the previous two comments, I think we can now safely proceed with this issue as specified.

@hussain-t
Copy link
Collaborator

Thanks, @techanvil 👍

@eugene-manuilov
Copy link
Collaborator

Thanks, @hussain-t and @techanvil. AC ✔️

@eugene-manuilov eugene-manuilov removed their assignment Jan 31, 2024
@techanvil
Copy link
Collaborator Author

@hussain-t, as discussed on Slack the AC does need a small tweak:

We can't use getConfiguredAudiences() to return the value for isAudienceSegmentationWidgetHidden() because getConfiguredAudiences() only returns configuredAudiences and not isAudienceSegmentationWidgetHidden.

I've assigned this back to you in AC for an update.

@hussain-t
Copy link
Collaborator

Thanks, @techanvil. I have updated the AC to retrieve the current value of the isAudienceSegmentationWidgetHidden setting directly via the GET audience-settings endpoint.

@hussain-t hussain-t assigned techanvil and unassigned hussain-t Feb 1, 2024
@techanvil
Copy link
Collaborator Author

techanvil commented Feb 1, 2024

Thanks @hussain-t, the AC LGTM ✅

Assigning to you in IB as requested. Remember, we don't literally have to directly fetch the value from GET audience-settings in each selector, we can create additional Redux infrastructure as needed e.g. a common getAudienceSettings() and so forth.

@techanvil techanvil assigned hussain-t and unassigned techanvil Feb 1, 2024
@eugene-manuilov
Copy link
Collaborator

IB ✔️

@eugene-manuilov eugene-manuilov removed their assignment Feb 15, 2024
@ivonac4 ivonac4 removed the Next Up Issues to prioritize for definition label Feb 16, 2024
@hussain-t hussain-t self-assigned this Mar 8, 2024
@hussain-t hussain-t removed their assignment Mar 18, 2024
@zutigrm zutigrm assigned zutigrm and hussain-t and unassigned zutigrm Mar 18, 2024
@hussain-t hussain-t assigned zutigrm and unassigned hussain-t Mar 19, 2024
@zutigrm zutigrm removed their assignment Mar 19, 2024
@kuasha420 kuasha420 assigned kuasha420 and hussain-t and unassigned kuasha420 Mar 19, 2024
@hussain-t hussain-t assigned kuasha420 and unassigned hussain-t Mar 20, 2024
kuasha420 added a commit that referenced this issue Mar 21, 2024
…ce-settings

Enhance/#8176 - Add REST and datastore APIs for audience settings
@kuasha420 kuasha420 removed their assignment Mar 21, 2024
@mohitwp mohitwp self-assigned this Mar 25, 2024
@mohitwp
Copy link
Collaborator

mohitwp commented Mar 27, 2024

QA Update ✅

  • Tested on dev environment.
  • Verified all Actions and Selectors under QAB.
  • Verified all Actions and Selectors giving expected results.

Action: setConfiguredAudiences( audienceResourceNames: Array )

image

image

Action: setAudienceSegmentationWidgetHidden( isWidgetHidden: boolean )

image

image

Action: saveAudienceSettings()

Changed boolean value from true to false -

image

image

image

Change settings -

image

image

SELECTORS

Selector: getAudienceSettings(): Object

image

image

Selector: getConfiguredAudiences(): Array

image

Selector: isAudienceSegmentationWidgetHidden(): boolean

image

Selector: haveConfiguredAudiencesChanged(): boolean

image

On changing the configured audiences it return the value true -

image

@mohitwp mohitwp removed their assignment Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Module: Analytics Google Analytics module related issues P1 Medium priority Type: Enhancement Improvement of an existing feature
Projects
None yet
Development

No branches or pull requests

8 participants