@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
181 lines (180 loc) • 6.02 kB
JavaScript
// 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