UNPKG

@wordpress/editor

Version:
181 lines (180 loc) 6.02 kB
// packages/editor/src/components/post-revisions-timeline/index.js import { useSelect, useDispatch } from "@wordpress/data"; import { store as coreStore } from "@wordpress/core-data"; import { DataViewsPicker, filterSortAndPaginate } from "@wordpress/dataviews"; import { dateI18n, getDate, humanTimeDiff, getSettings } from "@wordpress/date"; import { useCallback, useEffect, useMemo, useState } from "@wordpress/element"; import { __, sprintf } from "@wordpress/i18n"; import { authorField } from "@wordpress/fields"; import { Badge, Stack, Text } from "@wordpress/ui"; import { store as editorStore } from "../../store/index.mjs"; import { unlock } from "../../lock-unlock.mjs"; import { PostContentInformationUI } from "../post-content-information/index.mjs"; import { jsx, jsxs } from "react/jsx-runtime"; var PAGE_SIZE = 10; var EMPTY_ARRAY = []; var defaultLayouts = { pickerActivity: true }; var baseView = { type: "pickerActivity", titleField: "date", descriptionField: "details", fields: ["author"], layout: { density: "compact" }, page: 1, perPage: PAGE_SIZE }; var DAY_IN_MILLISECONDS = 864e5; function getDisplayDate(value) { const dateNowInMs = getDate(null).getTime(); const date = getDate(value ?? null); return dateNowInMs - date.getTime() > DAY_IN_MILLISECONDS ? dateI18n(getSettings().formats.datetimeAbbreviated, date) : humanTimeDiff(date); } function isAutosaveRevision(item) { return item.slug?.endsWith("-autosave-v1") ?? false; } function RevisionBadges({ item }) { if (!isAutosaveRevision(item)) { return null; } return /* @__PURE__ */ jsx(Badge, { intent: "none", children: __("Autosave") }); } function PostRevisionsTimeline() { const { setCurrentRevisionId } = unlock(useDispatch(editorStore)); const [view, setView] = useState(baseView); const { revisions, revisionKey, currentRevisionId } = useSelect( (select) => { const { getCurrentPostType } = select(editorStore); const { getCurrentRevisionId: _getCurrentRevisionId, getRevisionPage, getPageRevisions } = unlock(select(editorStore)); const { getEntityConfig } = select(coreStore); const _postType = getCurrentPostType(); const entityConfig = getEntityConfig("postType", _postType); const _revisionKey = entityConfig?.revisionKey || "id"; const _currentRevisionId = _getCurrentRevisionId(); return { // Same desc-ordered window the header slider renders (warm cache). revisions: getPageRevisions(getRevisionPage()), revisionKey: _revisionKey, currentRevisionId: _currentRevisionId }; }, [] ); const isLoading = !revisions; const fields = useMemo( () => [ { id: "date", label: __("Date"), // Return the humanized label the row renders so the picker // option's accessible name announces e.g. "5 minutes ago" // instead of the raw ISO timestamp. getValue: ({ item }) => { const displayDate = getDisplayDate(item.date); if (!isAutosaveRevision(item)) { return displayDate; } return sprintf( /* translators: 1: revision date, 2: revision type. */ __("%1$s, %2$s"), displayDate, __("Autosave") ); }, render: ({ item }) => /* @__PURE__ */ jsxs(Stack, { direction: "row", align: "center", gap: "sm", children: [ /* @__PURE__ */ jsx( Text, { variant: "heading-sm", render: /* @__PURE__ */ jsx("time", { dateTime: item.date }), children: getDisplayDate(item.date) } ), /* @__PURE__ */ jsx(RevisionBadges, { item }) ] }), enableSorting: false, enableHiding: false }, authorField, { id: "details", label: __("Details"), render: ({ item }) => { if (String(item[revisionKey]) !== String(currentRevisionId)) { return null; } return /* @__PURE__ */ jsx( PostContentInformationUI, { postContent: item.content?.raw } ); }, enableSorting: false, enableHiding: false } ], [revisionKey, currentRevisionId] ); const { data: shownRevisions, paginationInfo } = useMemo( () => filterSortAndPaginate(revisions || EMPTY_ARRAY, view, fields), [revisions, view, fields] ); useEffect(() => { if (!currentRevisionId || !revisions) { return; } const index = revisions.findIndex( (r) => String(r[revisionKey]) === String(currentRevisionId) ); if (index < 0) { return; } const page = Math.floor(index / view.perPage) + 1; setView((v) => v.page === page ? v : { ...v, page }); }, [currentRevisionId, revisions, revisionKey, view.perPage]); const selection = useMemo( () => currentRevisionId ? [String(currentRevisionId)] : EMPTY_ARRAY, [currentRevisionId] ); const onChangeSelection = useCallback( (newSelection) => { if (newSelection.length === 0) { return; } const selectedId = newSelection[newSelection.length - 1]; setCurrentRevisionId(Number(selectedId)); }, [setCurrentRevisionId] ); const getItemId = useCallback( (item) => String(item[revisionKey]), [revisionKey] ); return /* @__PURE__ */ jsx("div", { className: "editor-post-revisions-timeline", children: /* @__PURE__ */ jsxs( DataViewsPicker, { view, onChangeView: setView, fields, data: shownRevisions, isLoading, paginationInfo, defaultLayouts, getItemId, selection, onChangeSelection, children: [ /* @__PURE__ */ jsx(DataViewsPicker.Layout, {}), /* @__PURE__ */ jsx(DataViewsPicker.Footer, {}) ] } ) }); } export { PostRevisionsTimeline as default }; //# sourceMappingURL=index.mjs.map