sanity
Version:
Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches
1,056 lines • 309 kB
JavaScript
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
import { c } from "react/compiler-runtime";
import { IntentLink, useRouter, RouterContext } from "sanity/router";
import { ErrorOutlineIcon } from "@sanity/icons/ErrorOutline";
import { Card, Flex, Stack, Text, Box, useToast, useClickOutsideEvent, Spinner, TabList, Container, Checkbox, MenuDivider, Menu, Button as Button$1, LayerProvider, PortalProvider, Skeleton, Label, Badge, Inline, useMediaIndex } from "@sanity/ui";
import { motion, AnimatePresence } from "motion/react";
import { forwardRef, memo, useRef, useMemo, useEffect, useState } from "react";
import { getReleaseIdFromReleaseDocumentId, applyMendozaPatch, getTransactionsLogs, RELEASES_STUDIO_CLIENT_OPTIONS, useClient, useDocumentPreviewStore, useReleasesStore, useSource, getReleaseDocumentIdFromReleaseId, useDocumentPresence, DocumentPreviewPresence, useDocumentPreviewValues, SanityDefaultPreview, useTranslation, releasesLocaleNamespace, UserAvatar, useDateTimeFormat, useRelativeTime, Translate, LoadingBlock, Resizable, useProjectSubscriptions, useTimeZone, CONTENT_RELEASES_TIME_ZONE_SCOPE, useReleaseOperations, useReleasePermissions, TitleDescriptionForm, getIsReleaseOpen, getPublishDateFromRelease, isReleaseScheduledOrScheduling, ARCHIVED_RELEASE_STATES, LazyTextInput, getCalendarLabels, getReleaseTone, DatePicker, MONTH_PICKER_VARIANT, getIsScheduledDateInPast, ReleaseAvatar, isGoingToUnpublish, usePerspective, useSetPerspective, useWorkspace, isNotArchivedRelease, ToneIcon, TextWithTone, Details, PublishedRelease, isReleaseDocument, useReleasesUpsell, getReleaseDefaults, createReleaseId, RevertRelease, isReleaseLimitError, TimeZoneButtonElementQuery$1 as TimeZoneButtonElementQuery, TimeZoneButton, DateTimeInput, ScheduledRelease, UnscheduledRelease, GetHookCollectionState, DuplicatedRelease, UnarchivedRelease, ArchivedRelease, DeletedRelease, ReleaseTitle, RelativeTime, isNonNullable, AvatarSkeleton, useStudioUrl, ReleaseLinkCopied, ReleaseIdCopied, ReleaseTitleCopied, SearchProvider, SearchPopover, useDocumentPairPermissions, DiscardVersionDialog, UnpublishVersionDialog, useSchema, ContextMenuButton, isCardinalityOneRelease, getDocumentVariantType, AddedVersion, useActiveReleases, useArchivedReleases, useReleaseDocuments, NavigatedToReleasesOverview, NavigatedToScheduledDrafts, shouldShowReleaseInView, PREVIEW_SIZES, TitleSkeleton, useScheduledDraftDocument, useScheduledDraftMenuActions, isPausedCardinalityOneRelease, singleDocReleaseNamespace, useSingleDocReleaseEnabled, useSingleDocReleaseUpsell, UpsellPanel, useScheduledDraftsEnabled, useDialogTimeZone, filterReleasesForOverview, CreateReleaseDialog } from "./index2.js";
import "history";
import "sanity/_singletons";
import "@sanity/icons/ArrowLeft";
import "@sanity/icons/Launch";
import { styled } from "styled-components";
import { Button, Popover, Tab, Tooltip, MenuItem, Dialog, MenuButton } from "./index.js";
import "react-i18next";
import { switchMap, map, startWith, scan, tap, shareReplay, catchError } from "rxjs/operators";
import { useObservable } from "react-rx";
import { BehaviorSubject, filter, distinctUntilChanged, switchMap as switchMap$1, map as map$1, catchError as catchError$1, of, startWith as startWith$1, scan as scan$1, shareReplay as shareReplay$1, expand, reduce, tap as tap$1, from, skip, merge, combineLatest, forkJoin } from "rxjs";
import { getPublishedId, getVersionFromId, getVersionId } from "@sanity/client/csm";
import "quick-lru";
import "lodash-es/throttle.js";
import isEqual from "lodash-es/isEqual.js";
import "@sanity/logos";
import { ChevronRightIcon } from "@sanity/icons/ChevronRight";
import "@sanity/client";
import "./version.js";
import "@sanity/icons/Checkmark";
import "react-is";
import "@sanity/icons/Document";
import "@sanity/icons/Image";
import "@sanity/uuid";
import "@sanity/color";
import "color2k";
import "lodash-es/isString.js";
import { CopyIcon } from "@sanity/icons/Copy";
import "@sanity/icons/Clipboard";
import "./createAgentBundlesStore.js";
import { useTelemetry } from "@sanity/telemetry/react";
import "@portabletext/editor";
import { toString } from "@sanity/util/paths";
import "@sanity/types";
import "@sanity/icons/Revert";
import "@sanity/ui/theme";
import "date-fns/differenceInDays";
import "date-fns/differenceInHours";
import "date-fns/differenceInMinutes";
import "date-fns/differenceInMonths";
import "date-fns/differenceInSeconds";
import "date-fns/differenceInWeeks";
import "date-fns/differenceInYears";
import "@sanity/icons/AddCircle";
import { CalendarIcon } from "@sanity/icons/Calendar";
import "@sanity/icons/Circle";
import { CloseIcon } from "@sanity/icons/Close";
import "@sanity/icons/Edit";
import { PublishIcon } from "@sanity/icons/Publish";
import "@sanity/icons/Timeline";
import { TrashIcon } from "@sanity/icons/Trash";
import { UnpublishIcon } from "@sanity/icons/Unpublish";
import "@sanity/icons/ArrowDown";
import "@sanity/icons/ArrowRight";
import "@sanity/util/legacyDateFormat";
import "@sanity/diff-patch";
import "@sanity/diff";
import "mendoza";
import { InfoOutlineIcon } from "@sanity/icons/InfoOutline";
import { WarningOutlineIcon } from "@sanity/icons/WarningOutline";
import "@portabletext/sanity-bridge";
import "@sanity/id-utils";
import { ChevronDownIcon } from "@sanity/icons/ChevronDown";
import "date-fns/addHours";
import "date-fns/startOfHour";
import "@sanity/icons/Bolt";
import { ClockIcon } from "@sanity/icons/Clock";
import "@sanity/icons/Dot";
import { EarthGlobeIcon } from "@sanity/icons/EarthGlobe";
import { format } from "date-fns/format";
import { isValid } from "date-fns/isValid";
import { parse } from "date-fns/parse";
import "lodash-es/flatten.js";
import "date-fns/getMinutes";
import "date-fns/parseISO";
import "date-fns/setMinutes";
import "react-fast-compare";
import "clsx";
import "@sanity/icons/EarthAmericas";
import "lodash-es/noop.js";
import "@sanity/icons/Search";
import "lodash-es/pick.js";
import "lodash-es/get.js";
import "@algorithm.ts/lcs";
import "lodash-es/intersection.js";
import "json-stable-stringify";
import "shallow-equals";
import "scroll-into-view-if-needed";
import "@sanity/schema/_internal";
import "lodash-es/groupBy.js";
import "lodash-es/sortBy.js";
import "lodash-es/compact.js";
import "lodash-es/keyBy.js";
import "lodash-es/partition.js";
import "lodash-es/toLower.js";
import "lodash-es/union.js";
import "lodash-es/uniq.js";
import "lodash-es/words.js";
import "lodash-es/isFinite.js";
import { AddIcon } from "@sanity/icons/Add";
import "observable-callback";
import "@sanity/util/content";
import "@sanity/icons/BulbOutline";
import "@sanity/icons/Unknown";
import "@sanity/icons/ToggleArrowRight";
import "lodash-es/isPlainObject.js";
import "@sanity/insert-menu";
import "@dnd-kit/sortable";
import "@sanity/icons/DragHandle";
import "@sanity/icons/AddDocument";
import "@sanity/icons/InsertAbove";
import "@sanity/icons/InsertBelow";
import { useVirtualizer } from "@tanstack/react-virtual";
import "lodash-es/startCase.js";
import "speakingurl";
import "@portabletext/react";
import "@sanity/icons/LinkRemoved";
import "@sanity/asset-utils";
import "@sanity/icons/AccessDenied";
import "@sanity/icons/HelpCircle";
import "@sanity/image-url";
import "nanoid";
import "lodash-es/castArray.js";
import "rxjs-mergemap-array";
import "@sanity/mutator";
import "lodash-es/findIndex.js";
import "@sanity/diff-match-patch";
import "@sanity/icons";
import { LinkIcon } from "@sanity/icons/Link";
import "@sanity/icons/ChevronUp";
import "@sanity/icons/EyeOpen";
import "@sanity/icons/Feedback";
import "@xstate/react";
import "xstate";
import "@sanity/icons/FaceHappy";
import "@sanity/icons/FaceIndifferent";
import "@sanity/icons/FaceSad";
import "@sentry/react";
import { isBefore } from "date-fns/isBefore";
import { startOfMinute } from "date-fns/startOfMinute";
import "@sanity/icons/Documents";
import "@portabletext/toolkit";
import "lodash-es/debounce.js";
import "@sanity/icons/User";
import { CheckmarkCircleIcon } from "@sanity/icons/CheckmarkCircle";
import "lodash-es/deburr.js";
import "react-focus-lock";
import "@sanity/icons/ChevronLeft";
import "@sanity/schema";
import "@sanity/util/client";
import "@sanity/util/concurrency-limiter";
import "lodash-es/uniqBy.js";
import "json-reduce";
import "rxjs-exhaustmap-with-trailing";
import "@sanity/icons/Reset";
import "@sanity/icons/Sync";
import "lodash-es/pickBy.js";
import "swr";
import "@sanity/icons/Download";
import "@sanity/icons/Upload";
import "@sanity/icons/BinaryDocument";
import { LockIcon } from "@sanity/icons/Lock";
import "use-hot-module-reload";
import { EllipsisHorizontalIcon } from "@sanity/icons/EllipsisHorizontal";
import "lodash-es/memoize.js";
import "lodash-es/sortedIndex.js";
import "lodash-es/difference.js";
import "lodash-es/identity.js";
import "lodash-es/values.js";
import "@sanity/comlink";
import "lodash-es/omit.js";
import "@isaacs/ttlcache";
import "dataloader";
import "raf";
import "groq-js";
import "use-sync-external-store/with-selector";
import "is-network-error";
import "lodash-es/escapeRegExp.js";
import "@sanity/icons/Desktop";
import "@sanity/icons/Moon";
import "@sanity/icons/Sun";
import "lodash-es/isEmpty.js";
import "react-dom/server";
import "@sanity/icons/Controls";
import "@sanity/icons/Sort";
import "lodash-es/capitalize.js";
import "@sanity/icons/Undo";
import "@sanity/icons/Menu";
import "@sanity/icons/AddUser";
import "@sanity/icons/Cog";
import "@sanity/icons/Users";
import "semver";
import "@sanity/icons/Github";
import "@sanity/icons/Refresh";
import "@sanity/icons/Leave";
import "lodash-es/last.js";
import "react-dom/client";
import "date-fns/addWeeks";
import "date-fns/isAfter";
import { PinIcon } from "@sanity/icons/Pin";
import { PinFilledIcon } from "@sanity/icons/PinFilled";
import { addDays } from "date-fns/addDays";
import { RestoreIcon } from "@sanity/icons/Restore";
import { CloseCircleIcon } from "@sanity/icons/CloseCircle";
import { ArchiveIcon } from "@sanity/icons/Archive";
import { UnarchiveIcon } from "@sanity/icons/Unarchive";
import { ShareIcon } from "@sanity/icons/Share";
import { TargetIcon } from "@sanity/icons/Target";
import { TextIcon } from "@sanity/icons/Text";
import { Headers, Table } from "./Table.js";
import { isSameDay } from "date-fns/isSameDay";
import { CalendarDay, CalendarFilter } from "./CalendarFilter.js";
import { useReleasesMetadataProvider } from "./ReleasesMetadataProvider.js";
import { FilterIcon } from "@sanity/icons/Filter";
import { isPast } from "date-fns/isPast";
import { endOfDay } from "date-fns/endOfDay";
import { startOfDay } from "date-fns/startOfDay";
const GROUP_SEARCH_PARAM_KEY = "group", RELEASE_NOT_FOUND_SEARCH_PARAM_KEY = "releaseNotFound", DATE_SEARCH_PARAM_KEY = "date", VIEW_SEARCH_PARAM_KEY = "view", DATE_SEARCH_PARAM_VALUE_FORMAT = "yyyy-MM-dd";
function getInitialReleaseNotFound(router) {
return new URLSearchParams(router.state._searchParams).get(RELEASE_NOT_FOUND_SEARCH_PARAM_KEY) === "true";
}
const getInitialFilterDate = (router) => () => {
const activeFilterDate = new URLSearchParams(router.state._searchParams).get(DATE_SEARCH_PARAM_KEY);
return activeFilterDate ? new Date(activeFilterDate) : void 0;
}, getInitialReleaseGroupMode = (router) => () => {
const activeGroupMode = new URLSearchParams(router.state._searchParams).get(GROUP_SEARCH_PARAM_KEY);
return activeGroupMode === "archived" ? "archived" : activeGroupMode === "paused" ? "paused" : "active";
}, getInitialCardinalityView = ({
router,
isScheduledDraftsEnabled,
isReleasesEnabled
}) => () => isScheduledDraftsEnabled ? isReleasesEnabled ? new URLSearchParams(router.state._searchParams).get(VIEW_SEARCH_PARAM_KEY) === "drafts" ? "drafts" : "releases" : "drafts" : "releases", buildReleasesSearchParams = (releaseFilterDate, releaseGroupMode, cardinalityView) => {
const params = [];
return releaseFilterDate ? params.push([DATE_SEARCH_PARAM_KEY, format(releaseFilterDate, DATE_SEARCH_PARAM_VALUE_FORMAT)]) : releaseGroupMode !== "active" && params.push([GROUP_SEARCH_PARAM_KEY, releaseGroupMode]), cardinalityView === "drafts" && params.push([VIEW_SEARCH_PARAM_KEY, "drafts"]), params;
}, INITIAL_VALUE$1 = {
events: [],
nextCursor: "",
loading: !0,
error: null
};
function removeDupes$1(prev, next) {
const noDupes = [...prev, ...next].reduce((acc, event) => acc.has(event.id) ? acc : acc.set(event.id, event), /* @__PURE__ */ new Map());
return Array.from(noDupes.values());
}
function addEventData(event) {
return {
...event,
id: `${event.timestamp}-${event.type}`,
origin: "events"
};
}
function getReleaseActivityEvents({
client,
releaseId
}) {
const refetchEventsTrigger$ = new BehaviorSubject({
cursor: null,
origin: "initial"
}), fetchEvents = ({
limit,
nextCursor: nextCursor2
}) => {
const params = new URLSearchParams({
limit: limit.toString()
});
return nextCursor2 && params.append("nextCursor", nextCursor2), client.observable.request({
url: `/data/history/${client.config().dataset}/events/releases/${getReleaseIdFromReleaseDocumentId(releaseId)}?${params.toString()}`,
tag: "get-release-events"
}).pipe(map((response) => ({
events: response.events.map(addEventData),
nextCursor: response.nextCursor,
loading: !1,
error: null
})), catchError((error) => (console.error(error), [{
events: [],
nextCursor: "",
loading: !1,
error
}])));
};
let nextCursor = "";
return {
events$: refetchEventsTrigger$.pipe(switchMap(({
cursor,
origin
}) => fetchEvents({
nextCursor: cursor,
limit: origin === "reload" ? 10 : 100
}).pipe(map((response) => ({
...response,
origin
})), startWith({
events: [],
nextCursor: "",
loading: !0,
error: null,
origin
}))), scan((prev, next) => ({
events: removeDupes$1(prev.events, next.events).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()),
// If we are reloading, we should keep the cursor as it was before.
nextCursor: next.origin === "reload" ? prev.nextCursor : next.nextCursor,
loading: next.loading,
error: next.error
}), INITIAL_VALUE$1), tap((response) => {
nextCursor = response.nextCursor;
}), shareReplay(1)),
/**
* Loads new events for the release, fetching the latest events from the API.
*/
reloadEvents: () => refetchEventsTrigger$.next({
cursor: null,
origin: "reload"
}),
/**
* Loads more events for the release, fetching the next batch of events from the API.
*/
loadMore: () => {
const lastCursorUsed = refetchEventsTrigger$.getValue().cursor;
nextCursor && lastCursorUsed !== nextCursor && refetchEventsTrigger$.next({
origin: "loadMore",
cursor: nextCursor
});
}
};
}
function buildReleaseEditEvents(transactions, release) {
if (release._rev !== transactions[0]?.id)
return console.error("Some transactions are missing, cannot calculate the edit events"), [];
const releaseEditEvents = [];
let currentDocument = release;
for (const transaction of transactions) {
const effect = transaction.effects[release._id];
if (!effect) continue;
const before = applyMendozaPatch(currentDocument, effect.revert, currentDocument._rev), changed = {};
before?.state !== currentDocument.state && currentDocument.state === "archived" && releaseEditEvents.push({
type: "archiveRelease",
timestamp: transaction.timestamp,
author: transaction.author,
releaseName: getReleaseIdFromReleaseDocumentId(release._id),
id: transaction.id,
origin: "translog"
}), before?.state !== currentDocument.state && currentDocument.state === "published" && releaseEditEvents.push({
type: "publishRelease",
timestamp: transaction.timestamp,
author: transaction.author,
releaseName: getReleaseIdFromReleaseDocumentId(release._id),
id: transaction.id,
origin: "translog"
}), before?.state === "unarchiving" && currentDocument.state === "active" && releaseEditEvents.push({
type: "unarchiveRelease",
timestamp: transaction.timestamp,
author: transaction.author,
releaseName: getReleaseIdFromReleaseDocumentId(release._id),
id: transaction.id,
origin: "translog"
}), before?.metadata.releaseType !== currentDocument.metadata.releaseType && (changed.releaseType = currentDocument.metadata.releaseType), before?.metadata.intendedPublishAt !== currentDocument.metadata.intendedPublishAt && (changed.intendedPublishDate = currentDocument.metadata.intendedPublishAt), Object.values(changed).length >= 1 && releaseEditEvents.push({
type: before ? "editRelease" : "createRelease",
origin: "translog",
author: transaction.author,
change: changed,
id: transaction.id,
timestamp: transaction.timestamp,
releaseName: getReleaseIdFromReleaseDocumentId(release._id)
}), before && (currentDocument = before);
}
return releaseEditEvents;
}
const TRANSLOG_ENTRY_LIMIT = 100, documentTransactionsCache = /* @__PURE__ */ Object.create(null);
function removeDupes(newTransactions, oldTransactions) {
const seen = /* @__PURE__ */ new Set();
return newTransactions.concat(oldTransactions).filter((transaction) => seen.has(transaction.id) ? !1 : (seen.add(transaction.id), !0));
}
function getReleaseTransactions({
documentId,
client,
toTransaction
}) {
const cacheKey = `${documentId}`, cachedTransactions = documentTransactionsCache[cacheKey] || [];
if (cachedTransactions.length > 0 && cachedTransactions[0].id === toTransaction)
return of(cachedTransactions);
function fetchLogs(options) {
return from(getTransactionsLogs(client, documentId, {
tag: "sanity.studio.release.history",
effectFormat: "mendoza",
limit: TRANSLOG_ENTRY_LIMIT,
reverse: !0,
fromTransaction: options.fromTransaction,
toTransaction: options.toTransaction
}));
}
return fetchLogs({
fromTransaction: cachedTransactions[0]?.id,
toTransaction
}).pipe(
expand((response) => response.length === TRANSLOG_ENTRY_LIMIT ? fetchLogs({
fromTransaction: void 0,
toTransaction: response[response.length - 1].id
}) : of()),
// Combine all batches of transactions into a single array
reduce((allTransactions, batch) => allTransactions.concat(batch), [])
).pipe(map$1((transactions) => removeDupes(transactions, cachedTransactions)), tap$1((transactions) => {
documentTransactionsCache[cacheKey] = transactions;
}));
}
const INITIAL_VALUE = {
editEvents: [],
loading: !0,
error: null
};
function getReleaseEditEvents({
client,
observeDocument$
}) {
return observeDocument$.pipe(filter(Boolean), distinctUntilChanged((prev, next) => prev._rev === next._rev), switchMap$1((release) => getReleaseTransactions({
client,
documentId: release._id,
toTransaction: release._rev
}).pipe(map$1((transactions) => ({
editEvents: buildReleaseEditEvents(transactions, release),
loading: !1,
error: null
})), catchError$1((error) => (console.error(error), of({
editEvents: [],
loading: !1,
error
}))))), startWith$1(INITIAL_VALUE), scan$1((acc, current) => {
const editEvents = current.loading ? acc.editEvents : current.editEvents;
return {
...current,
editEvents
};
}, INITIAL_VALUE), shareReplay$1(1));
}
const isCreateReleaseEvent = (event) => event.type === "createRelease", isScheduleReleaseEvent = (event) => event.type === "scheduleRelease", isPublishReleaseEvent = (event) => event.type === "publishRelease", isArchiveReleaseEvent = (event) => event.type === "archiveRelease", isUnarchiveReleaseEvent = (event) => event.type === "unarchiveRelease", isAddDocumentToReleaseEvent = (event) => event.type === "addDocumentToRelease", isDiscardDocumentFromReleaseEvent = (event) => event.type === "discardDocumentFromRelease", isEditReleaseEvent = (event) => event.type === "editRelease", isTranslogEvent = (event) => event.origin === "translog", isEventsAPIEvent = (event) => event.origin === "events", EVENTS_INITIAL_VALUE = {
events: [],
hasMore: !1,
error: null,
loading: !0
}, notEnabledActivityEvents = {
events$: of({
events: [],
nextCursor: "",
loading: !1,
error: null
}),
reloadEvents: () => {
},
loadMore: () => {
}
};
function getReleaseEvents({
client,
releaseId,
releasesState$,
documentPreviewStore,
eventsAPIEnabled
}) {
const observeDocument$ = documentPreviewStore.unstable_observeDocument(releaseId, {
apiVersion: RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion
}), editEvents$ = getReleaseEditEvents({
client,
observeDocument$
}), releaseRev$ = releasesState$.pipe(
map$1((state) => state.releases.get(releaseId)?._rev),
filter(Boolean),
distinctUntilChanged(),
// Emit only when rev changes, after first non null value.
skip(1)
), activityEvents = eventsAPIEnabled ? getReleaseActivityEvents({
client,
releaseId
}) : notEnabledActivityEvents, documentsCount$ = eventsAPIEnabled ? of(0) : documentPreviewStore.unstable_observeDocumentIdSet("sanity::partOfRelease($releaseId)", {
releaseId: getReleaseIdFromReleaseDocumentId(releaseId)
}, {
apiVersion: RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion
}).pipe(
filter(({
status
}) => status === "connected"),
map$1(({
documentIds
}) => documentIds.length),
distinctUntilChanged(),
// Emit only when count changes, after first non null value.
skip(1)
), sideEffects$ = merge(releaseRev$, documentsCount$).pipe(tap$1(() => {
activityEvents.reloadEvents();
}), startWith$1(null));
return {
events$: combineLatest([activityEvents.events$, editEvents$, sideEffects$]).pipe(map$1(([activity, edit]) => {
const events = [...activity.events, ...edit.editEvents].sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp)).reduce((acc, event) => {
if (isCreateReleaseEvent(event)) {
const creationEvent = acc.find(isCreateReleaseEvent);
creationEvent ? isEventsAPIEvent(creationEvent) && isTranslogEvent(event) && (acc[acc.indexOf(creationEvent)] = event) : acc.push(event);
} else acc.push(event);
return acc;
}, []);
return {
events: deduplicateEvents(events),
hasMore: !!activity.nextCursor,
error: activity.error || edit.error,
loading: activity.loading || edit.loading
};
})),
loadMore: activityEvents.loadMore
};
}
const deduplicateEvents = (events) => events.filter((event, index) => {
const nextEvent = events[index + 1];
return nextEvent ? !(event.type === nextEvent.type && areTheSameDate(event.timestamp, nextEvent.timestamp)) : !0;
});
function areTheSameDate(date1, date2) {
const time1 = new Date(date1).getTime(), time2 = new Date(date2).getTime();
return Math.abs(time1 - time2) <= 1e3;
}
function useReleaseEvents(releaseId) {
const $ = c(12), client = useClient(RELEASES_STUDIO_CLIENT_OPTIONS), documentPreviewStore = useDocumentPreviewStore(), {
state$: releasesState$
} = useReleasesStore(), eventsAPIEnabled = !!useSource().beta?.eventsAPI?.releases;
let t0;
$[0] !== client || $[1] !== documentPreviewStore || $[2] !== eventsAPIEnabled || $[3] !== releaseId || $[4] !== releasesState$ ? (t0 = getReleaseEvents({
client,
releaseId: getReleaseDocumentIdFromReleaseId(releaseId),
releasesState$,
documentPreviewStore,
eventsAPIEnabled
}), $[0] = client, $[1] = documentPreviewStore, $[2] = eventsAPIEnabled, $[3] = releaseId, $[4] = releasesState$, $[5] = t0) : t0 = $[5];
const releaseEvents = t0, events = useObservable(releaseEvents.events$, EVENTS_INITIAL_VALUE);
let t1;
return $[6] !== events.error || $[7] !== events.events || $[8] !== events.hasMore || $[9] !== events.loading || $[10] !== releaseEvents.loadMore ? (t1 = {
events: events.events,
hasMore: events.hasMore,
loading: events.loading,
error: events.error,
loadMore: releaseEvents.loadMore
}, $[6] = events.error, $[7] = events.events, $[8] = events.hasMore, $[9] = events.loading, $[10] = releaseEvents.loadMore, $[11] = t1) : t1 = $[11], t1;
}
const isArchivedRelease = (releaseState) => releaseState === "archived" || releaseState === "archiving" || releaseState === "unarchiving";
function getReleaseDocumentIntent({
documentId,
documentTypeName,
releaseId,
releaseState,
documentRevision,
isCardinalityOneRelease: isCardinalityOneRelease2,
path
}) {
const releaseName = getReleaseIdFromReleaseDocumentId(releaseId);
let intentParams = {};
isCardinalityOneRelease2 ? intentParams = {
scheduledDraft: releaseName
} : releaseState === "published" ? intentParams = {
rev: `@release:${releaseName}`,
inspect: "sanity/structure/history"
} : releaseState === "archived" && (intentParams = {
rev: "@lastEdited",
inspect: "sanity/structure/history",
historyEvent: documentRevision,
historyVersion: releaseName,
archivedRelease: "true"
});
const searchParams = isCardinalityOneRelease2 || isArchivedRelease(releaseState) ? void 0 : [["perspective", releaseState === "published" ? "published" : releaseName]];
return {
params: {
id: getPublishedId(documentId),
type: documentTypeName,
...intentParams,
...path ? {
path
} : {}
},
searchParams
};
}
function ReleaseDocumentPreview(t0) {
const $ = c(32), {
documentId,
documentTypeName,
releaseId,
releaseState,
isCardinalityOneRelease: isCardinalityOneRelease2,
documentRevision,
layout,
isGoingToBePublished: t1
} = t0, isGoingToBePublished = t1 === void 0 ? !1 : t1, documentPresence = useDocumentPresence(documentId);
let t2;
$[0] !== documentId || $[1] !== documentRevision || $[2] !== documentTypeName || $[3] !== isCardinalityOneRelease2 || $[4] !== releaseId || $[5] !== releaseState ? (t2 = getReleaseDocumentIntent({
documentId,
documentTypeName,
releaseId,
releaseState,
documentRevision,
isCardinalityOneRelease: isCardinalityOneRelease2
}), $[0] = documentId, $[1] = documentRevision, $[2] = documentTypeName, $[3] = isCardinalityOneRelease2, $[4] = releaseId, $[5] = releaseState, $[6] = t2) : t2 = $[6];
const {
params,
searchParams
} = t2;
let t3;
$[7] !== params || $[8] !== searchParams ? (t3 = forwardRef(function(linkProps, ref) {
return /* @__PURE__ */ jsx(IntentLink, { ...linkProps, intent: "edit", params, searchParams, ref });
}), $[7] = params, $[8] = searchParams, $[9] = t3) : t3 = $[9];
const LinkComponent = t3;
let t4;
$[10] !== documentPresence ? (t4 = documentPresence?.length > 0 && /* @__PURE__ */ jsx(DocumentPreviewPresence, { presence: documentPresence }), $[10] = documentPresence, $[11] = t4) : t4 = $[11];
const previewPresence = t4;
let t5;
$[12] !== documentId || $[13] !== isGoingToBePublished ? (t5 = isGoingToBePublished ? getPublishedId(documentId) : documentId, $[12] = documentId, $[13] = isGoingToBePublished, $[14] = t5) : t5 = $[14];
let t6;
$[15] !== isGoingToBePublished || $[16] !== releaseId ? (t6 = isGoingToBePublished ? [] : [getReleaseIdFromReleaseDocumentId(releaseId)], $[15] = isGoingToBePublished, $[16] = releaseId, $[17] = t6) : t6 = $[17];
let t7;
$[18] !== documentTypeName || $[19] !== t5 || $[20] !== t6 ? (t7 = {
documentId: t5,
documentType: documentTypeName,
perspectiveStack: t6
}, $[18] = documentTypeName, $[19] = t5, $[20] = t6, $[21] = t7) : t7 = $[21];
const {
isLoading: previewLoading,
value: resolvedPreview
} = useDocumentPreviewValues(t7);
let t8;
$[22] !== resolvedPreview ? (t8 = resolvedPreview || {}, $[22] = resolvedPreview, $[23] = t8) : t8 = $[23];
let t9;
$[24] !== layout || $[25] !== previewLoading || $[26] !== previewPresence || $[27] !== t8 ? (t9 = /* @__PURE__ */ jsx(SanityDefaultPreview, { ...t8, status: previewPresence, isPlaceholder: previewLoading, layout }), $[24] = layout, $[25] = previewLoading, $[26] = previewPresence, $[27] = t8, $[28] = t9) : t9 = $[28];
let t10;
return $[29] !== LinkComponent || $[30] !== t9 ? (t10 = /* @__PURE__ */ jsx(Card, { tone: "inherit", as: LinkComponent, radius: 2, "data-as": "a", children: t9 }), $[29] = LinkComponent, $[30] = t9, $[31] = t10) : t10 = $[31], t10;
}
const StatusText = /* @__PURE__ */ styled(Text).withConfig({
displayName: "StatusText",
componentId: "sc-1vmkaay-0"
})(["strong{font-weight:500;color:var(--card-fg-color);}time{white-space:nowrap;}"]), ACTIVITY_TEXT_118N = {
addDocumentToRelease: "activity.event.add-document",
archiveRelease: "activity.event.archive",
createRelease: "activity.event.create",
discardDocumentFromRelease: "activity.event.discard-document",
publishRelease: "activity.event.publish",
scheduleRelease: "activity.event.schedule",
unarchiveRelease: "activity.event.unarchive",
unscheduleRelease: "activity.event.unschedule",
editRelease: "activity.event.edit"
}, ReleaseEventDocumentPreview = (t0) => {
const $ = c(4), {
event,
releaseId
} = t0;
let t1;
return $[0] !== event.documentId || $[1] !== event.documentType || $[2] !== releaseId ? (t1 = /* @__PURE__ */ jsx(Stack, { space: 2, children: /* @__PURE__ */ jsx(ReleaseDocumentPreview, { releaseId, documentId: event.documentId, documentTypeName: event.documentType, layout: "block" }) }), $[0] = event.documentId, $[1] = event.documentType, $[2] = releaseId, $[3] = t1) : t1 = $[3], t1;
}, ScheduleTarget = (t0) => {
const $ = c(13), {
children,
event
} = t0;
let t1;
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
dateStyle: "full",
timeStyle: "medium"
}, $[0] = t1) : t1 = $[0];
const dateTimeFormat = useDateTimeFormat(t1), {
t
} = useTranslation(releasesLocaleNamespace);
let t2;
bb0: {
if (isEditReleaseEvent(event)) {
if (event.change.releaseType === "asap") {
let t33;
$[1] !== t ? (t33 = t("activity.event.edit-time-asap"), $[1] = t, $[2] = t33) : t33 = $[2], t2 = t33;
break bb0;
}
if (event.change.releaseType === "undecided") {
let t33;
$[3] !== t ? (t33 = t("activity.event.edit-time-undecided"), $[3] = t, $[4] = t33) : t33 = $[4], t2 = t33;
break bb0;
}
}
let dateString;
if (isScheduleReleaseEvent(event) ? dateString = event.publishAt : isCreateReleaseEvent(event) ? dateString = event.change?.intendedPublishDate : isEditReleaseEvent(event) && (dateString = event.change.intendedPublishDate), !dateString) {
t2 = null;
break bb0;
}
let t32;
$[5] !== dateString || $[6] !== dateTimeFormat ? (t32 = dateTimeFormat.format(new Date(dateString)), $[5] = dateString, $[6] = dateTimeFormat, $[7] = t32) : t32 = $[7], t2 = t32;
}
const formattedDate = t2;
if (!formattedDate && isCreateReleaseEvent(event))
return null;
const t3 = formattedDate || "---";
let t4;
$[8] !== t3 ? (t4 = /* @__PURE__ */ jsx("strong", { children: t3 }), $[8] = t3, $[9] = t4) : t4 = $[9];
let t5;
return $[10] !== children || $[11] !== t4 ? (t5 = /* @__PURE__ */ jsxs("span", { children: [
children,
" ",
t4
] }), $[10] = children, $[11] = t4, $[12] = t5) : t5 = $[12], t5;
}, FadeInCard = motion.create(Card);
function ActivityTimestamp(t0) {
const $ = c(13), {
timestamp
} = t0;
let t1;
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
dateStyle: "medium",
timeStyle: "short"
}, $[0] = t1) : t1 = $[0];
const dateTimeFormat = useDateTimeFormat(t1);
let t2;
$[1] !== timestamp ? (t2 = new Date(timestamp), $[1] = timestamp, $[2] = t2) : t2 = $[2];
const date = t2;
let t3;
$[3] !== date || $[4] !== dateTimeFormat ? (t3 = dateTimeFormat.format(date), $[3] = date, $[4] = dateTimeFormat, $[5] = t3) : t3 = $[5];
const formattedDate = t3;
let t4;
$[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t4 = {
useTemporalPhrase: !0,
minimal: !0
}, $[6] = t4) : t4 = $[6];
const relativeTime = useRelativeTime(date, t4);
let t5;
$[7] !== date ? (t5 = date.toISOString(), $[7] = date, $[8] = t5) : t5 = $[8];
let t6;
return $[9] !== formattedDate || $[10] !== relativeTime || $[11] !== t5 ? (t6 = /* @__PURE__ */ jsx("time", { dateTime: t5, title: relativeTime, children: formattedDate }), $[9] = formattedDate, $[10] = relativeTime, $[11] = t5, $[12] = t6) : t6 = $[12], t6;
}
const ReleaseActivityListItem = memo((t0) => {
const $ = c(28), {
event,
releaseId,
releaseTitle
} = t0, {
t
} = useTranslation(releasesLocaleNamespace);
let t1, t2, t3;
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = {
opacity: 0
}, t2 = {
opacity: 1
}, t3 = {
type: "spring",
bounce: 0,
duration: 0.4
}, $[0] = t1, $[1] = t2, $[2] = t3) : (t1 = $[0], t2 = $[1], t3 = $[2]);
let t4;
$[3] !== event.author ? (t4 = /* @__PURE__ */ jsx(UserAvatar, { user: event.author }), $[3] = event.author, $[4] = t4) : t4 = $[4];
let t5;
$[5] !== event ? (t5 = {
ScheduleTarget: (t62) => {
const {
children
} = t62;
return /* @__PURE__ */ jsx(ScheduleTarget, { event, children });
}
}, $[5] = event, $[6] = t5) : t5 = $[6];
let t6;
$[7] !== releaseTitle ? (t6 = {
releaseTitle
}, $[7] = releaseTitle, $[8] = t6) : t6 = $[8];
const t7 = ACTIVITY_TEXT_118N[event.type];
let t8;
$[9] !== t || $[10] !== t5 || $[11] !== t6 || $[12] !== t7 ? (t8 = /* @__PURE__ */ jsx(Translate, { t, components: t5, values: t6, i18nKey: t7 }), $[9] = t, $[10] = t5, $[11] = t6, $[12] = t7, $[13] = t8) : t8 = $[13];
let t9;
$[14] !== event.timestamp ? (t9 = /* @__PURE__ */ jsx(ActivityTimestamp, { timestamp: event.timestamp }), $[14] = event.timestamp, $[15] = t9) : t9 = $[15];
let t10;
$[16] !== t8 || $[17] !== t9 ? (t10 = /* @__PURE__ */ jsx(Flex, { gap: 2, align: "center", children: /* @__PURE__ */ jsxs(StatusText, { muted: !0, size: 1, children: [
t8,
" ",
"\xB7 ",
t9
] }) }), $[16] = t8, $[17] = t9, $[18] = t10) : t10 = $[18];
let t11;
$[19] !== event || $[20] !== releaseId ? (t11 = isAddDocumentToReleaseEvent(event) || isDiscardDocumentFromReleaseEvent(event) ? /* @__PURE__ */ jsx(ReleaseEventDocumentPreview, { event, releaseId }) : null, $[19] = event, $[20] = releaseId, $[21] = t11) : t11 = $[21];
let t12;
$[22] !== t10 || $[23] !== t11 ? (t12 = /* @__PURE__ */ jsxs(Stack, { flex: 1, children: [
t10,
t11
] }), $[22] = t10, $[23] = t11, $[24] = t12) : t12 = $[24];
let t13;
return $[25] !== t12 || $[26] !== t4 ? (t13 = /* @__PURE__ */ jsx(FadeInCard, { paddingX: 1, paddingTop: 1, paddingBottom: 2, overflow: "hidden", initial: t1, animate: t2, transition: t3, children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
t4,
t12
] }) }), $[25] = t12, $[26] = t4, $[27] = t13) : t13 = $[27], t13;
}, (prevProps, nextProps) => prevProps.event.id === nextProps.event.id && prevProps.releaseId === nextProps.releaseId);
ReleaseActivityListItem.displayName = "ReleaseActivityListItem";
const estimateSize = (event) => event ? isAddDocumentToReleaseEvent(event) || isDiscardDocumentFromReleaseEvent(event) ? 70 : 56 : 40, VirtualContainer = /* @__PURE__ */ styled(Box).withConfig({
displayName: "VirtualContainer",
componentId: "sc-163h2xa-0"
})(["height:100%;overflow:scroll;"]), ReleaseActivityList = ({
events,
releaseTitle,
releaseId,
hasMore,
loadMore,
isLoading
}) => {
const virtualizerContainerRef = useRef(null), listEvents = useMemo(() => {
if (!hasMore && !isLoading) return events;
const lastEventFromEventsAPI = [...events].reverse().find(isEventsAPIEvent);
if (!lastEventFromEventsAPI && !isLoading) return events;
if (!lastEventFromEventsAPI) return [];
const lastEventDate = new Date(lastEventFromEventsAPI.timestamp);
return events.filter((event) => isTranslogEvent(event) ? new Date(event.timestamp) > lastEventDate : !0);
}, [events, hasMore, isLoading]), virtualizer = useVirtualizer({
// If we have more events, or the events are loading, we add a loader row at the end
count: hasMore || isLoading ? listEvents.length + 1 : listEvents.length,
getScrollElement: () => virtualizerContainerRef.current,
estimateSize: (i) => estimateSize(events[i]),
overscan: 10,
paddingEnd: 24
}), virtualItems = virtualizer.getVirtualItems();
return useEffect(() => {
const lastItem = virtualItems.at(-1);
lastItem && lastItem.index >= listEvents.length - 1 && hasMore && loadMore();
}, [listEvents.length, hasMore, loadMore, virtualItems]), /* @__PURE__ */ jsx(VirtualContainer, { id: "virtualizer-container", ref: virtualizerContainerRef, paddingX: 3, children: /* @__PURE__ */ jsx("div", { style: {
height: `${virtualizer.getTotalSize()}px`,
width: "100%",
position: "relative"
}, children: /* @__PURE__ */ jsx(AnimatePresence, { initial: !1, children: virtualizer.getVirtualItems().map((virtualRow) => {
const event_0 = listEvents[virtualRow.index], isLoaderRow = !event_0;
return /* @__PURE__ */ jsx("div", { "data-index": virtualRow.index, ref: virtualizer.measureElement, style: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
transform: `translateY(${virtualRow.start}px)`
}, children: isLoaderRow ? /* @__PURE__ */ jsx(Box, { paddingY: 4, children: /* @__PURE__ */ jsx(LoadingBlock, { fill: !0 }) }) : /* @__PURE__ */ jsx(ReleaseActivityListItem, { event: event_0, releaseId, releaseTitle }) }, virtualRow.key);
}) }) }) });
}, MotionFlex = motion.create(Flex), FillHeight = /* @__PURE__ */ styled.div.withConfig({
displayName: "FillHeight",
componentId: "sc-cp4fmh-0"
})(["--card-border-color:transparent;height:100%;display:flex;flex-direction:column;"]);
function ReleaseDashboardActivityPanel(t0) {
const $ = c(8), {
events,
release,
show
} = t0, {
t
} = useTranslation(releasesLocaleNamespace), {
t: tCore
} = useTranslation();
let t1;
$[0] !== events || $[1] !== release || $[2] !== show || $[3] !== t || $[4] !== tCore ? (t1 = show && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(motion.div, { animate: {
width: "auto",
opacity: 1
}, initial: {
width: 0,
opacity: 0
}, exit: {
width: 0,
opacity: 0
}, transition: {
type: "spring",
bounce: 0,
duration: 0.2
}, children: /* @__PURE__ */ jsx(Resizable, { as: FillHeight, minWidth: 320, maxWidth: 800, initialWidth: 320, resizerPosition: "left", style: {
display: "flex",
flexDirection: "column",
flex: "none",
maxHeight: "100%"
}, children: /* @__PURE__ */ jsxs(MotionFlex, { flex: "none", height: "fill", direction: "column", children: [
/* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: t("activity.panel.title") }) }),
events.error && !events.events.length && /* @__PURE__ */ jsx(Card, { padding: 3, tone: "caution", children: /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(Text, { size: 0, children: t("activity.panel.error") }) }) }),
events.loading && !events.events.length && /* @__PURE__ */ jsx(LoadingBlock, { title: t("activity.panel.loading") }),
/* @__PURE__ */ jsx(ReleaseActivityList, { releaseTitle: release.metadata.title || tCore("release.placeholder-untitled-release"), releaseId: release._id, events: events.events, hasMore: events.hasMore, loadMore: events.loadMore, isLoading: events.loading })
] }) }) }) }), $[0] = events, $[1] = release, $[2] = show, $[3] = t, $[4] = tCore, $[5] = t1) : t1 = $[5];
let t2;
return $[6] !== t1 ? (t2 = /* @__PURE__ */ jsx(AnimatePresence, { children: t1 }), $[6] = t1, $[7] = t2) : t2 = $[7], t2;
}
function ArchivedReleaseBanner(t0) {
const $ = c(17), {
release
} = t0, {
state
} = release, {
t: tRelease
} = useTranslation(releasesLocaleNamespace), {
projectSubscriptions
} = useProjectSubscriptions(), retentionDays = projectSubscriptions?.featureTypes.retention.features[0].attributes.maxRetentionDays, {
utcToCurrentZoneDate
} = useTimeZone(CONTENT_RELEASES_TIME_ZONE_SCOPE);
let t1;
bb0: {
if (!retentionDays || !release?._updatedAt) {
t1 = "";
break bb0;
}
let t22;
if ($[0] !== release._updatedAt || $[1] !== retentionDays || $[2] !== utcToCurrentZoneDate) {
const _removalDate = addDays(new Date(release._updatedAt), retentionDays);
t22 = format(utcToCurrentZoneDate(_removalDate), "PP"), $[0] = release._updatedAt, $[1] = retentionDays, $[2] = utcToCurrentZoneDate, $[3] = t22;
} else
t22 = $[3];
t1 = t22;
}
const removalDate = t1;
let t2;
$[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = /* @__PURE__ */ jsx(Text, { size: 1, children: /* @__PURE__ */ jsx(InfoOutlineIcon, {}) }), $[4] = t2) : t2 = $[4];
let t3;
$[5] !== state || $[6] !== tRelease ? (t3 = tRelease(state === "archived" ? "archive-info.title" : "publish-info.title"), $[5] = state, $[6] = tRelease, $[7] = t3) : t3 = $[7];
let t4;
$[8] !== t3 ? (t4 = /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: t3 }), $[8] = t3, $[9] = t4) : t4 = $[9];
let t5;
$[10] !== removalDate || $[11] !== retentionDays || $[12] !== tRelease ? (t5 = retentionDays && /* @__PURE__ */ jsx(Text, { size: 1, accent: !0, children: /* @__PURE__ */ jsx(Translate, { t: tRelease, i18nKey: "archive-info.description", values: {
retentionDays,
removalDate: removalDate || ""
}, components: {
Link: _temp$i
} }) }), $[10] = removalDate, $[11] = retentionDays, $[12] = tRelease, $[13] = t5) : t5 = $[13];
let t6;
return $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsx(Card, { padding: 4, radius: 4, tone: "primary", "data-testid": "retention-policy-card", children: /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
t2,
/* @__PURE__ */ jsxs(Stack, { space: 4, children: [
t4,
t5
] })
] }) }), $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6;
}
function _temp$i(t0) {
const {
children
} = t0;
return /* @__PURE__ */ jsx("a", { href: "https://www.sanity.io/docs/user-guides/history-experience", target: "_blank", rel: "noreferrer", children });
}
function ReleaseDetailsEditor(t0) {
const $ = c(13), {
release
} = t0, {
updateRelease
} = useReleaseOperations(), [timer, setTimer] = useState(void 0), {
checkWithPermissionGuard
} = useReleasePermissions(), [hasUpdatePermission, setHasUpdatePermission] = useState(null);
let t1;
$[0] !== hasUpdatePermission || $[1] !== timer || $[2] !== updateRelease ? (t1 = (changedValue) => {
clearTimeout(timer);
const newTimer = setTimeout(() => {
hasUpdatePermission && updateRelease(changedValue);
}, 200);
setTimer(newTimer);
}, $[0] = hasUpdatePermission, $[1] = timer, $[2] = updateRelease, $[3] = t1) : t1 = $[3];
const handleOnChange = t1, isMounted = useRef(!1);
let t2, t3;
$[4] !== checkWithPermissionGuard || $[5] !== release || $[6] !== updateRelease ? (t2 = () => (isMounted.current = !0, getIsReleaseOpen(release) && checkWithPermissionGuard(updateRelease, release).then((hasPermission) => {
isMounted.current && setHasUpdatePermission(hasPermission);
}), () => {
isMounted.current = !1;
}), t3 = [checkWithPermissionGuard, release, release._id, updateRelease], $[4] = checkWithPermissionGuard, $[5] = release, $[6] = updateRelease, $[7] = t2, $[8] = t3) : (t2 = $[7], t3 = $[8]), useEffect(t2, t3);
const t4 = release._id, t5 = !hasUpdatePermission;
let t6;
return $[9] !== handleOnChange || $[10] !== release || $[11] !== t5 ? (t6 = /* @__PURE__ */ jsx(TitleDescriptionForm, { release, onChange: handleOnChange, disabled: t5 }, t4), $[9] = handleOnChange, $[10] = release, $[11] = t5, $[12] = t6) : t6 = $[12], t6;
}
const useReleaseTime = () => {
const $ = c(9);
let t0;
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {
type: "contentReleases"
}, $[0] = t0) : t0 = $[0];
const {
timeZone,
utcToCurrentZoneDate,
getLocalTimeZone
} = useTimeZone(t0);
let t1;
$[1] !== getLocalTimeZone ? (t1 = getLocalTimeZone(), $[1] = getLocalTimeZone, $[2] = t1) : t1 = $[2];
const {
abbreviation: localeTimeZoneAbbreviation
} = t1;
let t2;
$[3] !== localeTimeZoneAbbreviation || $[4] !== timeZone.abbreviation ? (t2 = () => timeZone.abbreviation === localeTimeZoneAbbreviation ? "" : `(${timeZone.abbreviation})`, $[3] = localeTimeZoneAbbreviation, $[4] = timeZone.abbreviation, $[5] = t2) : t2 = $[5];
const getTimezoneAbbreviation = t2;
let t3;
return $[6] !== getTimezoneAbbreviation || $[7] !== utcToCurrentZoneDate ? (t3 = (release) => {
const publishDate = getPublishDateFromRelease(release);
return publishDate ? `${format(utcToCurrentZoneDate(publishDate), "PPpp")} ${getTimezoneAbbreviation()}` : null;
}, $[6] = getTimezoneAbbreviation, $[7] = utcToCurrentZoneDate, $[8] = t3) : t3 = $[8], t3;
}, ReleaseTime = (t0) => {
const $ = c(28), {
release
} = t0, {
t
} = useTranslation(), {
t: tRelease
} = useTranslation(releasesLocaleNamespace), getReleaseTime = useReleaseTime(), {
metadata
} = release;
if (metadata.releaseType === "asap") {
let t12;
$[0] !== t ? (t12 = t("release.type.asap"), $[0] = t, $[1] = t12) : t12 = $[1];
let t22;
return $[2] !== t12 ? (t22 = /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, weight: "medium", children: t12 }), $[2] = t12, $[3] = t22) : t22 = $[3], t22;
}
if (metadata.releaseType === "undecided") {
let t12;
$[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t12 = {
opacity: 0.5
}, $[4] = t12) : t12 = $[4];
let t22;
$[5] !== t ? (t22 = t("release.type.undecided"), $[5] = t, $[6] = t22) : t22 = $[6];
let t32;
return $[7] !== t22 ? (t32 = /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, weight: "medium", style: t12, children: t22 }), $[7] = t22, $[8] = t32) : t32 = $[8], t32;
}
let t1;
$[9] !== release ? (t1 = isReleaseScheduledOrScheduling(release), $[9] = release, $[10] = t1) : t1 = $[10];
const isScheduledOrScheduling = t1;
let t2;
$[11] !== release.state ? (t2 = ARCHIVED_RELEASE_STATES.includes(release.state), $[11] = release.state, $[12] = t2) : t2 = $[12];
const isInArchivedView = t2;
let t3;
$[13] !== isScheduledOrScheduling ? (t3 = isScheduledOrScheduling && /* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: /* @__PURE__ */ jsx(LockIcon, { "data-testid": "release-lock-icon" }) }) }), $[13] = isScheduledOrScheduling, $[14] = t3) : t3 = $[14];
let t4;
$[15] !== isInArchivedView || $[16] !== isScheduledOrScheduling || $[17] !== tRelease ? (t4 = !isInArchivedView && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: tRelease(isScheduledOrScheduling ? "time.scheduled" : "time.estimated") }) }),
/* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "\xB7" }) })
] }), $[15] = isInArchivedView, $[16] = isScheduledOrScheduling, $[17] = tRelease, $[18] = t4) : t4 = $[18];
let t5;
$[19] !== getReleaseTime || $[20] !== release ? (t5 = getReleaseTime(release), $[19] = getReleaseTime, $[20] = release, $[21] = t5) : t5 = $[21];
let t6;
$[22] !== t5 ? (t6 = /* @__PURE__ */ jsx(Box, { paddingY: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: t5 }) }), $[22] = t5, $[23] = t6) : t6 = $[23];
let t7;
return $[24] !== t3 || $[25] !== t4 || $[26] !== t6 ? (t7 = /* @__PURE__ */ jsxs(Flex, { gap: 1, align: "center", wrap: "wrap", children: [
t3,
t4,
t6
] }), $[24] = t3, $[25] = t4, $[26] = t6, $[27] = t7) : t7 = $[27], t7;
}, dateInputFormat = "PP HH:mm";
function ReleaseDateInput(props) {
const $ = c(12), {
setIsIntendedScheduleDateInPast,
intendedPublishAt,
setIntendedPublishAt
} = props, {
utcToCurrentZoneDate,
zoneDateToUtc
} = useTimeZone(CONTENT_RELEASES_TIME_ZONE_SCOPE);
let t0;
$[0] !== intendedPublishAt || $[1] !== utcToCurrentZoneDate ? (t0 = intendedPublishAt && utcToCurrentZoneDate(intendedPublishAt), $[0] = intendedPublishAt, $[1] = utcToCurrentZoneDate, $[2] = t0) : t0 = $[2];
const intendedPublishAtTimezoneAdjusted = t0;
let t1;
$[3] !== setIntendedPublishAt || $[4] !== setIsIntendedScheduleDateInPast || $[5] !== zoneDateToUtc ? (t1 = (event) => {
const parsedDate = zoneDateToUtc(parse(event.currentTarget.value, dateInputFormat, /* @__PURE__ */ new Date()));
isValid(parsedDate) && (setIsIntendedScheduleDateInPast(isBefore(parsedDate, /* @__PURE__ */ new Date())), setIntendedPublishAt(startOfMinute(parsedDate)));
}, $[3] = setIntendedPublishAt, $[4] = setIsIntendedScheduleDateInPast, $[5] = zoneDateToUtc, $[6] = t1) : t1 = $[6];
const handlePublishAtInputChange = t1;
let t2;
$[7] !== intendedPublishAtTimezoneAdjusted ? (t2 = intendedPublishAtTimezoneAdjusted ? format(intendedPublishAtTimezoneAdjusted, dateInputFormat) : void 0, $[7] = intendedPublishAtTimezoneAdjusted, $[8] = t2) : t2 = $[8];
let t3;
return $[9] !== handlePublishAtInputChange || $[10] !== t2 ? (t3 = /* @__PURE__ */ jsx(LazyTextInput, { "data-testid": "date-input", value: t2, onChange: handlePublishAtInputChange }), $[9] = handlePublishAtInputChange, $[10] = t2, $[11] = t3) : t3 = $[11], t3;
}
function ReleaseTypePicker(props) {
const $ = c(95), {
release
} = props, popoverRef = useRef(null), bu