diff --git a/static/app/components/onboarding/productSelection.spec.tsx b/static/app/components/onboarding/productSelection.spec.tsx
index a4b379cda971ab..a1525d045c9ab5 100644
--- a/static/app/components/onboarding/productSelection.spec.tsx
+++ b/static/app/components/onboarding/productSelection.spec.tsx
@@ -224,6 +224,58 @@ describe('Onboarding Product Selection', function () {
expect(screen.getByRole('checkbox', {name: 'Session Replay'})).toBeDisabled();
});
+ it('selects all products per default', async function () {
+ const {router} = initializeOrg({
+ router: {
+ location: {
+ query: {},
+ },
+ params: {},
+ },
+ });
+
+ render(, {
+ router,
+ });
+
+ // router.replace is called to apply default product selection
+ await waitFor(() =>
+ expect(router.replace).toHaveBeenCalledWith(
+ expect.objectContaining({
+ query: expect.objectContaining({
+ product: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
+ }),
+ })
+ )
+ );
+ });
+
+ it('applies defined default product selection', async function () {
+ const {router} = initializeOrg({
+ router: {
+ location: {
+ query: {},
+ },
+ params: {},
+ },
+ });
+
+ render(, {
+ router,
+ });
+
+ // router.replace is called to apply default product selection
+ await waitFor(() =>
+ expect(router.replace).toHaveBeenCalledWith(
+ expect.objectContaining({
+ query: expect.objectContaining({
+ product: [ProductSolution.PERFORMANCE_MONITORING],
+ }),
+ })
+ )
+ );
+ });
+
it('triggers onChange callback', async function () {
const {router} = initializeOrg({
router: {
diff --git a/static/app/components/onboarding/productSelection.tsx b/static/app/components/onboarding/productSelection.tsx
index 211ca293d09f6f..07f55fff616b64 100644
--- a/static/app/components/onboarding/productSelection.tsx
+++ b/static/app/components/onboarding/productSelection.tsx
@@ -162,7 +162,7 @@ export const platformProductAvailability = {
'node-nestjs': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
php: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'php-laravel': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
- ['php-symfony']: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
+ 'php-symfony': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
python: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'python-aiohttp': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'python-asgi': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
@@ -193,6 +193,16 @@ export const platformProductAvailability = {
'ruby-rails': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
} as Record;
+/**
+ * Defines which products are selected per default for each platform
+ * If not defined in here, all products are selected
+ */
+const platformDefaultProducts: Partial> = {
+ php: [ProductSolution.PERFORMANCE_MONITORING],
+ 'php-laravel': [ProductSolution.PERFORMANCE_MONITORING],
+ 'php-symfony': [ProductSolution.PERFORMANCE_MONITORING],
+};
+
type ProductProps = {
/**
* If the product is checked. This information is grabbed from the URL.
@@ -296,17 +306,12 @@ export type ProductSelectionProps = {
* The platform key of the project (e.g. javascript-react, python-django, etc.)
*/
platform?: PlatformKey;
- /**
- * A custom list of products per platform. If not provided, the default list is used.
- */
- productsPerPlatform?: Record;
};
export function ProductSelection({
disabledProducts: disabledProductsProp,
organization,
platform,
- productsPerPlatform = platformProductAvailability,
onChange,
onLoad,
}: ProductSelectionProps) {
@@ -314,16 +319,27 @@ export function ProductSelection({
const urlProducts = useMemo(() => params.product ?? [], [params.product]);
const products: ProductSolution[] | undefined = platform
- ? productsPerPlatform[platform]
+ ? platformProductAvailability[platform]
: undefined;
const disabledProducts = useMemo(
() => disabledProductsProp ?? getDisabledProducts(organization),
[organization, disabledProductsProp]
);
+
const defaultProducts = useMemo(() => {
- return products?.filter(product => !(product in disabledProducts)) ?? [];
- }, [products, disabledProducts]);
+ const productsArray = products ?? [];
+ const definedDefaults = platform ? platformDefaultProducts[platform] : undefined;
+ let selectedDefaults: ProductSolution[] = productsArray;
+
+ if (definedDefaults) {
+ selectedDefaults = definedDefaults.filter(product =>
+ // Make sure the default product is available for the platform
+ productsArray.includes(product)
+ );
+ }
+ return selectedDefaults.filter(product => !(product in disabledProducts));
+ }, [products, platform, disabledProducts]);
useEffect(() => {
onLoad?.(defaultProducts);
diff --git a/static/app/types/hooks.tsx b/static/app/types/hooks.tsx
index 019ee936ff0e19..5ce77e6e9cdd1c 100644
--- a/static/app/types/hooks.tsx
+++ b/static/app/types/hooks.tsx
@@ -123,10 +123,7 @@ type OrganizationHeaderProps = {
organization: Organization;
};
-type ProductSelectionAvailabilityProps = Omit<
- ProductSelectionProps,
- 'disabledProducts' | 'productsPerPlatform'
->;
+type ProductSelectionAvailabilityProps = Omit;
type FirstPartyIntegrationAlertProps = {
integrations: Integration[];