diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts
index 42b23a9246b35..4460ba29b498f 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts
@@ -50,6 +50,8 @@ export const PATTERN_ASSEMBLER_EVENTS = {
PATTERN_MOVEDOWN_CLICK: 'calypso_signup_pattern_assembler_pattern_movedown_click',
PATTERN_REPLACE_CLICK: 'calypso_signup_pattern_assembler_pattern_replace_click',
PATTERN_DELETE_CLICK: 'calypso_signup_pattern_assembler_pattern_delete_click',
+ PATTERN_SHUFFLE_CLICK: 'calypso_signup_pattern_assembler_pattern_shuffle_click',
+
PREVIEW_DEVICE_CLICK: 'calypso_signup_pattern_assembler_preview_device_click',
/**
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx
index 45dc0aa508f15..325ce0f3e8cf6 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx
@@ -45,7 +45,7 @@ import ScreenFontPairings from './screen-font-pairings';
import ScreenFooter from './screen-footer';
import ScreenHeader from './screen-header';
import ScreenMain from './screen-main';
-import { encodePatternId } from './utils';
+import { encodePatternId, getShuffledPattern, injectCategoryToPattern } from './utils';
import withGlobalStylesProvider from './with-global-styles-provider';
import type { Pattern } from './types';
import type { StepProps } from '../../types';
@@ -247,17 +247,17 @@ const PatternAssembler = ( {
}
};
- const replaceSection = ( pattern: Pattern ) => {
- if ( sectionPosition !== null ) {
+ const replaceSection = ( pattern: Pattern, position: number | null = sectionPosition ) => {
+ if ( position !== null ) {
setSections( [
- ...sections.slice( 0, sectionPosition ),
+ ...sections.slice( 0, position ),
{
...pattern,
- key: sections[ sectionPosition ].key,
+ key: sections[ position ].key,
},
- ...sections.slice( sectionPosition + 1 ),
+ ...sections.slice( position + 1 ),
] );
- updateActivePatternPosition( sectionPosition );
+ updateActivePatternPosition( position );
noticeOperations.showPatternInsertedNotice( pattern );
}
};
@@ -308,24 +308,7 @@ const PatternAssembler = ( {
selectedCategory?: string | null
) => {
if ( selectedPattern ) {
- // Inject the selected pattern category or the first category
- // to be used in tracks and as selected pattern name.
- const [ firstCategory ] = Object.keys( selectedPattern.categories );
- selectedPattern.category = categories.find( ( { name } ) => {
- if ( selectedCategory === CATEGORY_ALL_SLUG ) {
- return name === firstCategory;
- }
- return name === ( selectedCategory || firstCategory );
- } );
-
- if ( selectedCategory === CATEGORY_ALL_SLUG ) {
- // Use 'all' rather than 'featured' as slug for tracks.
- // Use the first category label as selected pattern name.
- selectedPattern.category = {
- name: 'all',
- label: selectedPattern.category?.label,
- };
- }
+ injectCategoryToPattern( selectedPattern, categories, selectedCategory );
trackEventPatternSelect( {
patternType: type,
@@ -485,6 +468,23 @@ const PatternAssembler = ( {
const onDeleteFooter = () => onSelect( 'footer', null );
+ const onShuffle = ( type: string, pattern: Pattern, position?: number ) => {
+ const [ firstCategory ] = Object.keys( pattern.categories );
+ const selectedCategory = pattern.category?.name || firstCategory;
+ const patterns =
+ patternsMapByCategory[ selectedCategory ] || patternsMapByCategory[ CATEGORY_ALL_SLUG ];
+ const shuffledPattern = getShuffledPattern( patterns, pattern );
+ injectCategoryToPattern( shuffledPattern, categories, selectedCategory );
+
+ if ( type === 'header' ) {
+ updateHeader( shuffledPattern );
+ } else if ( type === 'footer' ) {
+ updateFooter( shuffledPattern );
+ } else {
+ replaceSection( shuffledPattern, position );
+ }
+ };
+
const onScreenColorsSelect = ( variation: GlobalStylesObject | null ) => {
setColorVariation( variation );
recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.SCREEN_COLORS_PREVIEW_CLICK, {
@@ -619,6 +619,7 @@ const PatternAssembler = ( {
onMoveDownSection={ onMoveDownSection }
onDeleteHeader={ onDeleteHeader }
onDeleteFooter={ onDeleteFooter }
+ onShuffle={ onShuffle }
recordTracksEvent={ recordTracksEvent }
/>
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx
index be2299202d81e..a9dd23c878429 100644
--- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx
+++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx
@@ -1,8 +1,9 @@
import { Button } from '@wordpress/components';
-import { chevronUp, chevronDown, close, edit } from '@wordpress/icons';
+import { chevronUp, chevronDown, close, edit, shuffle } from '@wordpress/icons';
import { useTranslate } from 'i18n-calypso';
import { recordTracksEvent } from 'calypso/lib/analytics/tracks';
import { PATTERN_ASSEMBLER_EVENTS } from './events';
+import type { Category } from './types';
import './pattern-action-bar.scss';
type PatternActionBarProps = {
@@ -10,9 +11,11 @@ type PatternActionBarProps = {
onDelete: () => void;
onMoveUp?: () => void;
onMoveDown?: () => void;
+ onShuffle: () => void;
disableMoveUp?: boolean;
disableMoveDown?: boolean;
patternType: string;
+ category?: Category;
isRemoveButtonTextOnly?: boolean;
source: 'list' | 'large_preview';
};
@@ -22,13 +25,21 @@ const PatternActionBar = ( {
onDelete,
onMoveUp,
onMoveDown,
+ onShuffle,
disableMoveUp,
disableMoveDown,
patternType,
+ category,
isRemoveButtonTextOnly,
source,
}: PatternActionBarProps ) => {
const translate = useTranslate();
+ const eventProps = {
+ pattern_type: patternType,
+ pattern_category: category?.name,
+ source,
+ };
+
return (
{
- recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PATTERN_MOVEUP_CLICK, {
- source,
- } );
+ recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PATTERN_MOVEUP_CLICK, eventProps );
onMoveUp?.();
} }
icon={ chevronUp }
@@ -57,9 +66,7 @@ const PatternActionBar = ( {
role="menuitem"
label={ translate( 'Move down' ) }
onClick={ () => {
- recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PATTERN_MOVEDOWN_CLICK, {
- source,
- } );
+ recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PATTERN_MOVEDOWN_CLICK, eventProps );
onMoveDown?.();
} }
icon={ chevronDown }
@@ -67,16 +74,24 @@ const PatternActionBar = ( {
/>
) }
+