@wordpress/edit-site 4.9.0 → 4.12.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.
Files changed (199) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/add-new-template/add-custom-generic-template-modal.js +84 -0
  3. package/build/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  4. package/build/components/add-new-template/add-custom-template-modal.js +82 -61
  5. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
  6. package/build/components/add-new-template/new-template.js +94 -81
  7. package/build/components/add-new-template/new-template.js.map +1 -1
  8. package/build/components/add-new-template/utils.js +574 -57
  9. package/build/components/add-new-template/utils.js.map +1 -1
  10. package/build/components/block-editor/index.js +1 -3
  11. package/build/components/block-editor/index.js.map +1 -1
  12. package/build/components/code-editor/index.js +17 -4
  13. package/build/components/code-editor/index.js.map +1 -1
  14. package/build/components/editor/index.js +16 -0
  15. package/build/components/editor/index.js.map +1 -1
  16. package/build/components/error-boundary/index.js +6 -0
  17. package/build/components/error-boundary/index.js.map +1 -1
  18. package/build/components/global-styles/dimensions-panel.js +191 -21
  19. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  20. package/build/components/global-styles/global-styles-provider.js +4 -2
  21. package/build/components/global-styles/global-styles-provider.js.map +1 -1
  22. package/build/components/global-styles/hooks.js +11 -2
  23. package/build/components/global-styles/hooks.js.map +1 -1
  24. package/build/components/global-styles/screen-color-palette.js +13 -17
  25. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  26. package/build/components/global-styles/screen-colors.js +59 -7
  27. package/build/components/global-styles/screen-colors.js.map +1 -1
  28. package/build/components/global-styles/screen-heading-color.js +157 -0
  29. package/build/components/global-styles/screen-heading-color.js.map +1 -0
  30. package/build/components/global-styles/screen-link-color.js +48 -14
  31. package/build/components/global-styles/screen-link-color.js.map +1 -1
  32. package/build/components/global-styles/screen-typography-element.js +4 -0
  33. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  34. package/build/components/global-styles/screen-typography.js +5 -0
  35. package/build/components/global-styles/screen-typography.js.map +1 -1
  36. package/build/components/global-styles/typography-panel.js +73 -12
  37. package/build/components/global-styles/typography-panel.js.map +1 -1
  38. package/build/components/global-styles/typography-utils.js +217 -0
  39. package/build/components/global-styles/typography-utils.js.map +1 -0
  40. package/build/components/global-styles/ui.js +11 -0
  41. package/build/components/global-styles/ui.js.map +1 -1
  42. package/build/components/global-styles/use-global-styles-output.js +298 -61
  43. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  44. package/build/components/global-styles/utils.js +49 -3
  45. package/build/components/global-styles/utils.js.map +1 -1
  46. package/build/components/header/index.js +22 -10
  47. package/build/components/header/index.js.map +1 -1
  48. package/build/components/header/undo-redo/redo.js +2 -1
  49. package/build/components/header/undo-redo/redo.js.map +1 -1
  50. package/build/components/keyboard-shortcut-help-modal/index.js +1 -3
  51. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  52. package/build/components/list/actions/index.js +1 -1
  53. package/build/components/list/actions/index.js.map +1 -1
  54. package/build/components/save-button/index.js +2 -3
  55. package/build/components/save-button/index.js.map +1 -1
  56. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js +2 -2
  57. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  58. package/build/components/sidebar/template-card/template-actions.js +1 -1
  59. package/build/components/sidebar/template-card/template-actions.js.map +1 -1
  60. package/build/components/template-details/edit-template-title.js +11 -3
  61. package/build/components/template-details/edit-template-title.js.map +1 -1
  62. package/build/components/template-details/index.js +2 -21
  63. package/build/components/template-details/index.js.map +1 -1
  64. package/build/components/template-details/template-areas.js +1 -1
  65. package/build/components/template-details/template-areas.js.map +1 -1
  66. package/build/components/template-part-converter/convert-to-template-part.js +4 -1
  67. package/build/components/template-part-converter/convert-to-template-part.js.map +1 -1
  68. package/build/hooks/index.js +2 -0
  69. package/build/hooks/index.js.map +1 -1
  70. package/build/hooks/template-part-edit.js +86 -0
  71. package/build/hooks/template-part-edit.js.map +1 -0
  72. package/build/store/selectors.js +4 -1
  73. package/build/store/selectors.js.map +1 -1
  74. package/build-module/components/add-new-template/add-custom-generic-template-modal.js +77 -0
  75. package/build-module/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  76. package/build-module/components/add-new-template/add-custom-template-modal.js +82 -61
  77. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
  78. package/build-module/components/add-new-template/new-template.js +96 -84
  79. package/build-module/components/add-new-template/new-template.js.map +1 -1
  80. package/build-module/components/add-new-template/utils.js +555 -50
  81. package/build-module/components/add-new-template/utils.js.map +1 -1
  82. package/build-module/components/block-editor/index.js +1 -2
  83. package/build-module/components/block-editor/index.js.map +1 -1
  84. package/build-module/components/code-editor/index.js +18 -5
  85. package/build-module/components/code-editor/index.js.map +1 -1
  86. package/build-module/components/editor/index.js +16 -0
  87. package/build-module/components/editor/index.js.map +1 -1
  88. package/build-module/components/error-boundary/index.js +5 -0
  89. package/build-module/components/error-boundary/index.js.map +1 -1
  90. package/build-module/components/global-styles/dimensions-panel.js +191 -22
  91. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  92. package/build-module/components/global-styles/global-styles-provider.js +4 -2
  93. package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
  94. package/build-module/components/global-styles/hooks.js +11 -2
  95. package/build-module/components/global-styles/hooks.js.map +1 -1
  96. package/build-module/components/global-styles/screen-color-palette.js +14 -19
  97. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  98. package/build-module/components/global-styles/screen-colors.js +59 -7
  99. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  100. package/build-module/components/global-styles/screen-heading-color.js +143 -0
  101. package/build-module/components/global-styles/screen-heading-color.js.map +1 -0
  102. package/build-module/components/global-styles/screen-link-color.js +47 -14
  103. package/build-module/components/global-styles/screen-link-color.js.map +1 -1
  104. package/build-module/components/global-styles/screen-typography-element.js +4 -0
  105. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  106. package/build-module/components/global-styles/screen-typography.js +5 -0
  107. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  108. package/build-module/components/global-styles/typography-panel.js +74 -13
  109. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  110. package/build-module/components/global-styles/typography-utils.js +204 -0
  111. package/build-module/components/global-styles/typography-utils.js.map +1 -0
  112. package/build-module/components/global-styles/ui.js +10 -0
  113. package/build-module/components/global-styles/ui.js.map +1 -1
  114. package/build-module/components/global-styles/use-global-styles-output.js +294 -69
  115. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  116. package/build-module/components/global-styles/utils.js +47 -4
  117. package/build-module/components/global-styles/utils.js.map +1 -1
  118. package/build-module/components/header/index.js +25 -12
  119. package/build-module/components/header/index.js.map +1 -1
  120. package/build-module/components/header/undo-redo/redo.js +3 -2
  121. package/build-module/components/header/undo-redo/redo.js.map +1 -1
  122. package/build-module/components/keyboard-shortcut-help-modal/index.js +1 -2
  123. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  124. package/build-module/components/list/actions/index.js +1 -1
  125. package/build-module/components/list/actions/index.js.map +1 -1
  126. package/build-module/components/save-button/index.js +3 -4
  127. package/build-module/components/save-button/index.js.map +1 -1
  128. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js +3 -3
  129. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  130. package/build-module/components/sidebar/template-card/template-actions.js +1 -1
  131. package/build-module/components/sidebar/template-card/template-actions.js.map +1 -1
  132. package/build-module/components/template-details/edit-template-title.js +12 -3
  133. package/build-module/components/template-details/edit-template-title.js.map +1 -1
  134. package/build-module/components/template-details/index.js +3 -22
  135. package/build-module/components/template-details/index.js.map +1 -1
  136. package/build-module/components/template-details/template-areas.js +1 -1
  137. package/build-module/components/template-details/template-areas.js.map +1 -1
  138. package/build-module/components/template-part-converter/convert-to-template-part.js +3 -1
  139. package/build-module/components/template-part-converter/convert-to-template-part.js.map +1 -1
  140. package/build-module/hooks/index.js +1 -0
  141. package/build-module/hooks/index.js.map +1 -1
  142. package/build-module/hooks/template-part-edit.js +67 -0
  143. package/build-module/hooks/template-part-edit.js.map +1 -0
  144. package/build-module/store/selectors.js +5 -2
  145. package/build-module/store/selectors.js.map +1 -1
  146. package/build-style/style-rtl.css +55 -48
  147. package/build-style/style.css +55 -48
  148. package/package.json +29 -29
  149. package/src/components/add-new-template/add-custom-generic-template-modal.js +97 -0
  150. package/src/components/add-new-template/add-custom-template-modal.js +93 -68
  151. package/src/components/add-new-template/new-template.js +126 -95
  152. package/src/components/add-new-template/style.scss +41 -8
  153. package/src/components/add-new-template/utils.js +622 -80
  154. package/src/components/block-editor/index.js +0 -2
  155. package/src/components/code-editor/index.js +15 -5
  156. package/src/components/editor/index.js +11 -0
  157. package/src/components/error-boundary/index.js +5 -0
  158. package/src/components/global-styles/dimensions-panel.js +214 -24
  159. package/src/components/global-styles/global-styles-provider.js +8 -9
  160. package/src/components/global-styles/hooks.js +18 -0
  161. package/src/components/global-styles/screen-color-palette.js +25 -27
  162. package/src/components/global-styles/screen-colors.js +55 -7
  163. package/src/components/global-styles/screen-heading-color.js +201 -0
  164. package/src/components/global-styles/screen-link-color.js +65 -23
  165. package/src/components/global-styles/screen-typography-element.js +4 -0
  166. package/src/components/global-styles/screen-typography.js +6 -0
  167. package/src/components/global-styles/style.scss +14 -11
  168. package/src/components/global-styles/test/typography-utils.js +130 -0
  169. package/src/components/global-styles/test/use-global-styles-output.js +296 -2
  170. package/src/components/global-styles/typography-panel.js +85 -16
  171. package/src/components/global-styles/typography-utils.js +228 -0
  172. package/src/components/global-styles/ui.js +13 -0
  173. package/src/components/global-styles/use-global-styles-output.js +387 -89
  174. package/src/components/global-styles/utils.js +43 -2
  175. package/src/components/header/index.js +37 -13
  176. package/src/components/header/style.scss +5 -3
  177. package/src/components/header/undo-redo/redo.js +6 -2
  178. package/src/components/keyboard-shortcut-help-modal/index.js +1 -2
  179. package/src/components/keyboard-shortcut-help-modal/style.scss +0 -5
  180. package/src/components/list/actions/index.js +3 -1
  181. package/src/components/list/style.scss +0 -8
  182. package/src/components/save-button/index.js +10 -13
  183. package/src/components/sidebar/navigation-menu-sidebar/navigation-menu.js +1 -5
  184. package/src/components/sidebar/style.scss +4 -0
  185. package/src/components/sidebar/template-card/template-actions.js +3 -1
  186. package/src/components/template-details/edit-template-title.js +10 -2
  187. package/src/components/template-details/index.js +7 -22
  188. package/src/components/template-details/template-areas.js +3 -1
  189. package/src/components/template-part-converter/convert-to-template-part.js +3 -1
  190. package/src/components/test/error-boundary.js +38 -0
  191. package/src/hooks/index.js +1 -0
  192. package/src/hooks/template-part-edit.js +82 -0
  193. package/src/store/selectors.js +11 -5
  194. package/src/style.scss +0 -1
  195. package/build/components/edit-template-part-menu-button/index.js +0 -90
  196. package/build/components/edit-template-part-menu-button/index.js.map +0 -1
  197. package/build-module/components/edit-template-part-menu-button/index.js +0 -72
  198. package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
  199. package/src/components/edit-template-part-menu-button/index.js +0 -82
@@ -0,0 +1,77 @@
1
+ import { createElement } from "@wordpress/element";
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { kebabCase } from 'lodash';
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+
11
+ import { useState } from '@wordpress/element';
12
+ import { __ } from '@wordpress/i18n';
13
+ import { Button, Flex, FlexItem, Modal, TextControl } from '@wordpress/components';
14
+
15
+ function AddCustomGenericTemplateModal(_ref) {
16
+ let {
17
+ onClose,
18
+ createTemplate
19
+ } = _ref;
20
+ const [title, setTitle] = useState('');
21
+
22
+ const defaultTitle = __('Custom Template');
23
+
24
+ const [isBusy, setIsBusy] = useState(false);
25
+
26
+ async function onCreateTemplate(event) {
27
+ event.preventDefault();
28
+
29
+ if (isBusy) {
30
+ return;
31
+ }
32
+
33
+ setIsBusy(true);
34
+ createTemplate({
35
+ slug: 'wp-custom-template-' + kebabCase(title || defaultTitle),
36
+ title: title || defaultTitle
37
+ }, false);
38
+ }
39
+
40
+ return createElement(Modal, {
41
+ title: __('Create custom template'),
42
+ closeLabel: __('Close'),
43
+ onRequestClose: () => {
44
+ onClose();
45
+ },
46
+ overlayClassName: "edit-site-custom-generic-template__modal"
47
+ }, createElement("form", {
48
+ onSubmit: onCreateTemplate
49
+ }, createElement(Flex, {
50
+ align: "flex-start",
51
+ gap: 8
52
+ }, createElement(FlexItem, null, createElement(TextControl, {
53
+ label: __('Name'),
54
+ value: title,
55
+ onChange: setTitle,
56
+ placeholder: defaultTitle,
57
+ disabled: isBusy,
58
+ help: __('Describe the template, e.g. "Post with sidebar".')
59
+ }))), createElement(Flex, {
60
+ className: "edit-site-custom-generic-template__modal-actions",
61
+ justify: "flex-end",
62
+ expanded: false
63
+ }, createElement(FlexItem, null, createElement(Button, {
64
+ variant: "tertiary",
65
+ onClick: () => {
66
+ onClose();
67
+ }
68
+ }, __('Cancel'))), createElement(FlexItem, null, createElement(Button, {
69
+ variant: "primary",
70
+ type: "submit",
71
+ isBusy: isBusy,
72
+ "aria-disabled": isBusy
73
+ }, __('Create'))))));
74
+ }
75
+
76
+ export default AddCustomGenericTemplateModal;
77
+ //# sourceMappingURL=add-custom-generic-template-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["@wordpress/edit-site/src/components/add-new-template/add-custom-generic-template-modal.js"],"names":["kebabCase","useState","__","Button","Flex","FlexItem","Modal","TextControl","AddCustomGenericTemplateModal","onClose","createTemplate","title","setTitle","defaultTitle","isBusy","setIsBusy","onCreateTemplate","event","preventDefault","slug"],"mappings":";;AAAA;AACA;AACA;AACA,SAASA,SAAT,QAA0B,QAA1B;AAEA;AACA;AACA;;AACA,SAASC,QAAT,QAAyB,oBAAzB;AACA,SAASC,EAAT,QAAmB,iBAAnB;AACA,SACCC,MADD,EAECC,IAFD,EAGCC,QAHD,EAICC,KAJD,EAKCC,WALD,QAMO,uBANP;;AAQA,SAASC,6BAAT,OAAsE;AAAA,MAA9B;AAAEC,IAAAA,OAAF;AAAWC,IAAAA;AAAX,GAA8B;AACrE,QAAM,CAAEC,KAAF,EAASC,QAAT,IAAsBX,QAAQ,CAAE,EAAF,CAApC;;AACA,QAAMY,YAAY,GAAGX,EAAE,CAAE,iBAAF,CAAvB;;AACA,QAAM,CAAEY,MAAF,EAAUC,SAAV,IAAwBd,QAAQ,CAAE,KAAF,CAAtC;;AACA,iBAAee,gBAAf,CAAiCC,KAAjC,EAAyC;AACxCA,IAAAA,KAAK,CAACC,cAAN;;AAEA,QAAKJ,MAAL,EAAc;AACb;AACA;;AAEDC,IAAAA,SAAS,CAAE,IAAF,CAAT;AAEAL,IAAAA,cAAc,CACb;AACCS,MAAAA,IAAI,EACH,wBAAwBnB,SAAS,CAAEW,KAAK,IAAIE,YAAX,CAFnC;AAGCF,MAAAA,KAAK,EAAEA,KAAK,IAAIE;AAHjB,KADa,EAMb,KANa,CAAd;AAQA;;AACD,SACC,cAAC,KAAD;AACC,IAAA,KAAK,EAAGX,EAAE,CAAE,wBAAF,CADX;AAEC,IAAA,UAAU,EAAGA,EAAE,CAAE,OAAF,CAFhB;AAGC,IAAA,cAAc,EAAG,MAAM;AACtBO,MAAAA,OAAO;AACP,KALF;AAMC,IAAA,gBAAgB,EAAC;AANlB,KAQC;AAAM,IAAA,QAAQ,EAAGO;AAAjB,KACC,cAAC,IAAD;AAAM,IAAA,KAAK,EAAC,YAAZ;AAAyB,IAAA,GAAG,EAAG;AAA/B,KACC,cAAC,QAAD,QACC,cAAC,WAAD;AACC,IAAA,KAAK,EAAGd,EAAE,CAAE,MAAF,CADX;AAEC,IAAA,KAAK,EAAGS,KAFT;AAGC,IAAA,QAAQ,EAAGC,QAHZ;AAIC,IAAA,WAAW,EAAGC,YAJf;AAKC,IAAA,QAAQ,EAAGC,MALZ;AAMC,IAAA,IAAI,EAAGZ,EAAE,CACR,kDADQ;AANV,IADD,CADD,CADD,EAgBC,cAAC,IAAD;AACC,IAAA,SAAS,EAAC,kDADX;AAEC,IAAA,OAAO,EAAC,UAFT;AAGC,IAAA,QAAQ,EAAG;AAHZ,KAKC,cAAC,QAAD,QACC,cAAC,MAAD;AACC,IAAA,OAAO,EAAC,UADT;AAEC,IAAA,OAAO,EAAG,MAAM;AACfO,MAAAA,OAAO;AACP;AAJF,KAMGP,EAAE,CAAE,QAAF,CANL,CADD,CALD,EAeC,cAAC,QAAD,QACC,cAAC,MAAD;AACC,IAAA,OAAO,EAAC,SADT;AAEC,IAAA,IAAI,EAAC,QAFN;AAGC,IAAA,MAAM,EAAGY,MAHV;AAIC,qBAAgBA;AAJjB,KAMGZ,EAAE,CAAE,QAAF,CANL,CADD,CAfD,CAhBD,CARD,CADD;AAsDA;;AAED,eAAeM,6BAAf","sourcesContent":["/**\n * External dependencies\n */\nimport { kebabCase } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport { useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tButton,\n\tFlex,\n\tFlexItem,\n\tModal,\n\tTextControl,\n} from '@wordpress/components';\n\nfunction AddCustomGenericTemplateModal( { onClose, createTemplate } ) {\n\tconst [ title, setTitle ] = useState( '' );\n\tconst defaultTitle = __( 'Custom Template' );\n\tconst [ isBusy, setIsBusy ] = useState( false );\n\tasync function onCreateTemplate( event ) {\n\t\tevent.preventDefault();\n\n\t\tif ( isBusy ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsBusy( true );\n\n\t\tcreateTemplate(\n\t\t\t{\n\t\t\t\tslug:\n\t\t\t\t\t'wp-custom-template-' + kebabCase( title || defaultTitle ),\n\t\t\t\ttitle: title || defaultTitle,\n\t\t\t},\n\t\t\tfalse\n\t\t);\n\t}\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ __( 'Create custom template' ) }\n\t\t\tcloseLabel={ __( 'Close' ) }\n\t\t\tonRequestClose={ () => {\n\t\t\t\tonClose();\n\t\t\t} }\n\t\t\toverlayClassName=\"edit-site-custom-generic-template__modal\"\n\t\t>\n\t\t\t<form onSubmit={ onCreateTemplate }>\n\t\t\t\t<Flex align=\"flex-start\" gap={ 8 }>\n\t\t\t\t\t<FlexItem>\n\t\t\t\t\t\t<TextControl\n\t\t\t\t\t\t\tlabel={ __( 'Name' ) }\n\t\t\t\t\t\t\tvalue={ title }\n\t\t\t\t\t\t\tonChange={ setTitle }\n\t\t\t\t\t\t\tplaceholder={ defaultTitle }\n\t\t\t\t\t\t\tdisabled={ isBusy }\n\t\t\t\t\t\t\thelp={ __(\n\t\t\t\t\t\t\t\t'Describe the template, e.g. \"Post with sidebar\".'\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FlexItem>\n\t\t\t\t</Flex>\n\n\t\t\t\t<Flex\n\t\t\t\t\tclassName=\"edit-site-custom-generic-template__modal-actions\"\n\t\t\t\t\tjustify=\"flex-end\"\n\t\t\t\t\texpanded={ false }\n\t\t\t\t>\n\t\t\t\t\t<FlexItem>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\t\t\tonClose();\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Cancel' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</FlexItem>\n\t\t\t\t\t<FlexItem>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tisBusy={ isBusy }\n\t\t\t\t\t\t\taria-disabled={ isBusy }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Create' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</FlexItem>\n\t\t\t\t</Flex>\n\t\t\t</form>\n\t\t</Modal>\n\t);\n}\n\nexport default AddCustomGenericTemplateModal;\n"]}
@@ -6,7 +6,7 @@ import { createElement, Fragment } from "@wordpress/element";
6
6
  */
7
7
  import { useState, useMemo, useEffect } from '@wordpress/element';
8
8
  import { __, sprintf } from '@wordpress/i18n';
9
- import { Button, Flex, FlexItem, Modal, SearchControl, TextHighlight, __experimentalText as Text, __experimentalHeading as Heading, __unstableComposite as Composite, __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem } from '@wordpress/components';
9
+ import { Button, Flex, FlexItem, Modal, SearchControl, TextHighlight, __experimentalText as Text, __unstableComposite as Composite, __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem } from '@wordpress/components';
10
10
  import { useDebounce } from '@wordpress/compose';
11
11
  import { useEntityRecords } from '@wordpress/core-data';
12
12
  /**
@@ -15,11 +15,6 @@ import { useEntityRecords } from '@wordpress/core-data';
15
15
 
16
16
  import { mapToIHasNameAndId } from './utils';
17
17
  const EMPTY_ARRAY = [];
18
- const BASE_QUERY = {
19
- order: 'asc',
20
- _fields: 'id,title,slug,link',
21
- context: 'view'
22
- };
23
18
 
24
19
  function SuggestionListItem(_ref) {
25
20
  let {
@@ -35,16 +30,7 @@ function SuggestionListItem(_ref) {
35
30
  as: Button
36
31
  }, composite, {
37
32
  className: baseCssClass,
38
- onClick: () => {
39
- const 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. "Post: Hello, WordPress"
40
- __('%1$s: %2$s'), entityForSuggestions.labels.singular_name, suggestion.name);
41
- onSelect({
42
- title,
43
- description: sprintf( // translators: Represents the description of a user's custom template in the Site Editor, e.g. "Template for Post: Hello, WordPress"
44
- __('Template for %1$s'), title),
45
- slug: `single-${entityForSuggestions.slug}-${suggestion.slug}`
46
- });
47
- }
33
+ onClick: () => onSelect(entityForSuggestions.config.getSpecificTemplate(suggestion))
48
34
  }), createElement("span", {
49
35
  className: `${baseCssClass}__title`
50
36
  }, createElement(TextHighlight, {
@@ -55,6 +41,53 @@ function SuggestionListItem(_ref) {
55
41
  }, suggestion.link));
56
42
  }
57
43
 
44
+ function useDebouncedInput() {
45
+ const [input, setInput] = useState('');
46
+ const [debounced, setter] = useState('');
47
+ const setDebounced = useDebounce(setter, 250);
48
+ useEffect(() => {
49
+ if (debounced !== input) {
50
+ setDebounced(input);
51
+ }
52
+ }, [debounced, input]);
53
+ return [input, setInput, debounced];
54
+ }
55
+
56
+ function useSearchSuggestions(entityForSuggestions, search) {
57
+ const {
58
+ config
59
+ } = entityForSuggestions;
60
+ const query = useMemo(() => ({
61
+ order: 'asc',
62
+ context: 'view',
63
+ search,
64
+ per_page: search ? 20 : 10,
65
+ ...config.queryArgs(search)
66
+ }), [search, config]);
67
+ const {
68
+ records: searchResults,
69
+ hasResolved: searchHasResolved
70
+ } = useEntityRecords(entityForSuggestions.type, entityForSuggestions.slug, query);
71
+ const [suggestions, setSuggestions] = useState(EMPTY_ARRAY);
72
+ useEffect(() => {
73
+ if (!searchHasResolved) return;
74
+ let newSuggestions = EMPTY_ARRAY;
75
+
76
+ if (searchResults !== null && searchResults !== void 0 && searchResults.length) {
77
+ newSuggestions = searchResults;
78
+
79
+ if (config.recordNamePath) {
80
+ newSuggestions = mapToIHasNameAndId(newSuggestions, config.recordNamePath);
81
+ }
82
+ } // Update suggestions only when the query has resolved, so as to keep
83
+ // the previous results in the UI.
84
+
85
+
86
+ setSuggestions(newSuggestions);
87
+ }, [searchResults, searchHasResolved]);
88
+ return suggestions;
89
+ }
90
+
58
91
  function SuggestionList(_ref2) {
59
92
  let {
60
93
  entityForSuggestions,
@@ -63,54 +96,36 @@ function SuggestionList(_ref2) {
63
96
  const composite = useCompositeState({
64
97
  orientation: 'vertical'
65
98
  });
66
- const [suggestions, setSuggestions] = useState(EMPTY_ARRAY); // We need to track two values, the search input's value(searchInputValue)
67
- // and the one we want to debounce(search) and make REST API requests.
68
-
69
- const [searchInputValue, setSearchInputValue] = useState('');
70
- const [search, setSearch] = useState('');
71
- const debouncedSearch = useDebounce(setSearch, 250);
72
- const query = { ...BASE_QUERY,
73
- search,
74
- orderby: search ? 'relevance' : 'modified',
75
- exclude: entityForSuggestions.postsToExclude,
76
- per_page: search ? 20 : 10
77
- };
99
+ const [search, setSearch, debouncedSearch] = useDebouncedInput();
100
+ const suggestions = useSearchSuggestions(entityForSuggestions, debouncedSearch);
78
101
  const {
79
- records: searchResults,
80
- hasResolved: searchHasResolved
81
- } = useEntityRecords(entityForSuggestions.type, entityForSuggestions.slug, query);
82
- useEffect(() => {
83
- if (search !== searchInputValue) {
84
- debouncedSearch(searchInputValue);
85
- }
86
- }, [search, searchInputValue]);
87
- const entitiesInfo = useMemo(() => {
88
- if (!(searchResults !== null && searchResults !== void 0 && searchResults.length)) return EMPTY_ARRAY;
89
- return mapToIHasNameAndId(searchResults, 'title.rendered');
90
- }, [searchResults]); // Update suggestions only when the query has resolved.
102
+ labels
103
+ } = entityForSuggestions;
104
+ const [showSearchControl, setShowSearchControl] = useState(false);
91
105
 
92
- useEffect(() => {
93
- if (!searchHasResolved) return;
94
- setSuggestions(entitiesInfo);
95
- }, [entitiesInfo, searchHasResolved]);
96
- return createElement(Fragment, null, createElement(SearchControl, {
97
- onChange: setSearchInputValue,
98
- value: searchInputValue,
99
- label: entityForSuggestions.labels.search_items,
100
- placeholder: entityForSuggestions.labels.search_items
106
+ if (!showSearchControl && (suggestions === null || suggestions === void 0 ? void 0 : suggestions.length) > 9) {
107
+ setShowSearchControl(true);
108
+ }
109
+
110
+ return createElement(Fragment, null, showSearchControl && createElement(SearchControl, {
111
+ onChange: setSearch,
112
+ value: search,
113
+ label: labels.search_items,
114
+ placeholder: labels.search_items
101
115
  }), !!(suggestions !== null && suggestions !== void 0 && suggestions.length) && createElement(Composite, _extends({}, composite, {
102
116
  role: "listbox",
103
- className: "edit-site-custom-template-modal__suggestions_list"
117
+ className: "edit-site-custom-template-modal__suggestions_list",
118
+ "aria-label": __('Suggestions list')
104
119
  }), suggestions.map(suggestion => createElement(SuggestionListItem, {
105
120
  key: suggestion.slug,
106
121
  suggestion: suggestion,
107
- search: search,
122
+ search: debouncedSearch,
108
123
  onSelect: onSelect,
109
124
  entityForSuggestions: entityForSuggestions,
110
125
  composite: composite
111
- }))), search && !(suggestions !== null && suggestions !== void 0 && suggestions.length) && createElement("p", {
126
+ }))), debouncedSearch && !(suggestions !== null && suggestions !== void 0 && suggestions.length) && createElement("p", {
112
127
  className: "edit-site-custom-template-modal__no-results"
113
- }, entityForSuggestions.labels.not_found));
128
+ }, labels.not_found));
114
129
  }
115
130
 
116
131
  function AddCustomTemplateModal(_ref3) {
@@ -133,33 +148,39 @@ function AddCustomTemplateModal(_ref3) {
133
148
  align: "initial"
134
149
  }, createElement(FlexItem, {
135
150
  isBlock: true,
151
+ as: Button,
136
152
  onClick: () => {
137
153
  const {
138
154
  slug,
139
155
  title,
140
- description
156
+ description,
157
+ templatePrefix
141
158
  } = entityForSuggestions.template;
142
159
  onSelect({
143
160
  slug,
144
161
  title,
145
- description
162
+ description,
163
+ templatePrefix
146
164
  });
147
165
  }
148
- }, createElement(Heading, {
149
- level: 5
166
+ }, createElement(Text, {
167
+ as: "span",
168
+ weight: 600
150
169
  }, entityForSuggestions.labels.all_items), createElement(Text, {
151
170
  as: "span"
152
- }, // translators: The user is given the choice to set up a template for all items of a post type, or just a specific one.
171
+ }, // translators: The user is given the choice to set up a template for all items of a post type or taxonomy, or just a specific one.
153
172
  __('For all items'))), createElement(FlexItem, {
154
173
  isBlock: true,
174
+ as: Button,
155
175
  onClick: () => {
156
176
  setShowSearchEntities(true);
157
177
  }
158
- }, createElement(Heading, {
159
- level: 5
178
+ }, createElement(Text, {
179
+ as: "span",
180
+ weight: 600
160
181
  }, entityForSuggestions.labels.singular_name), createElement(Text, {
161
182
  as: "span"
162
- }, // translators: The user is given the choice to set up a template for all items of a post type, or just a specific one.
183
+ }, // translators: The user is given the choice to set up a template for all items of a post type or taxonomy, or just a specific one.
163
184
  __('For a specific item'))))), showSearchEntities && createElement(Fragment, null, createElement("p", null, __('This template will be used only for the specific item chosen.')), createElement(SuggestionList, {
164
185
  entityForSuggestions: entityForSuggestions,
165
186
  onSelect: onSelect
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/edit-site/src/components/add-new-template/add-custom-template-modal.js"],"names":["useState","useMemo","useEffect","__","sprintf","Button","Flex","FlexItem","Modal","SearchControl","TextHighlight","__experimentalText","Text","__experimentalHeading","Heading","__unstableComposite","Composite","__unstableUseCompositeState","useCompositeState","__unstableCompositeItem","CompositeItem","useDebounce","useEntityRecords","mapToIHasNameAndId","EMPTY_ARRAY","BASE_QUERY","order","_fields","context","SuggestionListItem","suggestion","search","onSelect","entityForSuggestions","composite","baseCssClass","title","labels","singular_name","name","description","slug","link","SuggestionList","orientation","suggestions","setSuggestions","searchInputValue","setSearchInputValue","setSearch","debouncedSearch","query","orderby","exclude","postsToExclude","per_page","records","searchResults","hasResolved","searchHasResolved","type","entitiesInfo","length","search_items","map","not_found","AddCustomTemplateModal","onClose","showSearchEntities","setShowSearchEntities","hasGeneralTemplate","template","all_items"],"mappings":";;;AAAA;AACA;AACA;AACA,SAASA,QAAT,EAAmBC,OAAnB,EAA4BC,SAA5B,QAA6C,oBAA7C;AACA,SAASC,EAAT,EAAaC,OAAb,QAA4B,iBAA5B;AACA,SACCC,MADD,EAECC,IAFD,EAGCC,QAHD,EAICC,KAJD,EAKCC,aALD,EAMCC,aAND,EAOCC,kBAAkB,IAAIC,IAPvB,EAQCC,qBAAqB,IAAIC,OAR1B,EASCC,mBAAmB,IAAIC,SATxB,EAUCC,2BAA2B,IAAIC,iBAVhC,EAWCC,uBAAuB,IAAIC,aAX5B,QAYO,uBAZP;AAaA,SAASC,WAAT,QAA4B,oBAA5B;AACA,SAASC,gBAAT,QAAiC,sBAAjC;AAEA;AACA;AACA;;AACA,SAASC,kBAAT,QAAmC,SAAnC;AAEA,MAAMC,WAAW,GAAG,EAApB;AACA,MAAMC,UAAU,GAAG;AAClBC,EAAAA,KAAK,EAAE,KADW;AAElBC,EAAAA,OAAO,EAAE,oBAFS;AAGlBC,EAAAA,OAAO,EAAE;AAHS,CAAnB;;AAMA,SAASC,kBAAT,OAMI;AAAA,MANyB;AAC5BC,IAAAA,UAD4B;AAE5BC,IAAAA,MAF4B;AAG5BC,IAAAA,QAH4B;AAI5BC,IAAAA,oBAJ4B;AAK5BC,IAAAA;AAL4B,GAMzB;AACH,QAAMC,YAAY,GACjB,8DADD;AAEA,SACC,cAAC,aAAD;AACC,IAAA,IAAI,EAAC,QADN;AAEC,IAAA,EAAE,EAAG9B;AAFN,KAGM6B,SAHN;AAIC,IAAA,SAAS,EAAGC,YAJb;AAKC,IAAA,OAAO,EAAG,MAAM;AACf,YAAMC,KAAK,GAAGhC,OAAO,EACpB;AACAD,MAAAA,EAAE,CAAE,YAAF,CAFkB,EAGpB8B,oBAAoB,CAACI,MAArB,CAA4BC,aAHR,EAIpBR,UAAU,CAACS,IAJS,CAArB;AAMAP,MAAAA,QAAQ,CAAE;AACTI,QAAAA,KADS;AAETI,QAAAA,WAAW,EAAEpC,OAAO,EACnB;AACAD,QAAAA,EAAE,CAAE,mBAAF,CAFiB,EAGnBiC,KAHmB,CAFX;AAOTK,QAAAA,IAAI,EAAG,UAAUR,oBAAoB,CAACQ,IAAM,IAAIX,UAAU,CAACW,IAAM;AAPxD,OAAF,CAAR;AASA;AArBF,MAuBC;AAAM,IAAA,SAAS,EAAI,GAAGN,YAAc;AAApC,KACC,cAAC,aAAD;AAAe,IAAA,IAAI,EAAGL,UAAU,CAACS,IAAjC;AAAwC,IAAA,SAAS,EAAGR;AAApD,IADD,CAvBD,EA0BGD,UAAU,CAACY,IAAX,IACD;AAAM,IAAA,SAAS,EAAI,GAAGP,YAAc;AAApC,KACGL,UAAU,CAACY,IADd,CA3BF,CADD;AAkCA;;AAED,SAASC,cAAT,QAA8D;AAAA,MAArC;AAAEV,IAAAA,oBAAF;AAAwBD,IAAAA;AAAxB,GAAqC;AAC7D,QAAME,SAAS,GAAGhB,iBAAiB,CAAE;AAAE0B,IAAAA,WAAW,EAAE;AAAf,GAAF,CAAnC;AACA,QAAM,CAAEC,WAAF,EAAeC,cAAf,IAAkC9C,QAAQ,CAAEwB,WAAF,CAAhD,CAF6D,CAG7D;AACA;;AACA,QAAM,CAAEuB,gBAAF,EAAoBC,mBAApB,IAA4ChD,QAAQ,CAAE,EAAF,CAA1D;AACA,QAAM,CAAE+B,MAAF,EAAUkB,SAAV,IAAwBjD,QAAQ,CAAE,EAAF,CAAtC;AACA,QAAMkD,eAAe,GAAG7B,WAAW,CAAE4B,SAAF,EAAa,GAAb,CAAnC;AACA,QAAME,KAAK,GAAG,EACb,GAAG1B,UADU;AAEbM,IAAAA,MAFa;AAGbqB,IAAAA,OAAO,EAAErB,MAAM,GAAG,WAAH,GAAiB,UAHnB;AAIbsB,IAAAA,OAAO,EAAEpB,oBAAoB,CAACqB,cAJjB;AAKbC,IAAAA,QAAQ,EAAExB,MAAM,GAAG,EAAH,GAAQ;AALX,GAAd;AAOA,QAAM;AAAEyB,IAAAA,OAAO,EAAEC,aAAX;AAA0BC,IAAAA,WAAW,EAAEC;AAAvC,MACLrC,gBAAgB,CACfW,oBAAoB,CAAC2B,IADN,EAEf3B,oBAAoB,CAACQ,IAFN,EAGfU,KAHe,CADjB;AAMAjD,EAAAA,SAAS,CAAE,MAAM;AAChB,QAAK6B,MAAM,KAAKgB,gBAAhB,EAAmC;AAClCG,MAAAA,eAAe,CAAEH,gBAAF,CAAf;AACA;AACD,GAJQ,EAIN,CAAEhB,MAAF,EAAUgB,gBAAV,CAJM,CAAT;AAKA,QAAMc,YAAY,GAAG5D,OAAO,CAAE,MAAM;AACnC,QAAK,EAAEwD,aAAF,aAAEA,aAAF,eAAEA,aAAa,CAAEK,MAAjB,CAAL,EAA+B,OAAOtC,WAAP;AAC/B,WAAOD,kBAAkB,CAAEkC,aAAF,EAAiB,gBAAjB,CAAzB;AACA,GAH2B,EAGzB,CAAEA,aAAF,CAHyB,CAA5B,CA1B6D,CA8B7D;;AACAvD,EAAAA,SAAS,CAAE,MAAM;AAChB,QAAK,CAAEyD,iBAAP,EAA2B;AAC3Bb,IAAAA,cAAc,CAAEe,YAAF,CAAd;AACA,GAHQ,EAGN,CAAEA,YAAF,EAAgBF,iBAAhB,CAHM,CAAT;AAIA,SACC,8BACC,cAAC,aAAD;AACC,IAAA,QAAQ,EAAGX,mBADZ;AAEC,IAAA,KAAK,EAAGD,gBAFT;AAGC,IAAA,KAAK,EAAGd,oBAAoB,CAACI,MAArB,CAA4B0B,YAHrC;AAIC,IAAA,WAAW,EAAG9B,oBAAoB,CAACI,MAArB,CAA4B0B;AAJ3C,IADD,EAOG,CAAC,EAAElB,WAAF,aAAEA,WAAF,eAAEA,WAAW,CAAEiB,MAAf,CAAD,IACD,cAAC,SAAD,eACM5B,SADN;AAEC,IAAA,IAAI,EAAC,SAFN;AAGC,IAAA,SAAS,EAAC;AAHX,MAKGW,WAAW,CAACmB,GAAZ,CAAmBlC,UAAF,IAClB,cAAC,kBAAD;AACC,IAAA,GAAG,EAAGA,UAAU,CAACW,IADlB;AAEC,IAAA,UAAU,EAAGX,UAFd;AAGC,IAAA,MAAM,EAAGC,MAHV;AAIC,IAAA,QAAQ,EAAGC,QAJZ;AAKC,IAAA,oBAAoB,EAAGC,oBALxB;AAMC,IAAA,SAAS,EAAGC;AANb,IADC,CALH,CARF,EAyBGH,MAAM,IAAI,EAAEc,WAAF,aAAEA,WAAF,eAAEA,WAAW,CAAEiB,MAAf,CAAV,IACD;AAAG,IAAA,SAAS,EAAC;AAAb,KACG7B,oBAAoB,CAACI,MAArB,CAA4B4B,SAD/B,CA1BF,CADD;AAiCA;;AAED,SAASC,sBAAT,QAA+E;AAAA,MAA9C;AAAEC,IAAAA,OAAF;AAAWnC,IAAAA,QAAX;AAAqBC,IAAAA;AAArB,GAA8C;AAC9E,QAAM,CAAEmC,kBAAF,EAAsBC,qBAAtB,IAAgDrE,QAAQ,CAC7DiC,oBAAoB,CAACqC,kBADwC,CAA9D;AAGA,QAAMnC,YAAY,GAAG,iCAArB;AACA,SACC,cAAC,KAAD;AACC,IAAA,KAAK,EAAG/B,OAAO,EACd;AACAD,IAAAA,EAAE,CAAE,kBAAF,CAFY,EAGd8B,oBAAoB,CAACI,MAArB,CAA4BC,aAHd,CADhB;AAMC,IAAA,SAAS,EAAGH,YANb;AAOC,IAAA,UAAU,EAAGhC,EAAE,CAAE,OAAF,CAPhB;AAQC,IAAA,cAAc,EAAGgE;AARlB,KAUG,CAAEC,kBAAF,IACD,8BACC,yBACGjE,EAAE,CACH,6EADG,CADL,CADD,EAMC,cAAC,IAAD;AACC,IAAA,SAAS,EAAI,GAAGgC,YAAc,YAD/B;AAEC,IAAA,GAAG,EAAC,GAFL;AAGC,IAAA,KAAK,EAAC;AAHP,KAKC,cAAC,QAAD;AACC,IAAA,OAAO,MADR;AAEC,IAAA,OAAO,EAAG,MAAM;AACf,YAAM;AAAEM,QAAAA,IAAF;AAAQL,QAAAA,KAAR;AAAeI,QAAAA;AAAf,UACLP,oBAAoB,CAACsC,QADtB;AAEAvC,MAAAA,QAAQ,CAAE;AAAES,QAAAA,IAAF;AAAQL,QAAAA,KAAR;AAAeI,QAAAA;AAAf,OAAF,CAAR;AACA;AANF,KAQC,cAAC,OAAD;AAAS,IAAA,KAAK,EAAG;AAAjB,KACGP,oBAAoB,CAACI,MAArB,CAA4BmC,SAD/B,CARD,EAWC,cAAC,IAAD;AAAM,IAAA,EAAE,EAAC;AAAT,KAEE;AACArE,EAAAA,EAAE,CAAE,eAAF,CAHJ,CAXD,CALD,EAuBC,cAAC,QAAD;AACC,IAAA,OAAO,MADR;AAEC,IAAA,OAAO,EAAG,MAAM;AACfkE,MAAAA,qBAAqB,CAAE,IAAF,CAArB;AACA;AAJF,KAMC,cAAC,OAAD;AAAS,IAAA,KAAK,EAAG;AAAjB,KACGpC,oBAAoB,CAACI,MAArB,CAA4BC,aAD/B,CAND,EASC,cAAC,IAAD;AAAM,IAAA,EAAE,EAAC;AAAT,KAEE;AACAnC,EAAAA,EAAE,CAAE,qBAAF,CAHJ,CATD,CAvBD,CAND,CAXF,EA2DGiE,kBAAkB,IACnB,8BACC,yBACGjE,EAAE,CACH,+DADG,CADL,CADD,EAMC,cAAC,cAAD;AACC,IAAA,oBAAoB,EAAG8B,oBADxB;AAEC,IAAA,QAAQ,EAAGD;AAFZ,IAND,CA5DF,CADD;AA2EA;;AAED,eAAekC,sBAAf","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useMemo, useEffect } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport {\n\tButton,\n\tFlex,\n\tFlexItem,\n\tModal,\n\tSearchControl,\n\tTextHighlight,\n\t__experimentalText as Text,\n\t__experimentalHeading as Heading,\n\t__unstableComposite as Composite,\n\t__unstableUseCompositeState as useCompositeState,\n\t__unstableCompositeItem as CompositeItem,\n} from '@wordpress/components';\nimport { useDebounce } from '@wordpress/compose';\nimport { useEntityRecords } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { mapToIHasNameAndId } from './utils';\n\nconst EMPTY_ARRAY = [];\nconst BASE_QUERY = {\n\torder: 'asc',\n\t_fields: 'id,title,slug,link',\n\tcontext: 'view',\n};\n\nfunction SuggestionListItem( {\n\tsuggestion,\n\tsearch,\n\tonSelect,\n\tentityForSuggestions,\n\tcomposite,\n} ) {\n\tconst baseCssClass =\n\t\t'edit-site-custom-template-modal__suggestions_list__list-item';\n\treturn (\n\t\t<CompositeItem\n\t\t\trole=\"option\"\n\t\t\tas={ Button }\n\t\t\t{ ...composite }\n\t\t\tclassName={ baseCssClass }\n\t\t\tonClick={ () => {\n\t\t\t\tconst title = sprintf(\n\t\t\t\t\t// 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. \"Post: Hello, WordPress\"\n\t\t\t\t\t__( '%1$s: %2$s' ),\n\t\t\t\t\tentityForSuggestions.labels.singular_name,\n\t\t\t\t\tsuggestion.name\n\t\t\t\t);\n\t\t\t\tonSelect( {\n\t\t\t\t\ttitle,\n\t\t\t\t\tdescription: sprintf(\n\t\t\t\t\t\t// translators: Represents the description of a user's custom template in the Site Editor, e.g. \"Template for Post: Hello, WordPress\"\n\t\t\t\t\t\t__( 'Template for %1$s' ),\n\t\t\t\t\t\ttitle\n\t\t\t\t\t),\n\t\t\t\t\tslug: `single-${ entityForSuggestions.slug }-${ suggestion.slug }`,\n\t\t\t\t} );\n\t\t\t} }\n\t\t>\n\t\t\t<span className={ `${ baseCssClass }__title` }>\n\t\t\t\t<TextHighlight text={ suggestion.name } highlight={ search } />\n\t\t\t</span>\n\t\t\t{ suggestion.link && (\n\t\t\t\t<span className={ `${ baseCssClass }__info` }>\n\t\t\t\t\t{ suggestion.link }\n\t\t\t\t</span>\n\t\t\t) }\n\t\t</CompositeItem>\n\t);\n}\n\nfunction SuggestionList( { entityForSuggestions, onSelect } ) {\n\tconst composite = useCompositeState( { orientation: 'vertical' } );\n\tconst [ suggestions, setSuggestions ] = useState( EMPTY_ARRAY );\n\t// We need to track two values, the search input's value(searchInputValue)\n\t// and the one we want to debounce(search) and make REST API requests.\n\tconst [ searchInputValue, setSearchInputValue ] = useState( '' );\n\tconst [ search, setSearch ] = useState( '' );\n\tconst debouncedSearch = useDebounce( setSearch, 250 );\n\tconst query = {\n\t\t...BASE_QUERY,\n\t\tsearch,\n\t\torderby: search ? 'relevance' : 'modified',\n\t\texclude: entityForSuggestions.postsToExclude,\n\t\tper_page: search ? 20 : 10,\n\t};\n\tconst { records: searchResults, hasResolved: searchHasResolved } =\n\t\tuseEntityRecords(\n\t\t\tentityForSuggestions.type,\n\t\t\tentityForSuggestions.slug,\n\t\t\tquery\n\t\t);\n\tuseEffect( () => {\n\t\tif ( search !== searchInputValue ) {\n\t\t\tdebouncedSearch( searchInputValue );\n\t\t}\n\t}, [ search, searchInputValue ] );\n\tconst entitiesInfo = useMemo( () => {\n\t\tif ( ! searchResults?.length ) return EMPTY_ARRAY;\n\t\treturn mapToIHasNameAndId( searchResults, 'title.rendered' );\n\t}, [ searchResults ] );\n\t// Update suggestions only when the query has resolved.\n\tuseEffect( () => {\n\t\tif ( ! searchHasResolved ) return;\n\t\tsetSuggestions( entitiesInfo );\n\t}, [ entitiesInfo, searchHasResolved ] );\n\treturn (\n\t\t<>\n\t\t\t<SearchControl\n\t\t\t\tonChange={ setSearchInputValue }\n\t\t\t\tvalue={ searchInputValue }\n\t\t\t\tlabel={ entityForSuggestions.labels.search_items }\n\t\t\t\tplaceholder={ entityForSuggestions.labels.search_items }\n\t\t\t/>\n\t\t\t{ !! suggestions?.length && (\n\t\t\t\t<Composite\n\t\t\t\t\t{ ...composite }\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\tclassName=\"edit-site-custom-template-modal__suggestions_list\"\n\t\t\t\t>\n\t\t\t\t\t{ suggestions.map( ( suggestion ) => (\n\t\t\t\t\t\t<SuggestionListItem\n\t\t\t\t\t\t\tkey={ suggestion.slug }\n\t\t\t\t\t\t\tsuggestion={ suggestion }\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tonSelect={ onSelect }\n\t\t\t\t\t\t\tentityForSuggestions={ entityForSuggestions }\n\t\t\t\t\t\t\tcomposite={ composite }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) ) }\n\t\t\t\t</Composite>\n\t\t\t) }\n\t\t\t{ search && ! suggestions?.length && (\n\t\t\t\t<p className=\"edit-site-custom-template-modal__no-results\">\n\t\t\t\t\t{ entityForSuggestions.labels.not_found }\n\t\t\t\t</p>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\nfunction AddCustomTemplateModal( { onClose, onSelect, entityForSuggestions } ) {\n\tconst [ showSearchEntities, setShowSearchEntities ] = useState(\n\t\tentityForSuggestions.hasGeneralTemplate\n\t);\n\tconst baseCssClass = 'edit-site-custom-template-modal';\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ sprintf(\n\t\t\t\t// translators: %s: Name of the post type e.g: \"Post\".\n\t\t\t\t__( 'Add template: %s' ),\n\t\t\t\tentityForSuggestions.labels.singular_name\n\t\t\t) }\n\t\t\tclassName={ baseCssClass }\n\t\t\tcloseLabel={ __( 'Close' ) }\n\t\t\tonRequestClose={ onClose }\n\t\t>\n\t\t\t{ ! showSearchEntities && (\n\t\t\t\t<>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Select whether to create a single template for all items or a specific one.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t\t<Flex\n\t\t\t\t\t\tclassName={ `${ baseCssClass }__contents` }\n\t\t\t\t\t\tgap=\"4\"\n\t\t\t\t\t\talign=\"initial\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<FlexItem\n\t\t\t\t\t\t\tisBlock\n\t\t\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\t\t\tconst { slug, title, description } =\n\t\t\t\t\t\t\t\t\tentityForSuggestions.template;\n\t\t\t\t\t\t\t\tonSelect( { slug, title, description } );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Heading level={ 5 }>\n\t\t\t\t\t\t\t\t{ entityForSuggestions.labels.all_items }\n\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t<Text as=\"span\">\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// translators: The user is given the choice to set up a template for all items of a post type, or just a specific one.\n\t\t\t\t\t\t\t\t\t__( 'For all items' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</FlexItem>\n\t\t\t\t\t\t<FlexItem\n\t\t\t\t\t\t\tisBlock\n\t\t\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\t\t\tsetShowSearchEntities( true );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Heading level={ 5 }>\n\t\t\t\t\t\t\t\t{ entityForSuggestions.labels.singular_name }\n\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t<Text as=\"span\">\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// translators: The user is given the choice to set up a template for all items of a post type, or just a specific one.\n\t\t\t\t\t\t\t\t\t__( 'For a specific item' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</FlexItem>\n\t\t\t\t\t</Flex>\n\t\t\t\t</>\n\t\t\t) }\n\t\t\t{ showSearchEntities && (\n\t\t\t\t<>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'This template will be used only for the specific item chosen.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t\t<SuggestionList\n\t\t\t\t\t\tentityForSuggestions={ entityForSuggestions }\n\t\t\t\t\t\tonSelect={ onSelect }\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default AddCustomTemplateModal;\n"]}
1
+ {"version":3,"sources":["@wordpress/edit-site/src/components/add-new-template/add-custom-template-modal.js"],"names":["useState","useMemo","useEffect","__","sprintf","Button","Flex","FlexItem","Modal","SearchControl","TextHighlight","__experimentalText","Text","__unstableComposite","Composite","__unstableUseCompositeState","useCompositeState","__unstableCompositeItem","CompositeItem","useDebounce","useEntityRecords","mapToIHasNameAndId","EMPTY_ARRAY","SuggestionListItem","suggestion","search","onSelect","entityForSuggestions","composite","baseCssClass","config","getSpecificTemplate","name","link","useDebouncedInput","input","setInput","debounced","setter","setDebounced","useSearchSuggestions","query","order","context","per_page","queryArgs","records","searchResults","hasResolved","searchHasResolved","type","slug","suggestions","setSuggestions","newSuggestions","length","recordNamePath","SuggestionList","orientation","setSearch","debouncedSearch","labels","showSearchControl","setShowSearchControl","search_items","map","not_found","AddCustomTemplateModal","onClose","showSearchEntities","setShowSearchEntities","hasGeneralTemplate","singular_name","title","description","templatePrefix","template","all_items"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useMemo, useEffect } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport {\n\tButton,\n\tFlex,\n\tFlexItem,\n\tModal,\n\tSearchControl,\n\tTextHighlight,\n\t__experimentalText as Text,\n\t__unstableComposite as Composite,\n\t__unstableUseCompositeState as useCompositeState,\n\t__unstableCompositeItem as CompositeItem,\n} from '@wordpress/components';\nimport { useDebounce } from '@wordpress/compose';\nimport { useEntityRecords } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { mapToIHasNameAndId } from './utils';\n\nconst EMPTY_ARRAY = [];\n\nfunction SuggestionListItem( {\n\tsuggestion,\n\tsearch,\n\tonSelect,\n\tentityForSuggestions,\n\tcomposite,\n} ) {\n\tconst baseCssClass =\n\t\t'edit-site-custom-template-modal__suggestions_list__list-item';\n\treturn (\n\t\t<CompositeItem\n\t\t\trole=\"option\"\n\t\t\tas={ Button }\n\t\t\t{ ...composite }\n\t\t\tclassName={ baseCssClass }\n\t\t\tonClick={ () =>\n\t\t\t\tonSelect(\n\t\t\t\t\tentityForSuggestions.config.getSpecificTemplate(\n\t\t\t\t\t\tsuggestion\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t<span className={ `${ baseCssClass }__title` }>\n\t\t\t\t<TextHighlight text={ suggestion.name } highlight={ search } />\n\t\t\t</span>\n\t\t\t{ suggestion.link && (\n\t\t\t\t<span className={ `${ baseCssClass }__info` }>\n\t\t\t\t\t{ suggestion.link }\n\t\t\t\t</span>\n\t\t\t) }\n\t\t</CompositeItem>\n\t);\n}\n\nfunction useDebouncedInput() {\n\tconst [ input, setInput ] = useState( '' );\n\tconst [ debounced, setter ] = useState( '' );\n\tconst setDebounced = useDebounce( setter, 250 );\n\tuseEffect( () => {\n\t\tif ( debounced !== input ) {\n\t\t\tsetDebounced( input );\n\t\t}\n\t}, [ debounced, input ] );\n\treturn [ input, setInput, debounced ];\n}\n\nfunction useSearchSuggestions( entityForSuggestions, search ) {\n\tconst { config } = entityForSuggestions;\n\tconst query = useMemo(\n\t\t() => ( {\n\t\t\torder: 'asc',\n\t\t\tcontext: 'view',\n\t\t\tsearch,\n\t\t\tper_page: search ? 20 : 10,\n\t\t\t...config.queryArgs( search ),\n\t\t} ),\n\t\t[ search, config ]\n\t);\n\tconst { records: searchResults, hasResolved: searchHasResolved } =\n\t\tuseEntityRecords(\n\t\t\tentityForSuggestions.type,\n\t\t\tentityForSuggestions.slug,\n\t\t\tquery\n\t\t);\n\tconst [ suggestions, setSuggestions ] = useState( EMPTY_ARRAY );\n\tuseEffect( () => {\n\t\tif ( ! searchHasResolved ) return;\n\t\tlet newSuggestions = EMPTY_ARRAY;\n\t\tif ( searchResults?.length ) {\n\t\t\tnewSuggestions = searchResults;\n\t\t\tif ( config.recordNamePath ) {\n\t\t\t\tnewSuggestions = mapToIHasNameAndId(\n\t\t\t\t\tnewSuggestions,\n\t\t\t\t\tconfig.recordNamePath\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// Update suggestions only when the query has resolved, so as to keep\n\t\t// the previous results in the UI.\n\t\tsetSuggestions( newSuggestions );\n\t}, [ searchResults, searchHasResolved ] );\n\treturn suggestions;\n}\n\nfunction SuggestionList( { entityForSuggestions, onSelect } ) {\n\tconst composite = useCompositeState( { orientation: 'vertical' } );\n\tconst [ search, setSearch, debouncedSearch ] = useDebouncedInput();\n\tconst suggestions = useSearchSuggestions(\n\t\tentityForSuggestions,\n\t\tdebouncedSearch\n\t);\n\tconst { labels } = entityForSuggestions;\n\tconst [ showSearchControl, setShowSearchControl ] = useState( false );\n\tif ( ! showSearchControl && suggestions?.length > 9 ) {\n\t\tsetShowSearchControl( true );\n\t}\n\treturn (\n\t\t<>\n\t\t\t{ showSearchControl && (\n\t\t\t\t<SearchControl\n\t\t\t\t\tonChange={ setSearch }\n\t\t\t\t\tvalue={ search }\n\t\t\t\t\tlabel={ labels.search_items }\n\t\t\t\t\tplaceholder={ labels.search_items }\n\t\t\t\t/>\n\t\t\t) }\n\t\t\t{ !! suggestions?.length && (\n\t\t\t\t<Composite\n\t\t\t\t\t{ ...composite }\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\tclassName=\"edit-site-custom-template-modal__suggestions_list\"\n\t\t\t\t\taria-label={ __( 'Suggestions list' ) }\n\t\t\t\t>\n\t\t\t\t\t{ suggestions.map( ( suggestion ) => (\n\t\t\t\t\t\t<SuggestionListItem\n\t\t\t\t\t\t\tkey={ suggestion.slug }\n\t\t\t\t\t\t\tsuggestion={ suggestion }\n\t\t\t\t\t\t\tsearch={ debouncedSearch }\n\t\t\t\t\t\t\tonSelect={ onSelect }\n\t\t\t\t\t\t\tentityForSuggestions={ entityForSuggestions }\n\t\t\t\t\t\t\tcomposite={ composite }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) ) }\n\t\t\t\t</Composite>\n\t\t\t) }\n\t\t\t{ debouncedSearch && ! suggestions?.length && (\n\t\t\t\t<p className=\"edit-site-custom-template-modal__no-results\">\n\t\t\t\t\t{ labels.not_found }\n\t\t\t\t</p>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\nfunction AddCustomTemplateModal( { onClose, onSelect, entityForSuggestions } ) {\n\tconst [ showSearchEntities, setShowSearchEntities ] = useState(\n\t\tentityForSuggestions.hasGeneralTemplate\n\t);\n\tconst baseCssClass = 'edit-site-custom-template-modal';\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ sprintf(\n\t\t\t\t// translators: %s: Name of the post type e.g: \"Post\".\n\t\t\t\t__( 'Add template: %s' ),\n\t\t\t\tentityForSuggestions.labels.singular_name\n\t\t\t) }\n\t\t\tclassName={ baseCssClass }\n\t\t\tcloseLabel={ __( 'Close' ) }\n\t\t\tonRequestClose={ onClose }\n\t\t>\n\t\t\t{ ! showSearchEntities && (\n\t\t\t\t<>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Select whether to create a single template for all items or a specific one.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t\t<Flex\n\t\t\t\t\t\tclassName={ `${ baseCssClass }__contents` }\n\t\t\t\t\t\tgap=\"4\"\n\t\t\t\t\t\talign=\"initial\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<FlexItem\n\t\t\t\t\t\t\tisBlock\n\t\t\t\t\t\t\tas={ Button }\n\t\t\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\t\t\tslug,\n\t\t\t\t\t\t\t\t\ttitle,\n\t\t\t\t\t\t\t\t\tdescription,\n\t\t\t\t\t\t\t\t\ttemplatePrefix,\n\t\t\t\t\t\t\t\t} = entityForSuggestions.template;\n\t\t\t\t\t\t\t\tonSelect( {\n\t\t\t\t\t\t\t\t\tslug,\n\t\t\t\t\t\t\t\t\ttitle,\n\t\t\t\t\t\t\t\t\tdescription,\n\t\t\t\t\t\t\t\t\ttemplatePrefix,\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Text as=\"span\" weight={ 600 }>\n\t\t\t\t\t\t\t\t{ entityForSuggestions.labels.all_items }\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<Text as=\"span\">\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// translators: The user is given the choice to set up a template for all items of a post type or taxonomy, or just a specific one.\n\t\t\t\t\t\t\t\t\t__( 'For all items' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</FlexItem>\n\t\t\t\t\t\t<FlexItem\n\t\t\t\t\t\t\tisBlock\n\t\t\t\t\t\t\tas={ Button }\n\t\t\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\t\t\tsetShowSearchEntities( true );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Text as=\"span\" weight={ 600 }>\n\t\t\t\t\t\t\t\t{ entityForSuggestions.labels.singular_name }\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<Text as=\"span\">\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// translators: The user is given the choice to set up a template for all items of a post type or taxonomy, or just a specific one.\n\t\t\t\t\t\t\t\t\t__( 'For a specific item' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</FlexItem>\n\t\t\t\t\t</Flex>\n\t\t\t\t</>\n\t\t\t) }\n\t\t\t{ showSearchEntities && (\n\t\t\t\t<>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'This template will be used only for the specific item chosen.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</p>\n\t\t\t\t\t<SuggestionList\n\t\t\t\t\t\tentityForSuggestions={ entityForSuggestions }\n\t\t\t\t\t\tonSelect={ onSelect }\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default AddCustomTemplateModal;\n"]}
@@ -1,27 +1,24 @@
1
1
  import { createElement, Fragment } from "@wordpress/element";
2
2
 
3
- /**
4
- * External dependencies
5
- */
6
- import { filter, includes } from 'lodash';
7
3
  /**
8
4
  * WordPress dependencies
9
5
  */
10
-
6
+ import apiFetch from '@wordpress/api-fetch';
7
+ import { addQueryArgs } from '@wordpress/url';
11
8
  import { DropdownMenu, MenuGroup, MenuItem, NavigableMenu } from '@wordpress/components';
12
9
  import { useState } from '@wordpress/element';
13
- import { useSelect, useDispatch } from '@wordpress/data';
10
+ import { useDispatch } from '@wordpress/data';
14
11
  import { store as coreStore } from '@wordpress/core-data';
15
- import { store as editorStore } from '@wordpress/editor';
16
- import { archive, blockMeta, category, home, list, media, notFound, page, post, postAuthor, postDate, search, tag } from '@wordpress/icons';
17
- import { __, sprintf } from '@wordpress/i18n';
12
+ import { archive, blockMeta, category, home, list, media, notFound, page, post, postAuthor, postDate, search, tag, layout as customGenericTemplateIcon } from '@wordpress/icons';
13
+ import { __ } from '@wordpress/i18n';
18
14
  import { store as noticesStore } from '@wordpress/notices';
19
15
  /**
20
16
  * Internal dependencies
21
17
  */
22
18
 
23
19
  import AddCustomTemplateModal from './add-custom-template-modal';
24
- import { usePostTypes, usePostTypesEntitiesInfo } from './utils';
20
+ import { useExistingTemplates, useDefaultTemplateTypes, useTaxonomiesMenuItems, usePostTypeMenuItems, useAuthorMenuItem } from './utils';
21
+ import AddCustomGenericTemplateModal from './add-custom-generic-template-modal';
25
22
  import { useHistory } from '../routes';
26
23
  import { store as editSiteStore } from '../../store';
27
24
  const DEFAULT_TEMPLATE_SLUGS = ['front-page', 'single', 'page', 'index', 'archive', 'author', 'category', 'date', 'tag', 'taxonomy', 'search', '404'];
@@ -44,20 +41,10 @@ export default function NewTemplate(_ref) {
44
41
  let {
45
42
  postType
46
43
  } = _ref;
47
- const history = useHistory();
48
- const postTypes = usePostTypes();
49
44
  const [showCustomTemplateModal, setShowCustomTemplateModal] = useState(false);
45
+ const [showCustomGenericTemplateModal, setShowCustomGenericTemplateModal] = useState(false);
50
46
  const [entityForSuggestions, setEntityForSuggestions] = useState({});
51
- const {
52
- existingTemplates,
53
- defaultTemplateTypes
54
- } = useSelect(select => ({
55
- existingTemplates: select(coreStore).getEntityRecords('postType', 'wp_template', {
56
- per_page: -1
57
- }),
58
- defaultTemplateTypes: select(editorStore).__experimentalGetDefaultTemplateTypes()
59
- }), []);
60
- const postTypesEntitiesInfo = usePostTypesEntitiesInfo(existingTemplates);
47
+ const history = useHistory();
61
48
  const {
62
49
  saveEntityRecord
63
50
  } = useDispatch(coreStore);
@@ -69,20 +56,37 @@ export default function NewTemplate(_ref) {
69
56
  } = useDispatch(editSiteStore);
70
57
 
71
58
  async function createTemplate(template) {
59
+ let isWPSuggestion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
60
+
72
61
  try {
73
62
  const {
74
63
  title,
75
64
  description,
76
- slug
65
+ slug,
66
+ templatePrefix
77
67
  } = template;
68
+ let templateContent = template.content; // Try to find fallback content from existing templates.
69
+
70
+ if (!templateContent) {
71
+ const fallbackTemplate = await apiFetch({
72
+ path: addQueryArgs('/wp/v2/templates/lookup', {
73
+ slug,
74
+ is_custom: !isWPSuggestion,
75
+ template_prefix: templatePrefix
76
+ })
77
+ });
78
+ templateContent = fallbackTemplate.content;
79
+ }
80
+
78
81
  const newTemplate = await saveEntityRecord('postType', 'wp_template', {
79
82
  description,
80
83
  // Slugs need to be strings, so this is for template `404`
81
84
  slug: slug.toString(),
82
85
  status: 'publish',
83
86
  title,
87
+ content: templateContent,
84
88
  // This adds a post meta field in template that is part of `is_custom` value calculation.
85
- is_wp_suggestion: true
89
+ is_wp_suggestion: isWPSuggestion
86
90
  }, {
87
91
  throwOnError: true
88
92
  }); // Set template before navigating away to avoid initial stale value.
@@ -101,68 +105,12 @@ export default function NewTemplate(_ref) {
101
105
  }
102
106
  }
103
107
 
104
- const existingTemplateSlugs = (existingTemplates || []).map(_ref2 => {
105
- let {
106
- slug
107
- } = _ref2;
108
- return slug;
109
- });
110
- const missingTemplates = filter(defaultTemplateTypes, template => includes(DEFAULT_TEMPLATE_SLUGS, template.slug) && !includes(existingTemplateSlugs, template.slug));
111
- const extraTemplates = (postTypes || []).reduce((accumulator, _postType) => {
112
- var _postTypesEntitiesInf;
113
-
114
- const {
115
- slug,
116
- labels,
117
- icon
118
- } = _postType;
119
- const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(`single-${slug}`);
120
- const hasEntities = postTypesEntitiesInfo === null || postTypesEntitiesInfo === void 0 ? void 0 : (_postTypesEntitiesInf = postTypesEntitiesInfo[slug]) === null || _postTypesEntitiesInf === void 0 ? void 0 : _postTypesEntitiesInf.hasEntities;
121
- const menuItem = {
122
- slug: `single-${slug}`,
123
- title: sprintf( // translators: %s: Name of the post type e.g: "Post".
124
- __('Single item: %s'), labels.singular_name),
125
- description: sprintf( // translators: %s: Name of the post type e.g: "Post".
126
- __('Displays a single item: %s.'), labels.singular_name),
127
- // `icon` is the `menu_icon` property of a post type. We
128
- // only handle `dashicons` for now, even if the `menu_icon`
129
- // also supports urls and svg as values.
130
- icon: icon !== null && icon !== void 0 && icon.startsWith('dashicons-') ? icon.slice(10) : null
131
- }; // We have a different template creation flow only if they have entities.
132
-
133
- if (hasEntities) {
134
- menuItem.onClick = template => {
135
- setShowCustomTemplateModal(true);
136
- setEntityForSuggestions({
137
- type: 'postType',
138
- slug,
139
- labels,
140
- hasGeneralTemplate,
141
- template,
142
- postsToExclude: postTypesEntitiesInfo[slug].existingPosts
143
- });
144
- };
145
- } // We don't need to add the menu item if there are no
146
- // entities and the general template exists.
147
-
148
-
149
- if (!hasGeneralTemplate || hasEntities) {
150
- accumulator.push(menuItem);
151
- }
152
-
153
- return accumulator;
154
- }, []);
108
+ const missingTemplates = useMissingTemplates(setEntityForSuggestions, setShowCustomTemplateModal);
155
109
 
156
- if (!missingTemplates.length && !extraTemplates.length) {
110
+ if (!missingTemplates.length) {
157
111
  return null;
158
- } // Update the sort order to match the DEFAULT_TEMPLATE_SLUGS order.
159
-
160
-
161
- missingTemplates === null || missingTemplates === void 0 ? void 0 : missingTemplates.sort((template1, template2) => {
162
- return DEFAULT_TEMPLATE_SLUGS.indexOf(template1.slug) - DEFAULT_TEMPLATE_SLUGS.indexOf(template2.slug);
163
- }); // Append all extra templates at the end of the list for now.
112
+ }
164
113
 
165
- missingTemplates.push(...extraTemplates);
166
114
  return createElement(Fragment, null, createElement(DropdownMenu, {
167
115
  className: "edit-site-new-template-dropdown",
168
116
  icon: null,
@@ -193,10 +141,74 @@ export default function NewTemplate(_ref) {
193
141
  key: slug,
194
142
  onClick: () => onClick ? onClick(template) : createTemplate(template)
195
143
  }, title);
196
- })))), showCustomTemplateModal && createElement(AddCustomTemplateModal, {
144
+ })), createElement(MenuGroup, null, createElement(MenuItem, {
145
+ icon: customGenericTemplateIcon,
146
+ iconPosition: "left",
147
+ info: __('Custom templates can be applied to any post or page.'),
148
+ key: "custom-template",
149
+ onClick: () => setShowCustomGenericTemplateModal(true)
150
+ }, __('Custom template'))))), showCustomTemplateModal && createElement(AddCustomTemplateModal, {
197
151
  onClose: () => setShowCustomTemplateModal(false),
198
152
  onSelect: createTemplate,
199
153
  entityForSuggestions: entityForSuggestions
154
+ }), showCustomGenericTemplateModal && createElement(AddCustomGenericTemplateModal, {
155
+ onClose: () => setShowCustomGenericTemplateModal(false),
156
+ createTemplate: createTemplate
200
157
  }));
201
158
  }
159
+
160
+ function useMissingTemplates(setEntityForSuggestions, setShowCustomTemplateModal) {
161
+ const existingTemplates = useExistingTemplates();
162
+ const defaultTemplateTypes = useDefaultTemplateTypes();
163
+ const existingTemplateSlugs = (existingTemplates || []).map(_ref2 => {
164
+ let {
165
+ slug
166
+ } = _ref2;
167
+ return slug;
168
+ });
169
+ const missingDefaultTemplates = (defaultTemplateTypes || []).filter(template => DEFAULT_TEMPLATE_SLUGS.includes(template.slug) && !existingTemplateSlugs.includes(template.slug));
170
+
171
+ const onClickMenuItem = _entityForSuggestions => {
172
+ setShowCustomTemplateModal(true);
173
+ setEntityForSuggestions(_entityForSuggestions);
174
+ }; // We need to replace existing default template types with
175
+ // the create specific template functionality. The original
176
+ // info (title, description, etc.) is preserved in the
177
+ // used hooks.
178
+
179
+
180
+ const enhancedMissingDefaultTemplateTypes = [...missingDefaultTemplates];
181
+ const {
182
+ defaultTaxonomiesMenuItems,
183
+ taxonomiesMenuItems
184
+ } = useTaxonomiesMenuItems(onClickMenuItem);
185
+ const {
186
+ defaultPostTypesMenuItems,
187
+ postTypesMenuItems
188
+ } = usePostTypeMenuItems(onClickMenuItem);
189
+ const authorMenuItem = useAuthorMenuItem(onClickMenuItem);
190
+ [...defaultTaxonomiesMenuItems, ...defaultPostTypesMenuItems, authorMenuItem].forEach(menuItem => {
191
+ if (!menuItem) {
192
+ return;
193
+ }
194
+
195
+ const matchIndex = enhancedMissingDefaultTemplateTypes.findIndex(template => template.slug === menuItem.slug); // Some default template types might have been filtered above from
196
+ // `missingDefaultTemplates` because they only check for the general
197
+ // template. So here we either replace or append the item, augmented
198
+ // with the check if it has available specific item to create a
199
+ // template for.
200
+
201
+ if (matchIndex > -1) {
202
+ enhancedMissingDefaultTemplateTypes[matchIndex] = menuItem;
203
+ } else {
204
+ enhancedMissingDefaultTemplateTypes.push(menuItem);
205
+ }
206
+ }); // Update the sort order to match the DEFAULT_TEMPLATE_SLUGS order.
207
+
208
+ enhancedMissingDefaultTemplateTypes === null || enhancedMissingDefaultTemplateTypes === void 0 ? void 0 : enhancedMissingDefaultTemplateTypes.sort((template1, template2) => {
209
+ return DEFAULT_TEMPLATE_SLUGS.indexOf(template1.slug) - DEFAULT_TEMPLATE_SLUGS.indexOf(template2.slug);
210
+ });
211
+ const missingTemplates = [...enhancedMissingDefaultTemplateTypes, ...postTypesMenuItems, ...taxonomiesMenuItems];
212
+ return missingTemplates;
213
+ }
202
214
  //# sourceMappingURL=new-template.js.map