From ba21e9c69addb0a98326eb0c0760eb6739ff4a6f Mon Sep 17 00:00:00 2001 From: Steven Le Date: Tue, 3 Mar 2026 11:16:31 -0800 Subject: [PATCH] chore: move release archive button to edit page --- .../DocPreviewCard/DocPreviewCard.tsx | 10 +- .../pages/EditReleasePage/EditReleasePage.tsx | 112 ++++++++++++++---- .../ui/pages/ReleasePage/ReleasePage.tsx | 88 +------------- 3 files changed, 92 insertions(+), 118 deletions(-) diff --git a/packages/root-cms/ui/components/DocPreviewCard/DocPreviewCard.tsx b/packages/root-cms/ui/components/DocPreviewCard/DocPreviewCard.tsx index 691cc04c..9269aedb 100644 --- a/packages/root-cms/ui/components/DocPreviewCard/DocPreviewCard.tsx +++ b/packages/root-cms/ui/components/DocPreviewCard/DocPreviewCard.tsx @@ -4,7 +4,6 @@ import {Loader} from '@mantine/core'; import {useEffect, useState} from 'preact/hooks'; import {joinClassNames} from '../../utils/classes.js'; import {getDocFromCacheOrFetch} from '../../utils/doc-cache.js'; -import {getDocServingUrl} from '../../utils/doc-urls.js'; import {notifyErrors} from '../../utils/notifications.js'; import {getNestedValue} from '../../utils/objects.js'; import {DocStatusBadges} from '../DocStatusBadges/DocStatusBadges.js'; @@ -57,7 +56,7 @@ export function DocPreviewCard(props: DocPreviewCardProps) { return; } - const [collection, slug] = docId.split('/'); + const [collection] = docId.split('/'); const fields = doc.fields || {}; const rootCollection = window.__ROOT_CTX.collections[collection]; if (!rootCollection) { @@ -75,10 +74,6 @@ export function DocPreviewCard(props: DocPreviewCardProps) { const previewImage = getNestedValue(fields, rootCollection.preview?.image || 'meta.image') || rootCollection.preview?.defaultImage; - const docServingUrl = getDocServingUrl({ - collectionId: collection, - slug: slug, - }); let Component: 'div' | 'a' = 'div'; const attrs: Record = {}; @@ -117,9 +112,6 @@ export function DocPreviewCard(props: DocPreviewCardProps) { )} - {props.variant !== 'compact' && docServingUrl && ( -
{docServingUrl}
- )} ); diff --git a/packages/root-cms/ui/pages/EditReleasePage/EditReleasePage.tsx b/packages/root-cms/ui/pages/EditReleasePage/EditReleasePage.tsx index bcb9e8d0..a820d76f 100644 --- a/packages/root-cms/ui/pages/EditReleasePage/EditReleasePage.tsx +++ b/packages/root-cms/ui/pages/EditReleasePage/EditReleasePage.tsx @@ -1,7 +1,8 @@ import {ActionIcon, Breadcrumbs, Tooltip} from '@mantine/core'; import {useModals} from '@mantine/modals'; import {showNotification, updateNotification} from '@mantine/notifications'; -import {IconTrashFilled} from '@tabler/icons-preact'; +import {IconArchive, IconRestore} from '@tabler/icons-preact'; +import {useEffect, useState} from 'preact/hooks'; import {route} from 'preact-router'; import {ConditionalTooltip} from '../../components/ConditionalTooltip/ConditionalTooltip.js'; import {Heading} from '../../components/Heading/Heading.js'; @@ -12,28 +13,38 @@ import {useProjectRoles} from '../../hooks/useProjectRoles.js'; import {Layout} from '../../layout/Layout.js'; import {testCanPublish} from '../../utils/permissions.js'; import './EditReleasePage.css'; -import {deleteRelease} from '../../utils/release.js'; +import { + Release, + archiveRelease, + getRelease, + unarchiveRelease, +} from '../../utils/release.js'; export function EditReleasePage(props: {id: string}) { + const [release, setRelease] = useState(null); const modals = useModals(); const modalTheme = useModalTheme(); const {roles} = useProjectRoles(); const currentUserEmail = window.firebase.user.email || ''; const canPublish = testCanPublish(roles, currentUserEmail); - function onDeleteClicked() { - const notificationId = `delete-release-${props.id}`; + useEffect(() => { + getRelease(props.id).then((release) => { + setRelease(release); + }); + }, [props.id]); + + function onArchiveClicked() { + const notificationId = `archive-release-${props.id}`; const modalId = modals.openConfirmModal({ ...modalTheme, - title: 'Delete release', + title: 'Archive release', children: ( - Are you sure you want to delete release {props.id}? There - is no undo. This will only delete the release; the docs in the release - will remain unchanged. + Are you sure you want to archive release {props.id}? ), - labels: {confirm: 'Delete', cancel: 'Cancel'}, + labels: {confirm: 'Archive', cancel: 'Cancel'}, cancelProps: {size: 'xs'}, confirmProps: {color: 'red', size: 'xs'}, onCancel: () => console.log('Cancel'), @@ -41,16 +52,18 @@ export function EditReleasePage(props: {id: string}) { onConfirm: async () => { showNotification({ id: notificationId, - title: 'Deleting release', - message: `Deleting ${props.id}...`, + title: 'Archiving release', + message: `Archiving ${props.id}...`, loading: true, autoClose: false, }); - await deleteRelease(props.id); + await archiveRelease(props.id); + const newRelease = await getRelease(props.id); + setRelease(newRelease); updateNotification({ id: notificationId, - title: 'Deleted release', - message: `Successfully deleted ${props.id}`, + title: 'Archived release', + message: `Successfully archived ${props.id}`, loading: false, autoClose: 5000, }); @@ -60,6 +73,45 @@ export function EditReleasePage(props: {id: string}) { }); } + function onUnarchiveClicked() { + const notificationId = `unarchive-release-${props.id}`; + const modalId = modals.openConfirmModal({ + ...modalTheme, + title: 'Unarchive release', + children: ( + + Are you sure you want to unarchive release {props.id}? + + ), + labels: {confirm: 'Unarchive', cancel: 'Cancel'}, + cancelProps: {size: 'xs'}, + confirmProps: {color: 'dark', size: 'xs'}, + onCancel: () => console.log('Cancel'), + closeOnConfirm: false, + onConfirm: async () => { + showNotification({ + id: notificationId, + title: 'Unarchiving release', + message: `Unarchiving ${props.id}...`, + loading: true, + autoClose: false, + }); + await unarchiveRelease(props.id); + const newRelease = await getRelease(props.id); + setRelease(newRelease); + updateNotification({ + id: notificationId, + title: 'Unarchived release', + message: `Successfully unarchived ${props.id}`, + loading: false, + autoClose: 5000, + }); + modals.closeModal(modalId); + route(`/cms/releases/${props.id}`); + }, + }); + } + return (
@@ -73,18 +125,30 @@ export function EditReleasePage(props: {id: string}) { Edit Release: {props.id}
- - - - - + {release?.archivedAt ? ( + + + + + + ) : ( + + + + + + )}
diff --git a/packages/root-cms/ui/pages/ReleasePage/ReleasePage.tsx b/packages/root-cms/ui/pages/ReleasePage/ReleasePage.tsx index f3f2d5cc..ed5589d0 100644 --- a/packages/root-cms/ui/pages/ReleasePage/ReleasePage.tsx +++ b/packages/root-cms/ui/pages/ReleasePage/ReleasePage.tsx @@ -1,3 +1,5 @@ +import './ReleasePage.css'; + import { ActionIcon, Breadcrumbs, @@ -8,12 +10,7 @@ import { } from '@mantine/core'; import {useModals} from '@mantine/modals'; import {showNotification, updateNotification} from '@mantine/notifications'; -import { - IconArchive, - IconArchiveOff, - IconRestore, - IconSettings, -} from '@tabler/icons-preact'; +import {IconSettings} from '@tabler/icons-preact'; import {useEffect, useState} from 'preact/hooks'; import {ConditionalTooltip} from '../../components/ConditionalTooltip/ConditionalTooltip.js'; import {DocPreviewCard} from '../../components/DocPreviewCard/DocPreviewCard.js'; @@ -31,11 +28,8 @@ import { cancelScheduledRelease, getRelease, publishRelease, - archiveRelease, - unarchiveRelease, } from '../../utils/release.js'; import {timestamp} from '../../utils/time.js'; -import './ReleasePage.css'; export function ReleasePage(props: {id: string}) { const [loading, setLoading] = useState(true); @@ -43,12 +37,6 @@ export function ReleasePage(props: {id: string}) { const [updated, setUpdated] = useState(0); const id = props.id; - const modals = useModals(); - const modalTheme = useModalTheme(); - const {roles} = useProjectRoles(); - const currentUserEmail = window.firebase.user.email || ''; - const canPublish = testCanPublish(roles, currentUserEmail); - async function init() { setLoading(true); await notifyErrors(async () => { @@ -68,48 +56,6 @@ export function ReleasePage(props: {id: string}) { init(); } - function onArchiveClicked() { - modals.openConfirmModal({ - ...modalTheme, - title: `Archive release: ${id}`, - children: ( - - Are you sure you want to archive this release? - - ), - labels: {confirm: 'Archive', cancel: 'Cancel'}, - cancelProps: {size: 'xs'}, - confirmProps: {color: 'dark', size: 'xs'}, - closeOnConfirm: true, - onConfirm: async () => { - await notifyErrors(async () => { - await archiveRelease(id); - }); - }, - }); - } - - function onUnarchiveClicked() { - modals.openConfirmModal({ - ...modalTheme, - title: `Unarchive release: ${id}`, - children: ( - - Are you sure you want to unarchive this release? - - ), - labels: {confirm: 'Unarchive', cancel: 'Cancel'}, - cancelProps: {size: 'xs'}, - confirmProps: {color: 'dark', size: 'xs'}, - closeOnConfirm: true, - onConfirm: async () => { - await notifyErrors(async () => { - await unarchiveRelease(id); - }); - }, - }); - } - return (
@@ -158,34 +104,6 @@ export function ReleasePage(props: {id: string}) { key={`data-sources-${updated}`} /> )} - {release && canPublish && ( -
- {release.archivedAt ? ( - - ) : ( - - )} -
- )} )}