"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.PageAttributesParent = PageAttributesParent;
exports.ParentRow = ParentRow;
exports.getItemPriority = exports.default = void 0;
var _removeAccents = _interopRequireDefault(require("remove-accents"));
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _compose = require("@wordpress/compose");
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _htmlEntities = require("@wordpress/html-entities");
var _coreData = require("@wordpress/core-data");
var _blockEditor = require("@wordpress/block-editor");
var _url = require("@wordpress/url");
var _postPanelRow = _interopRequireDefault(require("../post-panel-row"));
var _terms = require("../../utils/terms");
var _store = require("../../store");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

function getTitle(post) {
  return post?.title?.rendered ? (0, _htmlEntities.decodeEntities)(post.title.rendered) : `#${post.id} (${(0, _i18n.__)('no title')})`;
}
const getItemPriority = (name, searchValue) => {
  const normalizedName = (0, _removeAccents.default)(name || '').toLowerCase();
  const normalizedSearch = (0, _removeAccents.default)(searchValue || '').toLowerCase();
  if (normalizedName === normalizedSearch) {
    return 0;
  }
  if (normalizedName.startsWith(normalizedSearch)) {
    return normalizedName.length;
  }
  return Infinity;
};

/**
 * Renders the Page Attributes Parent component. A dropdown menu in an editor interface
 * for selecting the parent page of a given page.
 *
 * @return {Component|null} The component to be rendered. Return null if post type is not hierarchical.
 */
exports.getItemPriority = getItemPriority;
function PageAttributesParent() {
  const {
    editPost
  } = (0, _data.useDispatch)(_store.store);
  const [fieldValue, setFieldValue] = (0, _element.useState)(false);
  const {
    isHierarchical,
    parentPostId,
    parentPostTitle,
    pageItems
  } = (0, _data.useSelect)(select => {
    var _pType$hierarchical;
    const {
      getPostType,
      getEntityRecords,
      getEntityRecord
    } = select(_coreData.store);
    const {
      getCurrentPostId,
      getEditedPostAttribute
    } = select(_store.store);
    const postTypeSlug = getEditedPostAttribute('type');
    const pageId = getEditedPostAttribute('parent');
    const pType = getPostType(postTypeSlug);
    const postId = getCurrentPostId();
    const postIsHierarchical = (_pType$hierarchical = pType?.hierarchical) !== null && _pType$hierarchical !== void 0 ? _pType$hierarchical : false;
    const query = {
      per_page: 100,
      exclude: postId,
      parent_exclude: postId,
      orderby: 'menu_order',
      order: 'asc',
      _fields: 'id,title,parent'
    };

    // Perform a search when the field is changed.
    if (!!fieldValue) {
      query.search = fieldValue;
    }
    const parentPost = pageId ? getEntityRecord('postType', postTypeSlug, pageId) : null;
    return {
      isHierarchical: postIsHierarchical,
      parentPostId: pageId,
      parentPostTitle: parentPost ? getTitle(parentPost) : '',
      pageItems: postIsHierarchical ? getEntityRecords('postType', postTypeSlug, query) : null
    };
  }, [fieldValue]);
  const parentOptions = (0, _element.useMemo)(() => {
    const getOptionsFromTree = (tree, level = 0) => {
      const mappedNodes = tree.map(treeNode => [{
        value: treeNode.id,
        label: '— '.repeat(level) + (0, _htmlEntities.decodeEntities)(treeNode.name),
        rawName: treeNode.name
      }, ...getOptionsFromTree(treeNode.children || [], level + 1)]);
      const sortedNodes = mappedNodes.sort(([a], [b]) => {
        const priorityA = getItemPriority(a.rawName, fieldValue);
        const priorityB = getItemPriority(b.rawName, fieldValue);
        return priorityA >= priorityB ? 1 : -1;
      });
      return sortedNodes.flat();
    };
    if (!pageItems) {
      return [];
    }
    let tree = pageItems.map(item => ({
      id: item.id,
      parent: item.parent,
      name: getTitle(item)
    }));

    // Only build a hierarchical tree when not searching.
    if (!fieldValue) {
      tree = (0, _terms.buildTermsTree)(tree);
    }
    const opts = getOptionsFromTree(tree);

    // Ensure the current parent is in the options list.
    const optsHasParent = opts.find(item => item.value === parentPostId);
    if (parentPostTitle && !optsHasParent) {
      opts.unshift({
        value: parentPostId,
        label: parentPostTitle
      });
    }
    return opts;
  }, [pageItems, fieldValue, parentPostTitle, parentPostId]);
  if (!isHierarchical) {
    return null;
  }
  /**
   * Handle user input.
   *
   * @param {string} inputValue The current value of the input field.
   */
  const handleKeydown = inputValue => {
    setFieldValue(inputValue);
  };

  /**
   * Handle author selection.
   *
   * @param {Object} selectedPostId The selected Author.
   */
  const handleChange = selectedPostId => {
    editPost({
      parent: selectedPostId
    });
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ComboboxControl, {
    __nextHasNoMarginBottom: true,
    __next40pxDefaultSize: true,
    className: "editor-page-attributes__parent",
    label: (0, _i18n.__)('Parent'),
    help: (0, _i18n.__)('Choose a parent page.'),
    value: parentPostId,
    options: parentOptions,
    onFilterValueChange: (0, _compose.debounce)(handleKeydown, 300),
    onChange: handleChange,
    hideLabelFromVision: true
  });
}
function PostParentToggle({
  isOpen,
  onClick
}) {
  const parentPost = (0, _data.useSelect)(select => {
    const {
      getEditedPostAttribute
    } = select(_store.store);
    const parentPostId = getEditedPostAttribute('parent');
    if (!parentPostId) {
      return null;
    }
    const {
      getEntityRecord
    } = select(_coreData.store);
    const postTypeSlug = getEditedPostAttribute('type');
    return getEntityRecord('postType', postTypeSlug, parentPostId);
  }, []);
  const parentTitle = (0, _element.useMemo)(() => !parentPost ? (0, _i18n.__)('None') : getTitle(parentPost), [parentPost]);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
    size: "compact",
    className: "editor-post-parent__panel-toggle",
    variant: "tertiary",
    "aria-expanded": isOpen
    // translators: %s: Current post parent.
    ,
    "aria-label": (0, _i18n.sprintf)((0, _i18n.__)('Change parent: %s'), parentTitle),
    onClick: onClick,
    children: parentTitle
  });
}
function ParentRow() {
  const homeUrl = (0, _data.useSelect)(select => {
    // Site index.
    return select(_coreData.store).getEntityRecord('root', '__unstableBase')?.home;
  }, []);
  // Use internal state instead of a ref to make sure that the component
  // re-renders when the popover's anchor updates.
  const [popoverAnchor, setPopoverAnchor] = (0, _element.useState)(null);
  // Memoize popoverProps to avoid returning a new object every time.
  const popoverProps = (0, _element.useMemo)(() => ({
    // Anchor the popover to the middle of the entire row so that it doesn't
    // move around when the label changes.
    anchor: popoverAnchor,
    placement: 'left-start',
    offset: 36,
    shift: true
  }), [popoverAnchor]);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_postPanelRow.default, {
    label: (0, _i18n.__)('Parent'),
    ref: setPopoverAnchor,
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Dropdown, {
      popoverProps: popoverProps,
      className: "editor-post-parent__panel-dropdown",
      contentClassName: "editor-post-parent__panel-dialog",
      focusOnMount: true,
      renderToggle: ({
        isOpen,
        onToggle
      }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(PostParentToggle, {
        isOpen: isOpen,
        onClick: onToggle
      }),
      renderContent: ({
        onClose
      }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
        className: "editor-post-parent",
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.__experimentalInspectorPopoverHeader, {
          title: (0, _i18n.__)('Parent'),
          onClose: onClose
        }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
          children: [(0, _element.createInterpolateElement)((0, _i18n.sprintf)( /* translators: %1$s The home URL of the WordPress installation without the scheme. */
          (0, _i18n.__)('Child pages inherit characteristics from their parent, such as URL structure. For instance, if "Pricing" is a child of "Services", its URL would be %1$s<wbr />/services<wbr />/pricing.'), (0, _url.filterURLForDisplay)(homeUrl).replace(/([/.])/g, '<wbr />$1')), {
            wbr: /*#__PURE__*/(0, _jsxRuntime.jsx)("wbr", {})
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
            children: (0, _element.createInterpolateElement)((0, _i18n.__)('They also show up as sub-items in the default navigation menu. <a>Learn more.</a>'), {
              a: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ExternalLink, {
                href: (0, _i18n.__)('https://wordpress.org/documentation/article/page-post-settings-sidebar/#page-attributes')
              })
            })
          })]
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)(PageAttributesParent, {})]
      })
    })
  });
}
var _default = exports.default = PageAttributesParent;
//# sourceMappingURL=parent.js.map