diff --git a/packages/dataviews/src/item-actions.js b/packages/dataviews/src/item-actions.js index 473615214da7b2..974c5c5d0d5c3f 100644 --- a/packages/dataviews/src/item-actions.js +++ b/packages/dataviews/src/item-actions.js @@ -21,6 +21,7 @@ const { DropdownMenuGroupV2: DropdownMenuGroup, DropdownMenuItemV2: DropdownMenuItem, DropdownMenuItemLabelV2: DropdownMenuItemLabel, + kebabCase, } = unlock( componentsPrivateApis ); function ButtonTrigger( { action, onClick } ) { @@ -58,12 +59,17 @@ function ActionWithModal( { action, item, ActionTrigger } ) { { isModalOpen && ( { setIsModalOpen( false ); } } - overlayClassName="dataviews-action-modal" + overlayClassName={ `dataviews-action-modal dataviews-action-modal__${ kebabCase( + action.id + ) }` } > item.type !== TEMPLATE_PART_POST_TYPE, + modalHeader: __( 'Duplicate pattern' ), + RenderModal: ( { item, closeModal } ) => { + const { categoryId = PATTERN_DEFAULT_CATEGORY } = getQueryArgs( + window.location.href + ); + const isThemePattern = item.type === PATTERN_TYPES.theme; + const history = useHistory(); + function onPatternSuccess( { pattern } ) { + history.push( { + categoryType: PATTERN_TYPES.theme, + categoryId, + postType: PATTERN_TYPES.user, + postId: pattern.id, + } ); + closeModal(); + } + const duplicatedProps = useDuplicatePatternProps( { + pattern: isThemePattern ? item : item.patternPost, + onSuccess: onPatternSuccess, + } ); + return ( + + ); + }, +}; diff --git a/packages/edit-site/src/components/page-patterns/dataviews-patterns.js b/packages/edit-site/src/components/page-patterns/dataviews-patterns.js index ed3555f418d95f..f7e86b8e2e23b1 100644 --- a/packages/edit-site/src/components/page-patterns/dataviews-patterns.js +++ b/packages/edit-site/src/components/page-patterns/dataviews-patterns.js @@ -54,6 +54,7 @@ import { renameAction, resetAction, deleteAction, + duplicatePatternAction, } from './dataviews-pattern-actions'; import usePatternSettings from './use-pattern-settings'; import { unlock } from '../../lock-unlock'; @@ -314,7 +315,13 @@ export default function DataviewsPatterns() { }, [ patterns, view, fields ] ); const actions = useMemo( - () => [ renameAction, exportJSONaction, resetAction, deleteAction ], + () => [ + renameAction, + duplicatePatternAction, + exportJSONaction, + resetAction, + deleteAction, + ], [] ); const onChangeView = useCallback( diff --git a/packages/edit-site/src/components/page-patterns/style.scss b/packages/edit-site/src/components/page-patterns/style.scss index 013dc836e19ad3..cce14e8067122d 100644 --- a/packages/edit-site/src/components/page-patterns/style.scss +++ b/packages/edit-site/src/components/page-patterns/style.scss @@ -255,3 +255,31 @@ z-index: 2; } } + +// TODO: this is duplicated from `patterns-menu-items__convert-modal` styles, +// except for the `z-index`. Need to check if this is still needed. +.dataviews-action-modal__duplicate-pattern { + // Fix the modal width to prevent added categories from stretching the modal. + [role="dialog"] > [role="document"] { + width: 350px; + } + + .patterns-menu-items__convert-modal-categories { + position: relative; + } + + .components-form-token-field__suggestions-list:not(:empty) { + position: absolute; + border: $border-width solid var(--wp-admin-theme-color); + border-bottom-left-radius: $radius-block-ui; + border-bottom-right-radius: $radius-block-ui; + box-shadow: 0 0 0.5px 0.5px var(--wp-admin-theme-color); + box-sizing: border-box; + z-index: 1; + background-color: $white; + width: calc(100% + 2px); // Account for the border width of the token field. + left: -1px; + min-width: initial; + max-height: $grid-unit-60 * 2; // Adjust to not cover the save button, showing three items. + } +} diff --git a/packages/patterns/src/components/create-pattern-modal.js b/packages/patterns/src/components/create-pattern-modal.js index b12e4c9d21bedf..e69390b9997521 100644 --- a/packages/patterns/src/components/create-pattern-modal.js +++ b/packages/patterns/src/components/create-pattern-modal.js @@ -28,11 +28,25 @@ import CategorySelector, { CATEGORY_SLUG } from './category-selector'; import { unlock } from '../lock-unlock'; export default function CreatePatternModal( { + className = 'patterns-menu-items__convert-modal', + modalTitle = __( 'Create pattern' ), + ...restProps +} ) { + return ( + + + + ); +} + +export function CreatePatternModalContents( { confirmLabel = __( 'Create' ), defaultCategories = [], - className = 'patterns-menu-items__convert-modal', content, - modalTitle = __( 'Create pattern' ), onClose, onError, onSuccess, @@ -148,78 +162,68 @@ export default function CreatePatternModal( { return error.data.term_id; } } - return ( - { - onClose(); - setTitle( '' ); +
{ + event.preventDefault(); + onCreate( title, syncType ); } } - overlayClassName={ className } > - { - event.preventDefault(); - onCreate( title, syncType ); - } } - > - - + + + { + setSyncType( + syncType === PATTERN_SYNC_TYPES.full + ? PATTERN_SYNC_TYPES.unsynced + : PATTERN_SYNC_TYPES.full + ); + } } + /> + + + > + { __( 'Cancel' ) } + - - - -
-
+ + + + ); } diff --git a/packages/patterns/src/components/duplicate-pattern-modal.js b/packages/patterns/src/components/duplicate-pattern-modal.js index a62e7306dc90e1..6fa25a16f8594c 100644 --- a/packages/patterns/src/components/duplicate-pattern-modal.js +++ b/packages/patterns/src/components/duplicate-pattern-modal.js @@ -29,11 +29,7 @@ function getTermLabels( pattern, categories ) { .map( ( category ) => category.label ); } -export default function DuplicatePatternModal( { - pattern, - onClose, - onSuccess, -} ) { +export function useDuplicatePatternProps( { pattern, onSuccess } ) { const { createSuccessNotice } = useDispatch( noticesStore ); const categories = useSelect( ( select ) => { const { getUserPatternCategories, getBlockPatternCategories } = @@ -44,12 +40,10 @@ export default function DuplicatePatternModal( { user: getUserPatternCategories(), }; } ); - if ( ! pattern ) { return null; } - - const duplicatedProps = { + return { content: pattern.content, defaultCategories: getTermLabels( pattern, categories ), defaultSyncType: @@ -63,31 +57,39 @@ export default function DuplicatePatternModal( { ? pattern.title : pattern.title.raw ), - }; + onSuccess: ( { pattern: newPattern } ) => { + createSuccessNotice( + sprintf( + // translators: %s: The new pattern's title e.g. 'Call to action (copy)'. + __( '"%s" duplicated.' ), + newPattern.title.raw + ), + { + type: 'snackbar', + id: 'patterns-create', + } + ); - function handleOnSuccess( { pattern: newPattern } ) { - createSuccessNotice( - sprintf( - // translators: %s: The new pattern's title e.g. 'Call to action (copy)'. - __( '"%s" duplicated.' ), - newPattern.title.raw - ), - { - type: 'snackbar', - id: 'patterns-create', - } - ); + onSuccess?.( { pattern: newPattern } ); + }, + }; +} - onSuccess?.( { pattern: newPattern } ); +export default function DuplicatePatternModal( { + pattern, + onClose, + onSuccess, +} ) { + const duplicatedProps = useDuplicatePatternProps( { pattern, onSuccess } ); + if ( ! pattern ) { + return null; } - return ( ); diff --git a/packages/patterns/src/private-apis.js b/packages/patterns/src/private-apis.js index b357efb1bc107a..046e20dd300039 100644 --- a/packages/patterns/src/private-apis.js +++ b/packages/patterns/src/private-apis.js @@ -2,8 +2,14 @@ * Internal dependencies */ import { lock } from './lock-unlock'; -import CreatePatternModal from './components/create-pattern-modal'; -import DuplicatePatternModal from './components/duplicate-pattern-modal'; +import { + default as CreatePatternModal, + CreatePatternModalContents, +} from './components/create-pattern-modal'; +import { + default as DuplicatePatternModal, + useDuplicatePatternProps, +} from './components/duplicate-pattern-modal'; import RenamePatternModal from './components/rename-pattern-modal'; import PatternsMenuItems from './components'; import RenamePatternCategoryModal from './components/rename-pattern-category-modal'; @@ -20,7 +26,9 @@ import { export const privateApis = {}; lock( privateApis, { CreatePatternModal, + CreatePatternModalContents, DuplicatePatternModal, + useDuplicatePatternProps, RenamePatternModal, PatternsMenuItems, RenamePatternCategoryModal,