@wordpress/edit-site 4.10.0 → 4.12.1-next.d6164808d3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/build/components/add-new-template/add-custom-template-modal.js +26 -44
- package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build/components/add-new-template/new-template.js +45 -23
- package/build/components/add-new-template/new-template.js.map +1 -1
- package/build/components/add-new-template/utils.js +493 -242
- package/build/components/add-new-template/utils.js.map +1 -1
- package/build/components/block-editor/index.js +1 -3
- package/build/components/block-editor/index.js.map +1 -1
- package/build/components/block-editor/resizable-editor.js +26 -12
- package/build/components/block-editor/resizable-editor.js.map +1 -1
- package/build/components/global-styles/border-panel.js +3 -3
- package/build/components/global-styles/border-panel.js.map +1 -1
- package/build/components/global-styles/dimensions-panel.js +280 -20
- package/build/components/global-styles/dimensions-panel.js.map +1 -1
- package/build/components/global-styles/hooks.js +4 -4
- package/build/components/global-styles/hooks.js.map +1 -1
- package/build/components/global-styles/screen-color-palette.js +1 -1
- package/build/components/global-styles/screen-color-palette.js.map +1 -1
- package/build/components/global-styles/screen-colors.js +51 -7
- package/build/components/global-styles/screen-colors.js.map +1 -1
- package/build/components/global-styles/screen-heading-color.js +157 -0
- package/build/components/global-styles/screen-heading-color.js.map +1 -0
- package/build/components/global-styles/screen-typography-element.js +4 -0
- package/build/components/global-styles/screen-typography-element.js.map +1 -1
- package/build/components/global-styles/screen-typography.js +5 -0
- package/build/components/global-styles/screen-typography.js.map +1 -1
- package/build/components/global-styles/typography-panel.js +82 -14
- package/build/components/global-styles/typography-panel.js.map +1 -1
- package/build/components/global-styles/typography-utils.js +217 -0
- package/build/components/global-styles/typography-utils.js.map +1 -0
- package/build/components/global-styles/ui.js +11 -0
- package/build/components/global-styles/ui.js.map +1 -1
- package/build/components/global-styles/use-global-styles-output.js +183 -52
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/global-styles/utils.js +85 -5
- package/build/components/global-styles/utils.js.map +1 -1
- package/build/components/header/document-actions/index.js +1 -0
- package/build/components/header/document-actions/index.js.map +1 -1
- package/build/components/header/index.js +27 -12
- package/build/components/header/index.js.map +1 -1
- package/build/components/header/mode-switcher/index.js +0 -4
- package/build/components/header/mode-switcher/index.js.map +1 -1
- package/build/components/header/more-menu/index.js +13 -3
- package/build/components/header/more-menu/index.js.map +1 -1
- package/build/components/header/undo-redo/redo.js +2 -1
- package/build/components/header/undo-redo/redo.js.map +1 -1
- package/build/components/list/actions/index.js +1 -1
- package/build/components/list/actions/index.js.map +1 -1
- package/build/components/save-button/index.js +2 -3
- package/build/components/save-button/index.js.map +1 -1
- package/build/components/sidebar/default-sidebar.js +11 -1
- package/build/components/sidebar/default-sidebar.js.map +1 -1
- package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js +2 -2
- package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
- package/build/components/sidebar/plugin-sidebar/index.js +11 -1
- package/build/components/sidebar/plugin-sidebar/index.js.map +1 -1
- package/build/components/sidebar/template-card/template-actions.js +1 -1
- package/build/components/sidebar/template-card/template-actions.js.map +1 -1
- package/build/components/template-details/edit-template-title.js +1 -1
- package/build/components/template-details/edit-template-title.js.map +1 -1
- package/build/components/template-details/index.js +19 -9
- package/build/components/template-details/index.js.map +1 -1
- package/build/components/template-details/template-areas.js +1 -1
- package/build/components/template-details/template-areas.js.map +1 -1
- package/build/components/template-details/template-part-area-selector.js +47 -0
- package/build/components/template-details/template-part-area-selector.js.map +1 -0
- package/build/components/template-part-converter/convert-to-template-part.js +4 -1
- package/build/components/template-part-converter/convert-to-template-part.js.map +1 -1
- package/build/hooks/index.js +2 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/template-part-edit.js +86 -0
- package/build/hooks/template-part-edit.js.map +1 -0
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build-module/components/add-new-template/add-custom-template-modal.js +27 -45
- package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build-module/components/add-new-template/new-template.js +45 -25
- package/build-module/components/add-new-template/new-template.js.map +1 -1
- package/build-module/components/add-new-template/utils.js +489 -230
- package/build-module/components/add-new-template/utils.js.map +1 -1
- package/build-module/components/block-editor/index.js +1 -2
- package/build-module/components/block-editor/index.js.map +1 -1
- package/build-module/components/block-editor/resizable-editor.js +26 -12
- package/build-module/components/block-editor/resizable-editor.js.map +1 -1
- package/build-module/components/global-styles/border-panel.js +3 -3
- package/build-module/components/global-styles/border-panel.js.map +1 -1
- package/build-module/components/global-styles/dimensions-panel.js +278 -22
- package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
- package/build-module/components/global-styles/hooks.js +4 -4
- package/build-module/components/global-styles/hooks.js.map +1 -1
- package/build-module/components/global-styles/screen-color-palette.js +1 -1
- package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
- package/build-module/components/global-styles/screen-colors.js +51 -7
- package/build-module/components/global-styles/screen-colors.js.map +1 -1
- package/build-module/components/global-styles/screen-heading-color.js +143 -0
- package/build-module/components/global-styles/screen-heading-color.js.map +1 -0
- package/build-module/components/global-styles/screen-typography-element.js +4 -0
- package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
- package/build-module/components/global-styles/screen-typography.js +5 -0
- package/build-module/components/global-styles/screen-typography.js.map +1 -1
- package/build-module/components/global-styles/typography-panel.js +83 -15
- package/build-module/components/global-styles/typography-panel.js.map +1 -1
- package/build-module/components/global-styles/typography-utils.js +204 -0
- package/build-module/components/global-styles/typography-utils.js.map +1 -0
- package/build-module/components/global-styles/ui.js +10 -0
- package/build-module/components/global-styles/ui.js.map +1 -1
- package/build-module/components/global-styles/use-global-styles-output.js +182 -61
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/global-styles/utils.js +82 -5
- package/build-module/components/global-styles/utils.js.map +1 -1
- package/build-module/components/header/document-actions/index.js +1 -0
- package/build-module/components/header/document-actions/index.js.map +1 -1
- package/build-module/components/header/index.js +30 -14
- package/build-module/components/header/index.js.map +1 -1
- package/build-module/components/header/mode-switcher/index.js +0 -4
- package/build-module/components/header/mode-switcher/index.js.map +1 -1
- package/build-module/components/header/more-menu/index.js +13 -3
- package/build-module/components/header/more-menu/index.js.map +1 -1
- package/build-module/components/header/undo-redo/redo.js +3 -2
- package/build-module/components/header/undo-redo/redo.js.map +1 -1
- package/build-module/components/list/actions/index.js +1 -1
- package/build-module/components/list/actions/index.js.map +1 -1
- package/build-module/components/save-button/index.js +3 -4
- package/build-module/components/save-button/index.js.map +1 -1
- package/build-module/components/sidebar/default-sidebar.js +9 -1
- package/build-module/components/sidebar/default-sidebar.js.map +1 -1
- package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js +3 -3
- package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
- package/build-module/components/sidebar/plugin-sidebar/index.js +9 -1
- package/build-module/components/sidebar/plugin-sidebar/index.js.map +1 -1
- package/build-module/components/sidebar/template-card/template-actions.js +1 -1
- package/build-module/components/sidebar/template-card/template-actions.js.map +1 -1
- package/build-module/components/template-details/edit-template-title.js +1 -1
- package/build-module/components/template-details/edit-template-title.js.map +1 -1
- package/build-module/components/template-details/index.js +19 -10
- package/build-module/components/template-details/index.js.map +1 -1
- package/build-module/components/template-details/template-areas.js +1 -1
- package/build-module/components/template-details/template-areas.js.map +1 -1
- package/build-module/components/template-details/template-part-area-selector.js +35 -0
- package/build-module/components/template-details/template-part-area-selector.js.map +1 -0
- package/build-module/components/template-part-converter/convert-to-template-part.js +3 -1
- package/build-module/components/template-part-converter/convert-to-template-part.js.map +1 -1
- package/build-module/hooks/index.js +1 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/template-part-edit.js +67 -0
- package/build-module/hooks/template-part-edit.js.map +1 -0
- package/build-module/index.js +1 -1
- package/build-module/index.js.map +1 -1
- package/build-style/style-rtl.css +40 -33
- package/build-style/style.css +40 -33
- package/package.json +29 -29
- package/src/components/add-new-template/add-custom-template-modal.js +39 -48
- package/src/components/add-new-template/new-template.js +50 -58
- package/src/components/add-new-template/style.scss +20 -8
- package/src/components/add-new-template/utils.js +529 -231
- package/src/components/block-editor/index.js +0 -2
- package/src/components/block-editor/resizable-editor.js +28 -18
- package/src/components/editor/style.scss +1 -0
- package/src/components/global-styles/border-panel.js +3 -3
- package/src/components/global-styles/dimensions-panel.js +344 -45
- package/src/components/global-styles/hooks.js +6 -3
- package/src/components/global-styles/screen-color-palette.js +1 -1
- package/src/components/global-styles/screen-colors.js +46 -4
- package/src/components/global-styles/screen-heading-color.js +201 -0
- package/src/components/global-styles/screen-typography-element.js +4 -0
- package/src/components/global-styles/screen-typography.js +6 -0
- package/src/components/global-styles/style.scss +14 -6
- package/src/components/global-styles/test/typography-utils.js +130 -0
- package/src/components/global-styles/test/use-global-styles-output.js +143 -4
- package/src/components/global-styles/test/utils.js +68 -8
- package/src/components/global-styles/typography-panel.js +119 -48
- package/src/components/global-styles/typography-utils.js +228 -0
- package/src/components/global-styles/ui.js +13 -0
- package/src/components/global-styles/use-global-styles-output.js +203 -53
- package/src/components/global-styles/utils.js +70 -4
- package/src/components/header/document-actions/index.js +3 -0
- package/src/components/header/index.js +41 -14
- package/src/components/header/mode-switcher/index.js +0 -3
- package/src/components/header/more-menu/index.js +7 -2
- package/src/components/header/style.scss +5 -3
- package/src/components/header/undo-redo/redo.js +6 -2
- package/src/components/list/actions/index.js +3 -1
- package/src/components/save-button/index.js +10 -13
- package/src/components/sidebar/default-sidebar.js +12 -0
- package/src/components/sidebar/navigation-menu-sidebar/navigation-menu.js +1 -5
- package/src/components/sidebar/plugin-sidebar/index.js +12 -0
- package/src/components/sidebar/style.scss +4 -0
- package/src/components/sidebar/template-card/template-actions.js +3 -1
- package/src/components/template-details/edit-template-title.js +7 -3
- package/src/components/template-details/index.js +23 -8
- package/src/components/template-details/style.scss +0 -5
- package/src/components/template-details/template-areas.js +3 -1
- package/src/components/template-details/template-part-area-selector.js +38 -0
- package/src/components/template-part-converter/convert-to-template-part.js +3 -1
- package/src/hooks/index.js +1 -0
- package/src/hooks/template-part-edit.js +82 -0
- package/src/index.js +1 -1
- package/src/style.scss +0 -1
- package/build/components/edit-template-part-menu-button/index.js +0 -90
- package/build/components/edit-template-part-menu-button/index.js.map +0 -1
- package/build-module/components/edit-template-part-menu-button/index.js +0 -72
- package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
- package/src/components/edit-template-part-menu-button/index.js +0 -82
|
@@ -10,7 +10,7 @@ import { useSelect } from '@wordpress/data';
|
|
|
10
10
|
import { store as coreStore } from '@wordpress/core-data';
|
|
11
11
|
import { store as editorStore } from '@wordpress/editor';
|
|
12
12
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
13
|
-
import { useMemo } from '@wordpress/element';
|
|
13
|
+
import { useMemo, useCallback } from '@wordpress/element';
|
|
14
14
|
import { __, sprintf } from '@wordpress/i18n';
|
|
15
15
|
import { blockMeta, post } from '@wordpress/icons';
|
|
16
16
|
/**
|
|
@@ -40,73 +40,6 @@ export const mapToIHasNameAndId = (entities, path) => {
|
|
|
40
40
|
* @property {number[]} existingEntitiesIds An array of the existing entities ids.
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {Object} EntityConfig
|
|
45
|
-
* @property {string} entityName The entity's name.
|
|
46
|
-
* @property {Function} getOrderBy Getter for an entity's `orderBy` query parameter, given the object
|
|
47
|
-
* {search} as argument.
|
|
48
|
-
* @property {Function} getIcon Getter function for returning an entity's icon for the menu item.
|
|
49
|
-
* @property {Function} getTitle Getter function for returning an entity's title for the menu item.
|
|
50
|
-
* @property {Function} getDescription Getter function for returning an entity's description for the menu item.
|
|
51
|
-
* @property {string} recordNamePath The path to an entity's properties to use as a `name`. If not provided
|
|
52
|
-
* is assumed that `name` property exists.
|
|
53
|
-
* @property {string} templatePrefix The template prefix to create new templates and check against existing
|
|
54
|
-
* templates. For example custom post types need a `single-` prefix to all
|
|
55
|
-
* templates(`single-post-hello`), whereas `pages` don't (`page-hello`).
|
|
56
|
-
* @property {string} templateSlug If this property is provided, it is going to be used for the creation of
|
|
57
|
-
* new templates and the check against existing templates in the place
|
|
58
|
-
* of the actual entity's `slug`. An example is `Tag` templates where the
|
|
59
|
-
* the Tag's taxonomy slug is `post_tag`, but template hierarchy is based
|
|
60
|
-
* on `tag` alias.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
const taxonomyBaseConfig = {
|
|
64
|
-
entityName: 'taxonomy',
|
|
65
|
-
getOrderBy: _ref => {
|
|
66
|
-
let {
|
|
67
|
-
search
|
|
68
|
-
} = _ref;
|
|
69
|
-
return search ? 'name' : 'count';
|
|
70
|
-
},
|
|
71
|
-
getIcon: () => blockMeta,
|
|
72
|
-
getTitle: labels => sprintf( // translators: %s: Name of the taxonomy e.g: "Cagegory".
|
|
73
|
-
__('Single taxonomy: %s'), labels.singular_name),
|
|
74
|
-
getDescription: labels => sprintf( // translators: %s: Name of the taxonomy e.g: "Product Categories".
|
|
75
|
-
__('Displays a single taxonomy: %s.'), labels.singular_name)
|
|
76
|
-
};
|
|
77
|
-
const postTypeBaseConfig = {
|
|
78
|
-
entityName: 'postType',
|
|
79
|
-
getOrderBy: _ref2 => {
|
|
80
|
-
let {
|
|
81
|
-
search
|
|
82
|
-
} = _ref2;
|
|
83
|
-
return search ? 'relevance' : 'modified';
|
|
84
|
-
},
|
|
85
|
-
recordNamePath: 'title.rendered',
|
|
86
|
-
// `icon` is the `menu_icon` property of a post type. We
|
|
87
|
-
// only handle `dashicons` for now, even if the `menu_icon`
|
|
88
|
-
// also supports urls and svg as values.
|
|
89
|
-
getIcon: _icon => _icon !== null && _icon !== void 0 && _icon.startsWith('dashicons-') ? _icon.slice(10) : post,
|
|
90
|
-
getTitle: labels => sprintf( // translators: %s: Name of the post type e.g: "Post".
|
|
91
|
-
__('Single item: %s'), labels.singular_name),
|
|
92
|
-
getDescription: labels => sprintf( // translators: %s: Name of the post type e.g: "Post".
|
|
93
|
-
__('Displays a single item: %s.'), labels.singular_name)
|
|
94
|
-
};
|
|
95
|
-
export const entitiesConfig = {
|
|
96
|
-
postType: { ...postTypeBaseConfig,
|
|
97
|
-
templatePrefix: 'single-'
|
|
98
|
-
},
|
|
99
|
-
page: { ...postTypeBaseConfig
|
|
100
|
-
},
|
|
101
|
-
taxonomy: { ...taxonomyBaseConfig,
|
|
102
|
-
templatePrefix: 'taxonomy-'
|
|
103
|
-
},
|
|
104
|
-
category: { ...taxonomyBaseConfig
|
|
105
|
-
},
|
|
106
|
-
tag: { ...taxonomyBaseConfig,
|
|
107
|
-
templateSlug: 'tag'
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
43
|
export const useExistingTemplates = () => {
|
|
111
44
|
return useSelect(select => select(coreStore).getEntityRecords('postType', 'wp_template', {
|
|
112
45
|
per_page: -1
|
|
@@ -122,40 +55,14 @@ const usePublicPostTypes = () => {
|
|
|
122
55
|
}), []);
|
|
123
56
|
return useMemo(() => {
|
|
124
57
|
const excludedPostTypes = ['attachment'];
|
|
125
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(
|
|
58
|
+
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref => {
|
|
126
59
|
let {
|
|
127
60
|
viewable,
|
|
128
61
|
slug
|
|
129
|
-
} =
|
|
62
|
+
} = _ref;
|
|
130
63
|
return viewable && !excludedPostTypes.includes(slug);
|
|
131
64
|
});
|
|
132
65
|
}, [postTypes]);
|
|
133
|
-
}; // `page` post type is a special case in the template hierarchy,
|
|
134
|
-
// so we exclude it from the list of post types and we handle it
|
|
135
|
-
// separately.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
export const usePostTypes = () => {
|
|
139
|
-
const postTypes = usePublicPostTypes();
|
|
140
|
-
return useMemo(() => {
|
|
141
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref4 => {
|
|
142
|
-
let {
|
|
143
|
-
slug
|
|
144
|
-
} = _ref4;
|
|
145
|
-
return slug !== 'page';
|
|
146
|
-
});
|
|
147
|
-
}, [postTypes]);
|
|
148
|
-
};
|
|
149
|
-
export const usePostTypePage = () => {
|
|
150
|
-
const postTypes = usePublicPostTypes();
|
|
151
|
-
return useMemo(() => {
|
|
152
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref5 => {
|
|
153
|
-
let {
|
|
154
|
-
slug
|
|
155
|
-
} = _ref5;
|
|
156
|
-
return slug === 'page';
|
|
157
|
-
});
|
|
158
|
-
}, [postTypes]);
|
|
159
66
|
};
|
|
160
67
|
|
|
161
68
|
const usePublicTaxonomies = () => {
|
|
@@ -163,80 +70,463 @@ const usePublicTaxonomies = () => {
|
|
|
163
70
|
per_page: -1
|
|
164
71
|
}), []);
|
|
165
72
|
return useMemo(() => {
|
|
166
|
-
return taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(
|
|
73
|
+
return taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref2 => {
|
|
167
74
|
let {
|
|
168
75
|
visibility
|
|
169
|
-
} =
|
|
76
|
+
} = _ref2;
|
|
170
77
|
return visibility === null || visibility === void 0 ? void 0 : visibility.publicly_queryable;
|
|
171
78
|
});
|
|
172
79
|
}, [taxonomies]);
|
|
173
80
|
};
|
|
174
|
-
/**
|
|
175
|
-
* `category` and `post_tag` are handled specifically in template
|
|
176
|
-
* hierarchy so we need to differentiate them and return the rest,
|
|
177
|
-
* e.g. `category-$slug` and `taxonomy-$taxonomy-$term`.
|
|
178
|
-
*/
|
|
179
81
|
|
|
82
|
+
export const usePostTypeMenuItems = onClickMenuItem => {
|
|
83
|
+
const publicPostTypes = usePublicPostTypes();
|
|
84
|
+
const existingTemplates = useExistingTemplates();
|
|
85
|
+
const defaultTemplateTypes = useDefaultTemplateTypes(); // `page`is a special case in template hierarchy.
|
|
180
86
|
|
|
181
|
-
|
|
182
|
-
const taxonomies = usePublicTaxonomies();
|
|
183
|
-
const specialTaxonomies = ['category', 'post_tag'];
|
|
184
|
-
return useMemo(() => taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref7 => {
|
|
87
|
+
const templatePrefixes = useMemo(() => publicPostTypes === null || publicPostTypes === void 0 ? void 0 : publicPostTypes.reduce((accumulator, _ref3) => {
|
|
185
88
|
let {
|
|
186
89
|
slug
|
|
187
|
-
} =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
90
|
+
} = _ref3;
|
|
91
|
+
let suffix = slug;
|
|
92
|
+
|
|
93
|
+
if (slug !== 'page') {
|
|
94
|
+
suffix = `single-${suffix}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
accumulator[slug] = suffix;
|
|
98
|
+
return accumulator;
|
|
99
|
+
}, {}), [publicPostTypes]); // We need to keep track of naming conflicts. If a conflict
|
|
100
|
+
// occurs, we need to add slug.
|
|
101
|
+
|
|
102
|
+
const postTypeLabels = publicPostTypes === null || publicPostTypes === void 0 ? void 0 : publicPostTypes.reduce((accumulator, _ref4) => {
|
|
103
|
+
let {
|
|
104
|
+
labels
|
|
105
|
+
} = _ref4;
|
|
106
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
107
|
+
accumulator[singularName] = (accumulator[singularName] || 0) + 1;
|
|
108
|
+
return accumulator;
|
|
109
|
+
}, {});
|
|
110
|
+
|
|
111
|
+
const needsUniqueIdentifier = (labels, slug) => {
|
|
112
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
113
|
+
return postTypeLabels[singularName] > 1 && singularName !== slug;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const postTypesInfo = useEntitiesInfo('postType', templatePrefixes);
|
|
117
|
+
const existingTemplateSlugs = (existingTemplates || []).map(_ref5 => {
|
|
194
118
|
let {
|
|
195
119
|
slug
|
|
196
|
-
} =
|
|
197
|
-
return slug
|
|
198
|
-
})
|
|
120
|
+
} = _ref5;
|
|
121
|
+
return slug;
|
|
122
|
+
});
|
|
123
|
+
const menuItems = (publicPostTypes || []).reduce((accumulator, postType) => {
|
|
124
|
+
var _postTypesInfo$slug;
|
|
125
|
+
|
|
126
|
+
const {
|
|
127
|
+
slug,
|
|
128
|
+
labels,
|
|
129
|
+
icon
|
|
130
|
+
} = postType; // We need to check if the general template is part of the
|
|
131
|
+
// defaultTemplateTypes. If it is, just use that info and
|
|
132
|
+
// augment it with the specific template functionality.
|
|
133
|
+
|
|
134
|
+
const generalTemplateSlug = templatePrefixes[slug];
|
|
135
|
+
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref6 => {
|
|
136
|
+
let {
|
|
137
|
+
slug: _slug
|
|
138
|
+
} = _ref6;
|
|
139
|
+
return _slug === generalTemplateSlug;
|
|
140
|
+
});
|
|
141
|
+
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
142
|
+
|
|
143
|
+
const _needsUniqueIdentifier = needsUniqueIdentifier(labels, slug);
|
|
144
|
+
|
|
145
|
+
let menuItemTitle = sprintf( // translators: %s: Name of the post type e.g: "Post".
|
|
146
|
+
__('Single item: %s'), labels.singular_name);
|
|
147
|
+
|
|
148
|
+
if (_needsUniqueIdentifier) {
|
|
149
|
+
menuItemTitle = sprintf( // translators: %1s: Name of the post type e.g: "Post"; %2s: Slug of the post type e.g: "book".
|
|
150
|
+
__('Single item: %1$s (%2$s)'), labels.singular_name, slug);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const menuItem = defaultTemplateType ? { ...defaultTemplateType,
|
|
154
|
+
templatePrefix: templatePrefixes[slug]
|
|
155
|
+
} : {
|
|
156
|
+
slug: generalTemplateSlug,
|
|
157
|
+
title: menuItemTitle,
|
|
158
|
+
description: sprintf( // translators: %s: Name of the post type e.g: "Post".
|
|
159
|
+
__('Displays a single item: %s.'), labels.singular_name),
|
|
160
|
+
// `icon` is the `menu_icon` property of a post type. We
|
|
161
|
+
// only handle `dashicons` for now, even if the `menu_icon`
|
|
162
|
+
// also supports urls and svg as values.
|
|
163
|
+
icon: icon !== null && icon !== void 0 && icon.startsWith('dashicons-') ? icon.slice(10) : post,
|
|
164
|
+
templatePrefix: templatePrefixes[slug]
|
|
165
|
+
};
|
|
166
|
+
const hasEntities = postTypesInfo === null || postTypesInfo === void 0 ? void 0 : (_postTypesInfo$slug = postTypesInfo[slug]) === null || _postTypesInfo$slug === void 0 ? void 0 : _postTypesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
167
|
+
|
|
168
|
+
if (hasEntities) {
|
|
169
|
+
menuItem.onClick = template => {
|
|
170
|
+
onClickMenuItem({
|
|
171
|
+
type: 'postType',
|
|
172
|
+
slug,
|
|
173
|
+
config: {
|
|
174
|
+
recordNamePath: 'title.rendered',
|
|
175
|
+
queryArgs: _ref7 => {
|
|
176
|
+
let {
|
|
177
|
+
search
|
|
178
|
+
} = _ref7;
|
|
179
|
+
return {
|
|
180
|
+
_fields: 'id,title,slug,link',
|
|
181
|
+
orderBy: search ? 'relevance' : 'modified',
|
|
182
|
+
exclude: postTypesInfo[slug].existingEntitiesIds
|
|
183
|
+
};
|
|
184
|
+
},
|
|
185
|
+
getSpecificTemplate: suggestion => {
|
|
186
|
+
let title = sprintf( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the singular name of a post type and %2$s is the name of the post, e.g. "Page: Hello".
|
|
187
|
+
__('%1$s: %2$s'), labels.singular_name, suggestion.name);
|
|
188
|
+
const description = sprintf( // translators: Represents the description of a user's custom template in the Site Editor, e.g. "Template for Page: Hello"
|
|
189
|
+
__('Template for %1$s'), title);
|
|
190
|
+
|
|
191
|
+
if (_needsUniqueIdentifier) {
|
|
192
|
+
title = sprintf( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the template title and %2$s is the slug of the post type, e.g. "Project: Hello (project_type)"
|
|
193
|
+
__('%1$s (%2$s)'), title, slug);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
title,
|
|
198
|
+
description,
|
|
199
|
+
slug: `${templatePrefixes[slug]}-${suggestion.slug}`,
|
|
200
|
+
templatePrefix: templatePrefixes[slug]
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
labels,
|
|
205
|
+
hasGeneralTemplate,
|
|
206
|
+
template
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
} // We don't need to add the menu item if there are no
|
|
210
|
+
// entities and the general template exists.
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
if (!hasGeneralTemplate || hasEntities) {
|
|
214
|
+
accumulator.push(menuItem);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return accumulator;
|
|
218
|
+
}, []); // Split menu items into two groups: one for the default post types
|
|
219
|
+
// and one for the rest.
|
|
220
|
+
|
|
221
|
+
const postTypesMenuItems = useMemo(() => menuItems.reduce((accumulator, postType) => {
|
|
222
|
+
const {
|
|
223
|
+
slug
|
|
224
|
+
} = postType;
|
|
225
|
+
let key = 'postTypesMenuItems';
|
|
226
|
+
|
|
227
|
+
if (slug === 'page') {
|
|
228
|
+
key = 'defaultPostTypesMenuItems';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
accumulator[key].push(postType);
|
|
232
|
+
return accumulator;
|
|
233
|
+
}, {
|
|
234
|
+
defaultPostTypesMenuItems: [],
|
|
235
|
+
postTypesMenuItems: []
|
|
236
|
+
}), [menuItems]);
|
|
237
|
+
return postTypesMenuItems;
|
|
199
238
|
};
|
|
200
|
-
export const
|
|
201
|
-
const
|
|
202
|
-
|
|
239
|
+
export const useTaxonomiesMenuItems = onClickMenuItem => {
|
|
240
|
+
const publicTaxonomies = usePublicTaxonomies();
|
|
241
|
+
const existingTemplates = useExistingTemplates();
|
|
242
|
+
const defaultTemplateTypes = useDefaultTemplateTypes(); // `category` and `post_tag` are special cases in template hierarchy.
|
|
243
|
+
|
|
244
|
+
const templatePrefixes = useMemo(() => publicTaxonomies === null || publicTaxonomies === void 0 ? void 0 : publicTaxonomies.reduce((accumulator, _ref8) => {
|
|
203
245
|
let {
|
|
204
246
|
slug
|
|
247
|
+
} = _ref8;
|
|
248
|
+
let suffix = slug;
|
|
249
|
+
|
|
250
|
+
if (!['category', 'post_tag'].includes(slug)) {
|
|
251
|
+
suffix = `taxonomy-${suffix}`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (slug === 'post_tag') {
|
|
255
|
+
suffix = `tag`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
accumulator[slug] = suffix;
|
|
259
|
+
return accumulator;
|
|
260
|
+
}, {}), [publicTaxonomies]); // We need to keep track of naming conflicts. If a conflict
|
|
261
|
+
// occurs, we need to add slug.
|
|
262
|
+
|
|
263
|
+
const taxonomyLabels = publicTaxonomies === null || publicTaxonomies === void 0 ? void 0 : publicTaxonomies.reduce((accumulator, _ref9) => {
|
|
264
|
+
let {
|
|
265
|
+
labels
|
|
205
266
|
} = _ref9;
|
|
206
|
-
|
|
207
|
-
|
|
267
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
268
|
+
accumulator[singularName] = (accumulator[singularName] || 0) + 1;
|
|
269
|
+
return accumulator;
|
|
270
|
+
}, {});
|
|
271
|
+
|
|
272
|
+
const needsUniqueIdentifier = (labels, slug) => {
|
|
273
|
+
if (['category', 'post_tag'].includes(slug)) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
278
|
+
return taxonomyLabels[singularName] > 1 && singularName !== slug;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const taxonomiesInfo = useEntitiesInfo('taxonomy', templatePrefixes);
|
|
282
|
+
const existingTemplateSlugs = (existingTemplates || []).map(_ref10 => {
|
|
283
|
+
let {
|
|
284
|
+
slug
|
|
285
|
+
} = _ref10;
|
|
286
|
+
return slug;
|
|
287
|
+
});
|
|
288
|
+
const menuItems = (publicTaxonomies || []).reduce((accumulator, taxonomy) => {
|
|
289
|
+
var _taxonomiesInfo$slug;
|
|
290
|
+
|
|
291
|
+
const {
|
|
292
|
+
slug,
|
|
293
|
+
labels
|
|
294
|
+
} = taxonomy; // We need to check if the general template is part of the
|
|
295
|
+
// defaultTemplateTypes. If it is, just use that info and
|
|
296
|
+
// augment it with the specific template functionality.
|
|
297
|
+
|
|
298
|
+
const generalTemplateSlug = templatePrefixes[slug];
|
|
299
|
+
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref11 => {
|
|
300
|
+
let {
|
|
301
|
+
slug: _slug
|
|
302
|
+
} = _ref11;
|
|
303
|
+
return _slug === generalTemplateSlug;
|
|
304
|
+
});
|
|
305
|
+
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
306
|
+
|
|
307
|
+
const _needsUniqueIdentifier = needsUniqueIdentifier(labels, slug);
|
|
308
|
+
|
|
309
|
+
let menuItemTitle = labels.singular_name;
|
|
310
|
+
|
|
311
|
+
if (_needsUniqueIdentifier) {
|
|
312
|
+
menuItemTitle = sprintf( // translators: %1s: Name of the taxonomy e.g: "Category"; %2s: Slug of the taxonomy e.g: "product_cat".
|
|
313
|
+
__('%1$s (%2$s)'), labels.singular_name, slug);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const menuItem = defaultTemplateType ? { ...defaultTemplateType,
|
|
317
|
+
templatePrefix: templatePrefixes[slug]
|
|
318
|
+
} : {
|
|
319
|
+
slug: generalTemplateSlug,
|
|
320
|
+
title: menuItemTitle,
|
|
321
|
+
description: sprintf( // translators: %s: Name of the taxonomy e.g: "Product Categories".
|
|
322
|
+
__('Displays taxonomy: %s.'), labels.singular_name),
|
|
323
|
+
icon: blockMeta,
|
|
324
|
+
templatePrefix: templatePrefixes[slug]
|
|
325
|
+
};
|
|
326
|
+
const hasEntities = taxonomiesInfo === null || taxonomiesInfo === void 0 ? void 0 : (_taxonomiesInfo$slug = taxonomiesInfo[slug]) === null || _taxonomiesInfo$slug === void 0 ? void 0 : _taxonomiesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
327
|
+
|
|
328
|
+
if (hasEntities) {
|
|
329
|
+
menuItem.onClick = template => {
|
|
330
|
+
onClickMenuItem({
|
|
331
|
+
type: 'taxonomy',
|
|
332
|
+
slug,
|
|
333
|
+
config: {
|
|
334
|
+
queryArgs: _ref12 => {
|
|
335
|
+
let {
|
|
336
|
+
search
|
|
337
|
+
} = _ref12;
|
|
338
|
+
return {
|
|
339
|
+
_fields: 'id,name,slug,link',
|
|
340
|
+
orderBy: search ? 'name' : 'count',
|
|
341
|
+
exclude: taxonomiesInfo[slug].existingEntitiesIds
|
|
342
|
+
};
|
|
343
|
+
},
|
|
344
|
+
getSpecificTemplate: suggestion => {
|
|
345
|
+
let title = sprintf( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the singular name of a taxonomy and %2$s is the name of the term, e.g. "Category: shoes".
|
|
346
|
+
__('%1$s: %2$s'), labels.singular_name, suggestion.name);
|
|
347
|
+
const description = sprintf( // translators: Represents the description of a user's custom template in the Site Editor, e.g. "Template for Category: shoes"
|
|
348
|
+
__('Template for %1$s'), title);
|
|
349
|
+
|
|
350
|
+
if (_needsUniqueIdentifier) {
|
|
351
|
+
title = sprintf( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the template title and %2$s is the slug of the taxonomy, e.g. "Category: shoes (product_tag)"
|
|
352
|
+
__('%1$s (%2$s)'), title, slug);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
title,
|
|
357
|
+
description,
|
|
358
|
+
slug: `${templatePrefixes[slug]}-${suggestion.slug}`,
|
|
359
|
+
templatePrefix: templatePrefixes[slug]
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
labels,
|
|
364
|
+
hasGeneralTemplate,
|
|
365
|
+
template
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
} // We don't need to add the menu item if there are no
|
|
369
|
+
// entities and the general template exists.
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
if (!hasGeneralTemplate || hasEntities) {
|
|
373
|
+
accumulator.push(menuItem);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return accumulator;
|
|
377
|
+
}, []); // Split menu items into two groups: one for the default taxonomies
|
|
378
|
+
// and one for the rest.
|
|
379
|
+
|
|
380
|
+
const taxonomiesMenuItems = useMemo(() => menuItems.reduce((accumulator, taxonomy) => {
|
|
381
|
+
const {
|
|
382
|
+
slug
|
|
383
|
+
} = taxonomy;
|
|
384
|
+
let key = 'taxonomiesMenuItems';
|
|
385
|
+
|
|
386
|
+
if (['category', 'tag'].includes(slug)) {
|
|
387
|
+
key = 'defaultTaxonomiesMenuItems';
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
accumulator[key].push(taxonomy);
|
|
391
|
+
return accumulator;
|
|
392
|
+
}, {
|
|
393
|
+
defaultTaxonomiesMenuItems: [],
|
|
394
|
+
taxonomiesMenuItems: []
|
|
395
|
+
}), [menuItems]);
|
|
396
|
+
return taxonomiesMenuItems;
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
function useAuthorNeedsUniqueIndentifier() {
|
|
400
|
+
const authors = useSelect(select => select(coreStore).getUsers({
|
|
401
|
+
who: 'authors',
|
|
402
|
+
per_page: -1
|
|
403
|
+
}), []);
|
|
404
|
+
const authorsCountByName = useMemo(() => {
|
|
405
|
+
return (authors || []).reduce((authorsCount, _ref13) => {
|
|
406
|
+
let {
|
|
407
|
+
name
|
|
408
|
+
} = _ref13;
|
|
409
|
+
authorsCount[name] = (authorsCount[name] || 0) + 1;
|
|
410
|
+
return authorsCount;
|
|
411
|
+
}, {});
|
|
412
|
+
}, [authors]);
|
|
413
|
+
return useCallback(name => {
|
|
414
|
+
return authorsCountByName[name] > 1;
|
|
415
|
+
}, [authorsCountByName]);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const USE_AUTHOR_MENU_ITEM_TEMPLATE_PREFIX = {
|
|
419
|
+
user: 'author'
|
|
420
|
+
};
|
|
421
|
+
const USE_AUTHOR_MENU_ITEM_QUERY_PARAMETERS = {
|
|
422
|
+
user: {
|
|
423
|
+
who: 'authors'
|
|
424
|
+
}
|
|
208
425
|
};
|
|
426
|
+
export function useAuthorMenuItem(onClickMenuItem) {
|
|
427
|
+
var _authorInfo$user, _authorInfo$user2;
|
|
428
|
+
|
|
429
|
+
const existingTemplates = useExistingTemplates();
|
|
430
|
+
const defaultTemplateTypes = useDefaultTemplateTypes();
|
|
431
|
+
const authorInfo = useEntitiesInfo('root', USE_AUTHOR_MENU_ITEM_TEMPLATE_PREFIX, USE_AUTHOR_MENU_ITEM_QUERY_PARAMETERS);
|
|
432
|
+
const authorNeedsUniqueId = useAuthorNeedsUniqueIndentifier();
|
|
433
|
+
let authorMenuItem = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref14 => {
|
|
434
|
+
let {
|
|
435
|
+
slug
|
|
436
|
+
} = _ref14;
|
|
437
|
+
return slug === 'author';
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
if (!authorMenuItem) {
|
|
441
|
+
authorMenuItem = {
|
|
442
|
+
description: __('Displays latest posts written by a single author.'),
|
|
443
|
+
slug: 'author',
|
|
444
|
+
title: 'Author'
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const hasGeneralTemplate = !!(existingTemplates !== null && existingTemplates !== void 0 && existingTemplates.find(_ref15 => {
|
|
449
|
+
let {
|
|
450
|
+
slug
|
|
451
|
+
} = _ref15;
|
|
452
|
+
return slug === 'author';
|
|
453
|
+
}));
|
|
454
|
+
|
|
455
|
+
if ((_authorInfo$user = authorInfo.user) !== null && _authorInfo$user !== void 0 && _authorInfo$user.hasEntities) {
|
|
456
|
+
authorMenuItem = { ...authorMenuItem,
|
|
457
|
+
templatePrefix: 'author'
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
authorMenuItem.onClick = template => {
|
|
461
|
+
onClickMenuItem({
|
|
462
|
+
type: 'root',
|
|
463
|
+
slug: 'user',
|
|
464
|
+
config: {
|
|
465
|
+
queryArgs: _ref16 => {
|
|
466
|
+
let {
|
|
467
|
+
search
|
|
468
|
+
} = _ref16;
|
|
469
|
+
return {
|
|
470
|
+
_fields: 'id,name,slug,link',
|
|
471
|
+
orderBy: search ? 'name' : 'registered_date',
|
|
472
|
+
exclude: authorInfo.user.existingEntitiesIds,
|
|
473
|
+
who: 'authors'
|
|
474
|
+
};
|
|
475
|
+
},
|
|
476
|
+
getSpecificTemplate: suggestion => {
|
|
477
|
+
const needsUniqueId = authorNeedsUniqueId(suggestion.name);
|
|
478
|
+
const title = needsUniqueId ? sprintf( // translators: %1$s: Represents the name of an author e.g: "Jorge", %2$s: Represents the slug of an author e.g: "author-jorge-slug".
|
|
479
|
+
__('Author: %1$s (%2$s)'), suggestion.name, suggestion.slug) : sprintf( // translators: %s: Represents the name of an author e.g: "Jorge".
|
|
480
|
+
__('Author: %s'), suggestion.name);
|
|
481
|
+
const description = sprintf( // translators: %s: Represents the name of an author e.g: "Jorge".
|
|
482
|
+
__('Template for Author: %s'), suggestion.name);
|
|
483
|
+
return {
|
|
484
|
+
title,
|
|
485
|
+
description,
|
|
486
|
+
slug: `author-${suggestion.slug}`,
|
|
487
|
+
templatePrefix: 'author'
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
labels: {
|
|
492
|
+
singular_name: __('Author'),
|
|
493
|
+
search_items: __('Search Authors'),
|
|
494
|
+
not_found: __('No authors found.'),
|
|
495
|
+
all_items: __('All Authors')
|
|
496
|
+
},
|
|
497
|
+
hasGeneralTemplate,
|
|
498
|
+
template
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (!hasGeneralTemplate || (_authorInfo$user2 = authorInfo.user) !== null && _authorInfo$user2 !== void 0 && _authorInfo$user2.hasEntities) {
|
|
504
|
+
return authorMenuItem;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
209
507
|
/**
|
|
210
|
-
* Helper hook that
|
|
211
|
-
*
|
|
508
|
+
* Helper hook that filters all the existing templates by the given
|
|
509
|
+
* object with the entity's slug as key and the template prefix as value.
|
|
212
510
|
*
|
|
213
|
-
*
|
|
214
|
-
* `
|
|
511
|
+
* Example:
|
|
512
|
+
* `existingTemplates` is: [ { slug: 'tag-apple' }, { slug: 'page-about' }, { slug: 'tag' } ]
|
|
513
|
+
* `templatePrefixes` is: { post_tag: 'tag' }
|
|
514
|
+
* It will return: { post_tag: ['apple'] }
|
|
215
515
|
*
|
|
216
|
-
*
|
|
217
|
-
* to query afterwards for any remaing record, by excluding them.
|
|
516
|
+
* Note: We append the `-` to the given template prefix in this function for our checks.
|
|
218
517
|
*
|
|
219
|
-
* @param {string
|
|
220
|
-
* @
|
|
221
|
-
* @param {EntityConfig} entityConfig The entity config.
|
|
222
|
-
* @return {Record<string,EntitiesInfo>} An object with the `entities.slug` as `keys` and EntitiesInfo as values.
|
|
518
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
519
|
+
* @return {Record<string,string[]>} An object with the entity's slug as key and an array with the existing template slugs as value.
|
|
223
520
|
*/
|
|
224
521
|
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
} = _ref10;
|
|
231
|
-
const slugsToExcludePerEntity = useMemo(() => {
|
|
232
|
-
return entities === null || entities === void 0 ? void 0 : entities.reduce((accumulator, entity) => {
|
|
233
|
-
let _prefix = `${templateSlug || entity.slug}-`;
|
|
234
|
-
|
|
235
|
-
if (templatePrefix) {
|
|
236
|
-
_prefix = templatePrefix + _prefix;
|
|
237
|
-
}
|
|
238
|
-
|
|
522
|
+
const useExistingTemplateSlugs = templatePrefixes => {
|
|
523
|
+
const existingTemplates = useExistingTemplates();
|
|
524
|
+
const existingSlugs = useMemo(() => {
|
|
525
|
+
return Object.entries(templatePrefixes || {}).reduce((accumulator, _ref17) => {
|
|
526
|
+
let [slug, prefix] = _ref17;
|
|
239
527
|
const slugsWithTemplates = (existingTemplates || []).reduce((_accumulator, existingTemplate) => {
|
|
528
|
+
const _prefix = `${prefix}-`;
|
|
529
|
+
|
|
240
530
|
if (existingTemplate.slug.startsWith(_prefix)) {
|
|
241
531
|
_accumulator.push(existingTemplate.slug.substring(_prefix.length));
|
|
242
532
|
}
|
|
@@ -245,43 +535,75 @@ const useEntitiesInfo = (existingTemplates, entities, _ref10) => {
|
|
|
245
535
|
}, []);
|
|
246
536
|
|
|
247
537
|
if (slugsWithTemplates.length) {
|
|
248
|
-
accumulator[
|
|
538
|
+
accumulator[slug] = slugsWithTemplates;
|
|
249
539
|
}
|
|
250
540
|
|
|
251
541
|
return accumulator;
|
|
252
542
|
}, {});
|
|
253
|
-
}, [
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
543
|
+
}, [templatePrefixes, existingTemplates]);
|
|
544
|
+
return existingSlugs;
|
|
545
|
+
};
|
|
546
|
+
/**
|
|
547
|
+
* Helper hook that finds the existing records with an associated template,
|
|
548
|
+
* as they need to be excluded from the template suggestions.
|
|
549
|
+
*
|
|
550
|
+
* @param {string} entityName The entity's name.
|
|
551
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
552
|
+
* @param {Record<string,Object>} additionalQueryParameters An object with the entity's slug as key and additional query parameters as value.
|
|
553
|
+
* @return {Record<string,EntitiesInfo>} An object with the entity's slug as key and the existing records as value.
|
|
554
|
+
*/
|
|
555
|
+
|
|
258
556
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
557
|
+
const useTemplatesToExclude = function (entityName, templatePrefixes) {
|
|
558
|
+
let additionalQueryParameters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
559
|
+
const slugsToExcludePerEntity = useExistingTemplateSlugs(templatePrefixes);
|
|
560
|
+
const recordsToExcludePerEntity = useSelect(select => {
|
|
561
|
+
return Object.entries(slugsToExcludePerEntity || {}).reduce((accumulator, _ref18) => {
|
|
562
|
+
let [slug, slugsWithTemplates] = _ref18;
|
|
563
|
+
const entitiesWithTemplates = select(coreStore).getEntityRecords(entityName, slug, {
|
|
262
564
|
_fields: 'id',
|
|
263
565
|
context: 'view',
|
|
264
|
-
slug: slugsWithTemplates
|
|
566
|
+
slug: slugsWithTemplates,
|
|
567
|
+
...additionalQueryParameters[slug]
|
|
265
568
|
});
|
|
266
569
|
|
|
267
|
-
if (
|
|
268
|
-
accumulator[slug] =
|
|
570
|
+
if (entitiesWithTemplates !== null && entitiesWithTemplates !== void 0 && entitiesWithTemplates.length) {
|
|
571
|
+
accumulator[slug] = entitiesWithTemplates;
|
|
269
572
|
}
|
|
270
573
|
|
|
271
574
|
return accumulator;
|
|
272
575
|
}, {});
|
|
273
576
|
}, [slugsToExcludePerEntity]);
|
|
577
|
+
return recordsToExcludePerEntity;
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
580
|
+
* Helper hook that returns information about an entity having
|
|
581
|
+
* records that we can create a specific template for.
|
|
582
|
+
*
|
|
583
|
+
* For example we can search for `terms` in `taxonomy` entity or
|
|
584
|
+
* `posts` in `postType` entity.
|
|
585
|
+
*
|
|
586
|
+
* First we need to find the existing records with an associated template,
|
|
587
|
+
* to query afterwards for any remaining record, by excluding them.
|
|
588
|
+
*
|
|
589
|
+
* @param {string} entityName The entity's name.
|
|
590
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
591
|
+
* @param {Record<string,Object>} additionalQueryParameters An object with the entity's slug as key and additional query parameters as value.
|
|
592
|
+
* @return {Record<string,EntitiesInfo>} An object with the entity's slug as key and the EntitiesInfo as value.
|
|
593
|
+
*/
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
const useEntitiesInfo = function (entityName, templatePrefixes) {
|
|
597
|
+
let additionalQueryParameters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
598
|
+
const recordsToExcludePerEntity = useTemplatesToExclude(entityName, templatePrefixes, additionalQueryParameters);
|
|
274
599
|
const entitiesInfo = useSelect(select => {
|
|
275
|
-
return
|
|
600
|
+
return Object.keys(templatePrefixes || {}).reduce((accumulator, slug) => {
|
|
276
601
|
var _recordsToExcludePerE, _select$getEntityReco;
|
|
277
602
|
|
|
278
|
-
|
|
279
|
-
slug
|
|
280
|
-
} = _ref12;
|
|
281
|
-
const existingEntitiesIds = (recordsToExcludePerEntity === null || recordsToExcludePerEntity === void 0 ? void 0 : (_recordsToExcludePerE = recordsToExcludePerEntity[slug]) === null || _recordsToExcludePerE === void 0 ? void 0 : _recordsToExcludePerE.map(_ref13 => {
|
|
603
|
+
const existingEntitiesIds = (recordsToExcludePerEntity === null || recordsToExcludePerEntity === void 0 ? void 0 : (_recordsToExcludePerE = recordsToExcludePerEntity[slug]) === null || _recordsToExcludePerE === void 0 ? void 0 : _recordsToExcludePerE.map(_ref19 => {
|
|
282
604
|
let {
|
|
283
605
|
id
|
|
284
|
-
} =
|
|
606
|
+
} = _ref19;
|
|
285
607
|
return id;
|
|
286
608
|
})) || [];
|
|
287
609
|
accumulator[slug] = {
|
|
@@ -289,77 +611,14 @@ const useEntitiesInfo = (existingTemplates, entities, _ref10) => {
|
|
|
289
611
|
per_page: 1,
|
|
290
612
|
_fields: 'id',
|
|
291
613
|
context: 'view',
|
|
292
|
-
exclude: existingEntitiesIds
|
|
614
|
+
exclude: existingEntitiesIds,
|
|
615
|
+
...additionalQueryParameters[slug]
|
|
293
616
|
})) !== null && _select$getEntityReco !== void 0 && _select$getEntityReco.length),
|
|
294
617
|
existingEntitiesIds
|
|
295
618
|
};
|
|
296
619
|
return accumulator;
|
|
297
620
|
}, {});
|
|
298
|
-
}, [
|
|
621
|
+
}, [templatePrefixes, recordsToExcludePerEntity]);
|
|
299
622
|
return entitiesInfo;
|
|
300
623
|
};
|
|
301
|
-
|
|
302
|
-
export const useExtraTemplates = (entities, entityConfig, onClickMenuItem) => {
|
|
303
|
-
const existingTemplates = useExistingTemplates();
|
|
304
|
-
const defaultTemplateTypes = useDefaultTemplateTypes();
|
|
305
|
-
const entitiesInfo = useEntitiesInfo(existingTemplates, entities, entityConfig);
|
|
306
|
-
const existingTemplateSlugs = (existingTemplates || []).map(_ref14 => {
|
|
307
|
-
let {
|
|
308
|
-
slug
|
|
309
|
-
} = _ref14;
|
|
310
|
-
return slug;
|
|
311
|
-
});
|
|
312
|
-
const extraTemplates = (entities || []).reduce((accumulator, entity) => {
|
|
313
|
-
var _entityConfig$getIcon, _entitiesInfo$slug;
|
|
314
|
-
|
|
315
|
-
const {
|
|
316
|
-
slug,
|
|
317
|
-
labels,
|
|
318
|
-
icon
|
|
319
|
-
} = entity;
|
|
320
|
-
const slugForGeneralTemplate = entityConfig.templateSlug || slug; // We need to check if the general template is part of the
|
|
321
|
-
// defaultTemplateTypes. If it is, just use that info and
|
|
322
|
-
// augment it with the specific template functionality.
|
|
323
|
-
|
|
324
|
-
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref15 => {
|
|
325
|
-
let {
|
|
326
|
-
slug: _slug
|
|
327
|
-
} = _ref15;
|
|
328
|
-
return _slug === slugForGeneralTemplate;
|
|
329
|
-
});
|
|
330
|
-
const generalTemplateSlug = (defaultTemplateType === null || defaultTemplateType === void 0 ? void 0 : defaultTemplateType.slug) || `${entityConfig.templatePrefix}${slug}`;
|
|
331
|
-
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
332
|
-
const menuItem = defaultTemplateType ? { ...defaultTemplateType
|
|
333
|
-
} : {
|
|
334
|
-
slug: generalTemplateSlug,
|
|
335
|
-
title: entityConfig.getTitle(labels),
|
|
336
|
-
description: entityConfig.getDescription(labels),
|
|
337
|
-
icon: (_entityConfig$getIcon = entityConfig.getIcon) === null || _entityConfig$getIcon === void 0 ? void 0 : _entityConfig$getIcon.call(entityConfig, icon)
|
|
338
|
-
};
|
|
339
|
-
const hasEntities = entitiesInfo === null || entitiesInfo === void 0 ? void 0 : (_entitiesInfo$slug = entitiesInfo[slug]) === null || _entitiesInfo$slug === void 0 ? void 0 : _entitiesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
340
|
-
|
|
341
|
-
if (hasEntities) {
|
|
342
|
-
menuItem.onClick = template => {
|
|
343
|
-
onClickMenuItem({
|
|
344
|
-
type: entityConfig.entityName,
|
|
345
|
-
slug,
|
|
346
|
-
config: entityConfig,
|
|
347
|
-
labels,
|
|
348
|
-
hasGeneralTemplate,
|
|
349
|
-
template,
|
|
350
|
-
postsToExclude: entitiesInfo[slug].existingEntitiesIds
|
|
351
|
-
});
|
|
352
|
-
};
|
|
353
|
-
} // We don't need to add the menu item if there are no
|
|
354
|
-
// entities and the general template exists.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (!hasGeneralTemplate || hasEntities) {
|
|
358
|
-
accumulator.push(menuItem);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return accumulator;
|
|
362
|
-
}, []);
|
|
363
|
-
return extraTemplates;
|
|
364
|
-
};
|
|
365
624
|
//# sourceMappingURL=utils.js.map
|