Skip to content

Commit

Permalink
Re-enable Changelog - full client side filtering (#9240)
Browse files Browse the repository at this point in the history
* Revert "Revert "Revert "Add Changelog Maintence (#9236)"" (#9238)"

This reverts commit 83c8a98.

* Filter list on client side

* Change to fetch requests

* Add cache tags

* Add href to pages

* Fix prerender

* Add CI excpetion

* Cache buster

* Next try to get caching right
  • Loading branch information
HazAT authored Feb 25, 2024
1 parent 83c8a98 commit a8dec43
Show file tree
Hide file tree
Showing 22 changed files with 1,005 additions and 194 deletions.
96 changes: 96 additions & 0 deletions app/changelog/%5Fadmin/[id]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {Fragment, Suspense} from 'react';
import Link from 'next/link';

import {editChangelog} from 'sentry-docs/actions/changelog';
import {FileUpload} from 'sentry-docs/components/changelog/fileUpload';
import {ForwardRefEditor} from 'sentry-docs/components/changelog/forwardRefEditor';
import {TitleSlug} from 'sentry-docs/components/changelog/titleSlug';
import {Button} from 'sentry-docs/components/changelog/ui/Button';
import {Select} from 'sentry-docs/components/changelog/ui/Select';
import prisma from 'sentry-docs/prisma';

export default async function ChangelogCreatePage({params}) {
const categories = await prisma.category.findMany({
orderBy: {
name: 'asc',
},
});
const changelog = await prisma.changelog.findUnique({
where: {id: params.id},
include: {
author: true,
categories: true,
},
});

if (!changelog) {
return (
<Fragment>
<header>
<h2>Changelog not found</h2>
</header>
<footer>
<Link href="/changelogs">Return to Changelogs list</Link>
</footer>
</Fragment>
);
}

return (
<section className="overflow-x-auto col-start-3 col-span-8">
<form action={editChangelog} className="px-2 w-full">
<input type="hidden" name="id" value={changelog.id} />
<TitleSlug defaultSlug={changelog.slug} defaultTitle={changelog.title} />
<FileUpload defaultFile={changelog.image || ''} />
<div className="my-6">
<label htmlFor="summary" className="block text-xs font-medium text-gray-700">
Summary
<Fragment>
&nbsp;<span className="font-bold text-secondary">*</span>
</Fragment>
</label>
<textarea name="summary" className="w-full" required>
{changelog.summary}
</textarea>
<span className="text-xs text-gray-500 italic">
This will be shown in the list
</span>
</div>
<div>
<Select
name="categories"
className="mt-1 mb-6"
label="Category"
placeholder="Select Category"
defaultValue={changelog.categories.map(category => ({
label: category.name,
value: category.name,
}))}
options={categories.map(category => ({
label: category.name,
value: category.name,
}))}
isMulti
/>
</div>

<Suspense fallback={null}>
<ForwardRefEditor
name="content"
defaultValue={changelog.content || ''}
className="w-full"
/>
</Suspense>

<footer className="flex items-center justify-between mt-2 mb-8">
<Link href="/changelog/_admin" className="underline text-gray-500">
Return to Changelogs list
</Link>
<div>
<Button type="submit">Update</Button>
</div>
</footer>
</form>
</section>
);
}
25 changes: 25 additions & 0 deletions app/changelog/%5Fadmin/confirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';

export default function Confirm({changelog, action, children}) {
return (
<form
action={action}
className="inline-block"
onSubmit={e => {
e.preventDefault();
// eslint-disable-next-line no-alert
if (confirm('Are you sure?')) {
action(new FormData(e.currentTarget));
}
}}
>
<input type="hidden" name="id" value={changelog.id} />
<button
type="submit"
className="text-indigo-600 hover:bg-indigo-100 rounded-md px-1 py-2 text-xs whitespace-nowrap"
>
{children}
</button>
</form>
);
}
65 changes: 65 additions & 0 deletions app/changelog/%5Fadmin/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {Fragment} from 'react';
import Link from 'next/link';

import {createChangelog} from 'sentry-docs/actions/changelog';
import {FileUpload} from 'sentry-docs/components/changelog/fileUpload';
import {ForwardRefEditor} from 'sentry-docs/components/changelog/forwardRefEditor';
import {TitleSlug} from 'sentry-docs/components/changelog/titleSlug';
import {Button} from 'sentry-docs/components/changelog/ui/Button';
import {Select} from 'sentry-docs/components/changelog/ui/Select';
import prisma from 'sentry-docs/prisma';

export default async function ChangelogCreatePage() {
const categories = await prisma.category.findMany({
orderBy: {
name: 'asc',
},
});

return (
<section className="overflow-x-auto col-start-3 col-span-8">
<form action={createChangelog} className="px-2 w-full">
<TitleSlug />
<FileUpload />
<div className="my-6">
<label htmlFor="summary" className="block text-xs font-medium text-gray-700">
Summary
<Fragment>
&nbsp;<span className="font-bold text-secondary">*</span>
</Fragment>
</label>
<textarea name="summary" className="w-full" required />
<span className="text-xs text-gray-500 italic">
This will be shown in the list
</span>
</div>
<div>
<Select
name="categories"
className="mt-1 mb-6"
label="Category"
placeholder="Select Category"
options={categories.map(category => ({
label: category.name,
value: category.name,
}))}
isMulti
/>
</div>

<ForwardRefEditor name="content" className="w-full" />

<footer className="flex items-center justify-between mt-2">
<Link href="/changelog/_admin" className="underline text-gray-500">
Return to Changelogs list
</Link>
<div>
<Button type="submit">Create (not published yet)</Button>
<br />
<span className="text-xs text-gray-500 italic">You can publish it later</span>
</div>
</footer>
</form>
</section>
);
}
33 changes: 33 additions & 0 deletions app/changelog/%5Fadmin/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {type ReactNode, Suspense} from 'react';
import {GET} from 'app/changelog/api/auth/[...nextauth]/route';
import type {Metadata} from 'next';
import {getServerSession} from 'next-auth/next';

import LoginButton from 'sentry-docs/components/changelog/loginButton';
import NextAuthSessionProvider from 'sentry-docs/components/nextAuthSessionProvider';

export const metadata: Metadata = {
robots: 'noindex, nofollow',
};

export default async function Layout({children}: {children: ReactNode}) {
const session = await getServerSession(GET);
let content = (
<div className="relative min-h-[calc(100vh-8rem)] w-full mx-auto bg-gray-200 pt-16 grid grid-cols-12">
{children}
<div className="fixed top-3 right-4 z-50">
<Suspense fallback={null}>
<LoginButton />
</Suspense>
</div>
</div>
);
if (!session) {
content = (
<div className="relative min-h-[calc(100vh-8rem)] w-full mx-auto bg-gray-200 pt-16 flex items-center justify-center">
<LoginButton />
</div>
);
}
return <NextAuthSessionProvider>{content}</NextAuthSessionProvider>;
}
13 changes: 13 additions & 0 deletions app/changelog/%5Fadmin/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function Loading() {
return (
<div className="fixed inset-0 flex items-center justify-center">
<h3 className="text-2xl text-primary font-semibold">
<div
className="mx-auto mb-8 h-16 w-16 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"
role="status"
/>{' '}
Loading...
</h3>
</div>
);
}
121 changes: 121 additions & 0 deletions app/changelog/%5Fadmin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {Fragment} from 'react';
import {PlusIcon} from '@radix-ui/react-icons';
import {Button, Text} from '@radix-ui/themes';
import Link from 'next/link';

import {
deleteChangelog,
publishChangelog,
unpublishChangelog,
} from 'sentry-docs/actions/changelog';
import prisma from 'sentry-docs/prisma';

import Confirm from './confirm';

export default async function ChangelogsListPage() {
const changelogs = await prisma.changelog.findMany({
include: {
categories: true,
author: true,
},
orderBy: {
createdAt: 'desc',
},
});

return (
<Fragment>
<header className="mb-4 col-start-2 col-span-2 text-left">
<Button>
<PlusIcon />
<Link href="/changelog/_admin/create">New Changelog</Link>
</Button>
</header>
<section className="overflow-x-auto col-start-2 col-span-10 shadow-md rounded-lg">
<table className="w-full text-sm text-left text-gray-500">
<thead className="text-xs text-gray-700 uppercase bg-gray-50">
<tr>
<th className="whitespace-nowrap px-4 py-2">Title</th>
<th className="whitespace-nowrap px-4 py-2">Categories</th>
<th className="whitespace-nowrap px-4 py-2">Published by</th>
<th className="px-4 py-2" />
</tr>
</thead>
<tbody className="divide-y divide-gray-200 bg-white border-b hover:bg-gray-50 dark:hover:bg-gray-600">
{changelogs.length === 0 && (
<tr>
<td
colSpan={10}
className="text-center font-medium text-gray-900 whitespace-nowrap"
>
No changelogs found
</td>
</tr>
)}

{changelogs.map(changelog => (
<tr key={changelog.id} className="bg-white border-b hover:bg-gray-50">
<td className="px-6 py-4 font-medium text-gray-900">{changelog.title}</td>

<td className="px-4 py-2">
{changelog.categories.map(category => (
<div
key={category.id}
className="inline whitespace-nowrap p-2 uppercase shadow-sm no-underline rounded-full text-red text-xs mr-1 bg-gray-100"
>
{category.name}
</div>
))}
</td>
<td className="px-4 py-2 text-center">
{changelog.published && (
<span className="text-gray-500">
<Text size="1">
{' '}
{new Date(changelog.publishedAt || '').toLocaleDateString(
undefined,
{month: 'long', day: 'numeric'}
)}
</Text>
<br />
</span>
)}
<Text size="1">{changelog.author?.name}</Text>
</td>

<td className="px-4 py-2">
<div className="flex h-full justify-end">
<Link
href={`/changelog/${changelog.slug}`}
className="text-indigo-600 hover:bg-indigo-100 rounded-md px-1 py-2 text-xs whitespace-nowrap"
>
👀 Show
</Link>
<Link
href={`/changelog/_admin/${changelog.id}/edit`}
className="text-indigo-600 hover:bg-indigo-100 rounded-md px-1 py-2 text-xs whitespace-nowrap"
>
📝 Edit
</Link>
{changelog.published ? (
<Confirm action={unpublishChangelog} changelog={changelog}>
⛔️ Unpublish?
</Confirm>
) : (
<Confirm action={publishChangelog} changelog={changelog}>
✅ Publish?
</Confirm>
)}
<Confirm action={deleteChangelog} changelog={changelog}>
💀 Delete?
</Confirm>
</div>
</td>
</tr>
))}
</tbody>
</table>
</section>
</Fragment>
);
}
Loading

0 comments on commit a8dec43

Please sign in to comment.