"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = TemplatePartEdit;
var _blocks = require("@wordpress/blocks");
var _data = require("@wordpress/data");
var _blockEditor = require("@wordpress/block-editor");
var _components = require("@wordpress/components");
var _compose = require("@wordpress/compose");
var _i18n = require("@wordpress/i18n");
var _coreData = require("@wordpress/core-data");
var _element = require("@wordpress/element");
var _notices = require("@wordpress/notices");
var _placeholder = _interopRequireDefault(require("./placeholder"));
var _selectionModal = _interopRequireDefault(require("./selection-modal"));
var _advancedControls = require("./advanced-controls");
var _innerBlocks = _interopRequireDefault(require("./inner-blocks"));
var _createTemplatePartId = require("./utils/create-template-part-id");
var _hooks = require("./utils/hooks");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

function ReplaceButton({
  isEntityAvailable,
  area,
  templatePartId,
  isTemplatePartSelectionOpen,
  setIsTemplatePartSelectionOpen
}) {
  // This hook fetches patterns, so don't run it unconditionally in the main
  // edit function!
  const {
    templateParts
  } = (0, _hooks.useAlternativeTemplateParts)(area, templatePartId);
  const hasReplacements = !!templateParts.length;
  const canReplace = isEntityAvailable && hasReplacements && (area === 'header' || area === 'footer');
  if (!canReplace) {
    return null;
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
    onClick: () => {
      setIsTemplatePartSelectionOpen(true);
    },
    "aria-expanded": isTemplatePartSelectionOpen,
    "aria-haspopup": "dialog",
    children: (0, _i18n.__)('Replace')
  });
}
function TemplatesList({
  area,
  clientId,
  isEntityAvailable,
  onSelect
}) {
  // This hook fetches patterns, so don't run it unconditionally in the main
  // edit function!
  const blockPatterns = (0, _hooks.useAlternativeBlockPatterns)(area, clientId);
  const canReplace = isEntityAvailable && !!blockPatterns.length && (area === 'header' || area === 'footer');
  const shownTemplates = (0, _compose.useAsyncList)(blockPatterns);
  if (!canReplace) {
    return null;
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.PanelBody, {
    title: (0, _i18n.__)('Design'),
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.__experimentalBlockPatternsList, {
      label: (0, _i18n.__)('Templates'),
      blockPatterns: blockPatterns,
      shownPatterns: shownTemplates,
      onClickPattern: onSelect,
      showTitle: false
    })
  });
}
function TemplatePartEdit({
  attributes,
  setAttributes,
  clientId
}) {
  const {
    createSuccessNotice
  } = (0, _data.useDispatch)(_notices.store);
  const {
    editEntityRecord
  } = (0, _data.useDispatch)(_coreData.store);
  const currentTheme = (0, _data.useSelect)(select => select(_coreData.store).getCurrentTheme()?.stylesheet, []);
  const {
    slug,
    theme = currentTheme,
    tagName,
    layout = {}
  } = attributes;
  const templatePartId = (0, _createTemplatePartId.createTemplatePartId)(theme, slug);
  const hasAlreadyRendered = (0, _blockEditor.useHasRecursion)(templatePartId);
  const [isTemplatePartSelectionOpen, setIsTemplatePartSelectionOpen] = (0, _element.useState)(false);
  const {
    isResolved,
    hasInnerBlocks,
    isMissing,
    area,
    onNavigateToEntityRecord,
    title,
    canUserEdit
  } = (0, _data.useSelect)(select => {
    const {
      getEditedEntityRecord,
      hasFinishedResolution
    } = select(_coreData.store);
    const {
      getBlockCount,
      getSettings
    } = select(_blockEditor.store);
    const getEntityArgs = ['postType', 'wp_template_part', templatePartId];
    const entityRecord = templatePartId ? getEditedEntityRecord(...getEntityArgs) : null;
    const _area = entityRecord?.area || attributes.area;
    const hasResolvedEntity = templatePartId ? hasFinishedResolution('getEditedEntityRecord', getEntityArgs) : false;
    const _canUserEdit = hasResolvedEntity ? select(_coreData.store).canUser('update', {
      kind: 'postType',
      name: 'wp_template_part',
      id: templatePartId
    }) : false;
    return {
      hasInnerBlocks: getBlockCount(clientId) > 0,
      isResolved: hasResolvedEntity,
      isMissing: hasResolvedEntity && (!entityRecord || Object.keys(entityRecord).length === 0),
      area: _area,
      onNavigateToEntityRecord: getSettings().onNavigateToEntityRecord,
      title: entityRecord?.title,
      canUserEdit: !!_canUserEdit
    };
  }, [templatePartId, attributes.area, clientId]);
  const areaObject = (0, _hooks.useTemplatePartArea)(area);
  const blockProps = (0, _blockEditor.useBlockProps)();
  const isPlaceholder = !slug;
  const isEntityAvailable = !isPlaceholder && !isMissing && isResolved;
  const TagName = tagName || areaObject.tagName;
  const onPatternSelect = async pattern => {
    await editEntityRecord('postType', 'wp_template_part', templatePartId, {
      blocks: pattern.blocks,
      content: (0, _blocks.serialize)(pattern.blocks)
    });
    createSuccessNotice((0, _i18n.sprintf)( /* translators: %s: template part title. */
    (0, _i18n.__)('Template Part "%s" updated.'), title || slug), {
      type: 'snackbar'
    });
  };

  // We don't want to render a missing state if we have any inner blocks.
  // A new template part is automatically created if we have any inner blocks but no entity.
  if (!hasInnerBlocks && (slug && !theme || slug && isMissing)) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(TagName, {
      ...blockProps,
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.Warning, {
        children: (0, _i18n.sprintf)( /* translators: %s: Template part slug */
        (0, _i18n.__)('Template part has been deleted or is unavailable: %s'), slug)
      })
    });
  }
  if (isEntityAvailable && hasAlreadyRendered) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(TagName, {
      ...blockProps,
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.Warning, {
        children: (0, _i18n.__)('Block cannot be rendered inside itself.')
      })
    });
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_blockEditor.RecursionProvider, {
      uniqueId: templatePartId,
      children: [isEntityAvailable && onNavigateToEntityRecord && canUserEdit && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockControls, {
        group: "other",
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, {
          onClick: () => onNavigateToEntityRecord({
            postId: templatePartId,
            postType: 'wp_template_part'
          }),
          children: (0, _i18n.__)('Edit')
        })
      }), canUserEdit && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.InspectorControls, {
        group: "advanced",
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_advancedControls.TemplatePartAdvancedControls, {
          tagName: tagName,
          setAttributes: setAttributes,
          isEntityAvailable: isEntityAvailable,
          templatePartId: templatePartId,
          defaultWrapper: areaObject.tagName,
          hasInnerBlocks: hasInnerBlocks
        })
      }), isPlaceholder && /*#__PURE__*/(0, _jsxRuntime.jsx)(TagName, {
        ...blockProps,
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_placeholder.default, {
          area: attributes.area,
          templatePartId: templatePartId,
          clientId: clientId,
          setAttributes: setAttributes,
          onOpenSelectionModal: () => setIsTemplatePartSelectionOpen(true)
        })
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockSettingsMenuControls, {
        children: ({
          selectedClientIds
        }) => {
          // Only enable for single selection that matches the current block.
          // Ensures menu item doesn't render multiple times.
          if (!(selectedClientIds.length === 1 && clientId === selectedClientIds[0])) {
            return null;
          }
          return /*#__PURE__*/(0, _jsxRuntime.jsx)(ReplaceButton, {
            isEntityAvailable,
            area,
            clientId,
            templatePartId,
            isTemplatePartSelectionOpen,
            setIsTemplatePartSelectionOpen
          });
        }
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.InspectorControls, {
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(TemplatesList, {
          area: area,
          clientId: clientId,
          isEntityAvailable: isEntityAvailable,
          onSelect: pattern => onPatternSelect(pattern)
        })
      }), isEntityAvailable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_innerBlocks.default, {
        tagName: TagName,
        blockProps: blockProps,
        postId: templatePartId,
        hasInnerBlocks: hasInnerBlocks,
        layout: layout
      }), !isPlaceholder && !isResolved && /*#__PURE__*/(0, _jsxRuntime.jsx)(TagName, {
        ...blockProps,
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Spinner, {})
      })]
    }), isTemplatePartSelectionOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Modal, {
      overlayClassName: "block-editor-template-part__selection-modal",
      title: (0, _i18n.sprintf)(
      // Translators: %s as template part area title ("Header", "Footer", etc.).
      (0, _i18n.__)('Choose a %s'), areaObject.label.toLowerCase()),
      onRequestClose: () => setIsTemplatePartSelectionOpen(false),
      isFullScreen: true,
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_selectionModal.default, {
        templatePartId: templatePartId,
        clientId: clientId,
        area: area,
        setAttributes: setAttributes,
        onClose: () => setIsTemplatePartSelectionOpen(false)
      })
    })]
  });
}
//# sourceMappingURL=index.js.map