375 lines
9.8 KiB
TypeScript
375 lines
9.8 KiB
TypeScript
/**
|
|
* External dependencies
|
|
*/
|
|
import { createRegistrySelector, createSelector } from '@wordpress/data';
|
|
import { store as coreDataStore } from '@wordpress/core-data';
|
|
import { store as interfaceStore } from '@wordpress/interface';
|
|
import { store as editorStore } from '@wordpress/editor';
|
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
import { serialize, parse } from '@wordpress/blocks';
|
|
import { BlockInstance } from '@wordpress/blocks/index';
|
|
import { Post } from '@wordpress/core-data/build-types/entity-types/post';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { storeName, editorCurrentPostType } from './constants';
|
|
import { State, Feature, EmailTemplate, EmailEditorPostType } from './types';
|
|
|
|
function getContentFromEntity( entity ): string {
|
|
if ( entity?.content && typeof entity.content === 'function' ) {
|
|
return entity.content( entity ) as string;
|
|
}
|
|
if ( entity?.blocks ) {
|
|
return serialize( entity.blocks );
|
|
}
|
|
if ( entity?.content ) {
|
|
return entity.content as string;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
const patternsWithParsedBlocks = new WeakMap();
|
|
function enhancePatternWithParsedBlocks( pattern ) {
|
|
let enhancedPattern = patternsWithParsedBlocks.get( pattern );
|
|
if ( ! enhancedPattern ) {
|
|
enhancedPattern = {
|
|
...pattern,
|
|
get blocks() {
|
|
return parse( pattern.content );
|
|
},
|
|
};
|
|
patternsWithParsedBlocks.set( pattern, enhancedPattern );
|
|
}
|
|
return enhancedPattern;
|
|
}
|
|
|
|
export const isFeatureActive = createRegistrySelector(
|
|
( select ) =>
|
|
( _, feature: Feature ): boolean =>
|
|
!! select( preferencesStore ).get( storeName, feature )
|
|
);
|
|
|
|
export const isSidebarOpened = createRegistrySelector(
|
|
( select ) => (): boolean =>
|
|
!! select( interfaceStore ).getActiveComplementaryArea( storeName )
|
|
);
|
|
|
|
export const hasEdits = createRegistrySelector( ( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
return !! select( coreDataStore ).hasEditsForEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
} );
|
|
|
|
export const isEmailLoaded = createRegistrySelector(
|
|
( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
return !! select( coreDataStore ).getEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
}
|
|
);
|
|
|
|
export const isSaving = createRegistrySelector( ( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
return !! select( coreDataStore ).isSavingEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
} );
|
|
|
|
export const isEmpty = createRegistrySelector( ( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
|
|
const post: EmailEditorPostType = select( coreDataStore ).getEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
if ( ! post ) {
|
|
return true;
|
|
}
|
|
|
|
const { content, mailpoet_data: mailpoetData, title } = post;
|
|
return (
|
|
! content.raw &&
|
|
! mailpoetData.subject &&
|
|
! mailpoetData.preheader &&
|
|
! title.raw
|
|
);
|
|
} );
|
|
|
|
export const hasEmptyContent = createRegistrySelector(
|
|
( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
|
|
const post = select( coreDataStore ).getEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
if ( ! post ) {
|
|
return true;
|
|
}
|
|
|
|
// @ts-expect-error Missing property in type
|
|
const { content } = post;
|
|
return ! content.raw;
|
|
}
|
|
);
|
|
|
|
export const isEmailSent = createRegistrySelector(
|
|
( select ) => (): boolean => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
|
|
const post = select( coreDataStore ).getEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
);
|
|
if ( ! post ) {
|
|
return false;
|
|
}
|
|
|
|
// @ts-expect-error Missing property in type
|
|
const status = post.status;
|
|
return status === 'sent';
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Returns the content of the email being edited.
|
|
*
|
|
* @param {Object} state Global application state.
|
|
* @return {string} Post content.
|
|
*/
|
|
export const getEditedEmailContent = createRegistrySelector(
|
|
( select ) => (): string => {
|
|
const postId = select( storeName ).getEmailPostId();
|
|
const record = select( coreDataStore ).getEditedEntityRecord(
|
|
'postType',
|
|
editorCurrentPostType,
|
|
postId
|
|
) as unknown as
|
|
| { content: string | unknown; blocks: BlockInstance[] }
|
|
| undefined;
|
|
|
|
if ( record ) {
|
|
return getContentFromEntity( record );
|
|
}
|
|
return '';
|
|
}
|
|
);
|
|
|
|
export const getSentEmailEditorPosts = createRegistrySelector(
|
|
( select ) => () =>
|
|
select( coreDataStore )
|
|
.getEntityRecords( 'postType', editorCurrentPostType, {
|
|
per_page: 30, // show a maximum of 30 for now
|
|
status: 'publish,sent', // show only sent emails
|
|
} )
|
|
?.filter(
|
|
( post: EmailEditorPostType ) => post?.content?.raw !== '' // filter out empty content
|
|
) || []
|
|
);
|
|
|
|
export const getBlockPatternsForEmailTemplate = createRegistrySelector(
|
|
( select ) =>
|
|
createSelector(
|
|
() =>
|
|
select( coreDataStore )
|
|
.getBlockPatterns()
|
|
.filter(
|
|
( { templateTypes } ) =>
|
|
Array.isArray( templateTypes ) &&
|
|
templateTypes.includes( 'email-template' )
|
|
)
|
|
.map( enhancePatternWithParsedBlocks ),
|
|
() => [ select( coreDataStore ).getBlockPatterns() ]
|
|
)
|
|
);
|
|
|
|
/**
|
|
* COPIED FROM https://github.com/WordPress/gutenberg/blob/9c6d4fe59763b188d27ad937c2f0daa39e4d9341/packages/edit-post/src/store/selectors.js
|
|
* Retrieves the template of the currently edited post.
|
|
*
|
|
* @return {Object?} Post Template.
|
|
*/
|
|
export const getEditedPostTemplate = createRegistrySelector(
|
|
( select ) => (): EmailTemplate => {
|
|
const currentTemplate =
|
|
// @ts-expect-error Expected 0 arguments, but got 1.
|
|
select( editorStore ).getEditedPostAttribute( 'template' );
|
|
|
|
if ( currentTemplate ) {
|
|
const templateWithSameSlug = select( coreDataStore )
|
|
.getEntityRecords( 'postType', 'wp_template', { per_page: -1 } )
|
|
// @ts-expect-error Missing property in type
|
|
?.find( ( template ) => template.slug === currentTemplate );
|
|
|
|
if ( ! templateWithSameSlug ) {
|
|
return templateWithSameSlug as EmailTemplate;
|
|
}
|
|
|
|
return select( coreDataStore ).getEditedEntityRecord(
|
|
'postType',
|
|
'wp_template',
|
|
|
|
// @ts-expect-error getEditedPostAttribute
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
templateWithSameSlug.id
|
|
) as unknown as EmailTemplate;
|
|
}
|
|
|
|
const defaultTemplateId = select( coreDataStore ).getDefaultTemplateId(
|
|
{
|
|
slug: 'email-general',
|
|
}
|
|
);
|
|
|
|
return select( coreDataStore ).getEditedEntityRecord(
|
|
'postType',
|
|
'wp_template',
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
defaultTemplateId
|
|
) as unknown as EmailTemplate;
|
|
}
|
|
);
|
|
|
|
export const getCurrentTemplate = createRegistrySelector( ( select ) => () => {
|
|
const isEditingTemplate =
|
|
select( editorStore ).getCurrentPostType() === 'wp_template';
|
|
|
|
if ( isEditingTemplate ) {
|
|
const templateId = select( editorStore ).getCurrentPostId();
|
|
|
|
return select( coreDataStore ).getEditedEntityRecord(
|
|
'postType',
|
|
'wp_template',
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
templateId
|
|
) as unknown as EmailTemplate;
|
|
}
|
|
return getEditedPostTemplate();
|
|
} );
|
|
|
|
export const getCurrentTemplateContent = () => {
|
|
const template = getCurrentTemplate();
|
|
if ( template ) {
|
|
return getContentFromEntity( template );
|
|
}
|
|
return '';
|
|
};
|
|
|
|
export const getGlobalEmailStylesPost = createRegistrySelector(
|
|
( select ) => () => {
|
|
const postId = select( storeName ).getGlobalStylesPostId();
|
|
|
|
if ( postId ) {
|
|
return select( coreDataStore ).getEditedEntityRecord(
|
|
'postType',
|
|
'wp_global_styles',
|
|
postId
|
|
) as unknown as Post;
|
|
}
|
|
return getEditedPostTemplate();
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Retrieves the email templates.
|
|
*/
|
|
export const getEmailTemplates = createRegistrySelector(
|
|
( select ) => () =>
|
|
select( coreDataStore )
|
|
.getEntityRecords( 'postType', 'wp_template', {
|
|
per_page: -1,
|
|
post_type: editorCurrentPostType,
|
|
} )
|
|
// We still need to filter the templates because, in some cases, the API also returns custom templates
|
|
// ignoring the post_type filter in the query
|
|
?.filter( ( template ) =>
|
|
// @ts-expect-error Missing property in type
|
|
template.post_types.includes( editorCurrentPostType )
|
|
)
|
|
);
|
|
|
|
export function getEmailPostId( state: State ): number {
|
|
return state.postId;
|
|
}
|
|
|
|
export function getSettingsSidebarActiveTab( state: State ): string {
|
|
return state.settingsSidebar.activeTab;
|
|
}
|
|
|
|
export function getInitialEditorSettings(
|
|
state: State
|
|
): State[ 'editorSettings' ] {
|
|
return state.editorSettings;
|
|
}
|
|
|
|
export function getPaletteColors(
|
|
state: State
|
|
): State[ 'editorSettings' ][ '__experimentalFeatures' ][ 'color' ][ 'palette' ] {
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
return state.editorSettings.__experimentalFeatures.color.palette;
|
|
}
|
|
|
|
export function getPreviewState( state: State ): State[ 'preview' ] {
|
|
return state.preview;
|
|
}
|
|
|
|
export function getPersonalizationTagsState(
|
|
state: State
|
|
): State[ 'personalizationTags' ] {
|
|
return state.personalizationTags;
|
|
}
|
|
|
|
export function getPersonalizationTagsList(
|
|
state: State
|
|
): State[ 'personalizationTags' ][ 'list' ] {
|
|
return state.personalizationTags.list;
|
|
}
|
|
|
|
export const getDeviceType = createRegistrySelector(
|
|
( select ) => () =>
|
|
// @ts-expect-error getDeviceType is missing in types.
|
|
select( editorStore ).getDeviceType() as string
|
|
);
|
|
|
|
export function getStyles( state: State ): State[ 'theme' ][ 'styles' ] {
|
|
return state.theme.styles;
|
|
}
|
|
|
|
export function getAutosaveInterval(
|
|
state: State
|
|
): State[ 'autosaveInterval' ] {
|
|
return state.autosaveInterval;
|
|
}
|
|
|
|
export function getCdnUrl( state: State ): State[ 'cdnUrl' ] {
|
|
return state.cdnUrl;
|
|
}
|
|
|
|
export function isPremiumPluginActive( state: State ): boolean {
|
|
return state.isPremiumPluginActive;
|
|
}
|
|
|
|
export function getTheme( state: State ): State[ 'theme' ] {
|
|
return state.theme;
|
|
}
|
|
|
|
export function getGlobalStylesPostId( state: State ): number | null {
|
|
return state.styles.globalStylesPostId;
|
|
}
|
|
|
|
export function getUrls( state: State ): State[ 'urls' ] {
|
|
return state.urls;
|
|
}
|