2023-08-28 01:28:05 +00:00
/* eslint-disable @woocommerce/dependency-group */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/ * *
* External dependencies
* /
// @ts-ignore No types for this exist yet.
2023-09-22 06:27:22 +00:00
import { store as blockEditorStore } from '@wordpress/block-editor' ;
// @ts-ignore No types for this exist yet.
2023-09-14 08:24:46 +00:00
import { useEntityRecords } from '@wordpress/core-data' ;
2023-09-22 06:27:22 +00:00
import { select } from '@wordpress/data' ;
2023-08-28 01:28:05 +00:00
// @ts-ignore No types for this exist yet.
import { privateApis as routerPrivateApis } from '@wordpress/router' ;
// @ts-ignore No types for this exist yet.
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock' ;
// @ts-ignore No types for this exist yet.
import useSiteEditorSettings from '@wordpress/edit-site/build-module/components/block-editor/use-site-editor-settings' ;
2023-09-14 08:24:46 +00:00
2023-08-28 01:28:05 +00:00
/ * *
* Internal dependencies
* /
import BlockPreview from './block-preview' ;
2023-09-05 06:21:19 +00:00
import { useCallback } from '@wordpress/element' ;
2023-09-14 08:24:46 +00:00
import { useEditorBlocks } from './hooks/use-editor-blocks' ;
2023-09-18 09:29:29 +00:00
import { useScrollOpacity } from './hooks/use-scroll-opacity' ;
import { useQuery } from '@woocommerce/navigation' ;
2023-08-28 01:28:05 +00:00
2023-09-18 09:29:29 +00:00
const { useHistory } = unlock ( routerPrivateApis ) ;
2023-08-28 01:28:05 +00:00
type Page = {
link : string ;
title : { rendered : string ; raw : string } ;
[ key : string ] : unknown ;
} ;
2023-09-22 06:27:22 +00:00
const findPageIdByLinkOrTitle = ( event : MouseEvent , _pages : Page [ ] ) = > {
const target = event . target as HTMLAnchorElement ;
const clickedPage =
_pages . find ( ( page ) = > page . link === target . href ) ||
_pages . find ( ( page ) = > page . title . rendered === target . innerText ) ;
return clickedPage ? clickedPage.id : null ;
} ;
const findPageIdByBlockClientId = ( event : MouseEvent ) = > {
const navLink = ( event . target as HTMLAnchorElement ) . closest (
'.wp-block-navigation-link'
) ;
if ( navLink ) {
const blockClientId = navLink . getAttribute ( 'data-block' ) ;
const navLinkBlocks =
// @ts-ignore No types for this exist yet.
select ( blockEditorStore ) . getBlocksByClientId ( blockClientId ) ;
if ( navLinkBlocks && navLinkBlocks . length ) {
return navLinkBlocks [ 0 ] . attributes . id ;
}
}
return null ;
} ;
2023-08-28 01:28:05 +00:00
// We only show the edit option when page count is <= MAX_PAGE_COUNT
// Performance of Navigation Links is not good past this value.
const MAX_PAGE_COUNT = 100 ;
export const BlockEditor = ( { } ) = > {
const history = useHistory ( ) ;
const settings = useSiteEditorSettings ( ) ;
2023-09-14 08:24:46 +00:00
const [ blocks ] = useEditorBlocks ( ) ;
2023-09-18 09:29:29 +00:00
const urlParams = useQuery ( ) ;
const scrollDirection =
urlParams . path === '/customize-store/assembler-hub/footer'
? 'bottomUp'
: 'topDown' ;
const previewOpacity = useScrollOpacity (
2023-09-19 05:54:19 +00:00
'.woocommerce-customize-store__block-editor iframe' ,
2023-09-18 09:29:29 +00:00
scrollDirection
) ;
2023-08-28 01:28:05 +00:00
// // See packages/block-library/src/page-list/edit.js.
const { records : pages } = useEntityRecords ( 'postType' , 'page' , {
per_page : MAX_PAGE_COUNT ,
_fields : [ 'id' , 'link' , 'menu_order' , 'parent' , 'title' , 'type' ] ,
// TODO: When https://core.trac.wordpress.org/ticket/39037 REST API support for multiple orderby
// values is resolved, update 'orderby' to [ 'menu_order', 'post_title' ] to provide a consistent
// sort.
orderby : 'menu_order' ,
order : 'asc' ,
} ) ;
2023-09-05 06:21:19 +00:00
const onClickNavigationItem = useCallback (
( event : MouseEvent ) = > {
2023-09-22 06:27:22 +00:00
// If the user clicks on a navigation item, we want to update the URL to reflect the page they are on.
// Because of bug in the block library (See https://github.com/woocommerce/team-ghidorah/issues/253#issuecomment-1665106817), we're not able to use href link to find the page ID. Instead, we'll use the link/title first, and if that doesn't work, we'll use the block client ID. It depends on the header block type to determine which one to use.
// This is a temporary solution until the block library is fixed.
const pageId =
findPageIdByLinkOrTitle ( event , pages ) ||
findPageIdByBlockClientId ( event ) ;
if ( pageId ) {
2023-09-05 06:21:19 +00:00
history . push ( {
2023-09-18 09:29:29 +00:00
. . . urlParams ,
2023-09-22 06:27:22 +00:00
postId : pageId ,
2023-09-05 06:21:19 +00:00
postType : 'page' ,
} ) ;
2023-09-22 06:27:22 +00:00
return ;
2023-09-05 06:21:19 +00:00
}
2023-09-22 06:27:22 +00:00
// Home page
const { postId , postType , . . . params } = urlParams ;
history . push ( {
. . . params ,
} ) ;
2023-09-05 06:21:19 +00:00
} ,
2023-09-18 09:29:29 +00:00
[ history , urlParams , pages ]
2023-09-05 06:21:19 +00:00
) ;
2023-08-28 01:28:05 +00:00
2023-09-05 06:21:19 +00:00
return (
< div className = "woocommerce-customize-store__block-editor" >
< div className = { 'woocommerce-block-preview-container' } >
< BlockPreview
blocks = { blocks }
settings = { settings }
additionalStyles = { '' }
2023-09-29 03:38:25 +00:00
isNavigable = { false }
2023-09-05 06:21:19 +00:00
onClickNavigationItem = { onClickNavigationItem }
// Don't use sub registry so that we can get the logo block from the main registry on the logo sidebar navigation screen component.
useSubRegistry = { false }
2023-09-18 09:29:29 +00:00
previewOpacity = { previewOpacity }
2023-09-05 06:21:19 +00:00
/ >
< / div >
2023-08-28 01:28:05 +00:00
< / div >
) ;
} ;