Add status property to content item structure (#44)
* Add status property to content item structure This commit introduces a new `status` property to the content item structure, allowing content items to maintain a status such as 'draft', 'published', 'review', 'pending'. This status is mapped to the corresponding status in Wordpress and Keystatic clients to ensure consistent usage across platforms. Content retrieval methods now also include a status filter. * Refactor code for style and readability improvements This commit includes changes in various files across different packages to improve code readability, including adjusting spacing and breaking down complex lines into simpler parts. In addition, the switch statement in `wp-client.ts` has been refactored and status values are now held in variables, and the CSS classes in `global-loader.tsx` have been reorganized.
This commit is contained in:
committed by
GitHub
parent
21f42f14ce
commit
3393863dd2
@@ -8,6 +8,7 @@ export namespace Cms {
|
||||
content: unknown;
|
||||
publishedAt: string;
|
||||
image: string | undefined;
|
||||
status: ContentItemStatus;
|
||||
slug: string;
|
||||
categories: Category[];
|
||||
tags: Tag[];
|
||||
@@ -16,6 +17,8 @@ export namespace Cms {
|
||||
parentId: string | undefined;
|
||||
}
|
||||
|
||||
export type ContentItemStatus = 'draft' | 'published' | 'review' | 'pending';
|
||||
|
||||
export interface Category {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -38,6 +41,7 @@ export namespace Cms {
|
||||
language?: string | undefined;
|
||||
sortDirection?: 'asc' | 'desc';
|
||||
sortBy?: 'publishedAt' | 'order' | 'title';
|
||||
status?: ContentItemStatus;
|
||||
}
|
||||
|
||||
export interface GetCategoriesOptions {
|
||||
@@ -74,6 +78,7 @@ export abstract class CmsClient {
|
||||
abstract getContentItemBySlug(params: {
|
||||
slug: string;
|
||||
collection: string;
|
||||
status?: Cms.ContentItemStatus;
|
||||
}): Promise<Cms.ContentItem | undefined>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import Markdoc from '@markdoc/markdoc';
|
||||
|
||||
import { Cms, CmsClient } from '@kit/cms';
|
||||
|
||||
import { createKeystaticReader } from './create-reader';
|
||||
@@ -27,6 +25,12 @@ class KeystaticClient implements CmsClient {
|
||||
|
||||
const filtered = docs
|
||||
.filter((item) => {
|
||||
const status = options?.status ?? 'published';
|
||||
|
||||
if (item.entry.status !== status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const categoryMatch = options?.categories?.length
|
||||
? options.categories.find((category) =>
|
||||
item.entry.categories.includes(category),
|
||||
@@ -89,7 +93,11 @@ class KeystaticClient implements CmsClient {
|
||||
};
|
||||
}
|
||||
|
||||
async getContentItemBySlug(params: { slug: string; collection: string }) {
|
||||
async getContentItemBySlug(params: {
|
||||
slug: string;
|
||||
collection: string;
|
||||
status?: Cms.ContentItemStatus;
|
||||
}) {
|
||||
const reader = await createKeystaticReader();
|
||||
|
||||
const collection =
|
||||
@@ -100,11 +108,18 @@ class KeystaticClient implements CmsClient {
|
||||
}
|
||||
|
||||
const doc = await reader.collections[collection].read(params.slug);
|
||||
const status = params.status ?? 'published';
|
||||
|
||||
// verify that the document exists
|
||||
if (!doc) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
// check the document matches the status provided in the params
|
||||
if (doc.status !== status) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
const allPosts = await reader.collections[collection].all();
|
||||
|
||||
const children = allPosts.filter(
|
||||
@@ -136,13 +151,15 @@ class KeystaticClient implements CmsClient {
|
||||
slug: string;
|
||||
},
|
||||
>(item: Type, children: Type[] = []): Promise<Cms.ContentItem> {
|
||||
const { transform, renderers } = await import('@markdoc/markdoc');
|
||||
|
||||
const publishedAt = item.entry.publishedAt
|
||||
? new Date(item.entry.publishedAt)
|
||||
: new Date();
|
||||
|
||||
const markdoc = await item.entry.content();
|
||||
const content = Markdoc.transform(markdoc.node);
|
||||
const html = Markdoc.renderers.html(content);
|
||||
const content = transform(markdoc.node);
|
||||
const html = renderers.html(content);
|
||||
|
||||
return {
|
||||
id: item.slug,
|
||||
@@ -153,6 +170,7 @@ class KeystaticClient implements CmsClient {
|
||||
publishedAt: publishedAt.toISOString(),
|
||||
content: html,
|
||||
image: item.entry.image ?? undefined,
|
||||
status: item.entry.status,
|
||||
categories:
|
||||
item.entry.categories.map((item) => {
|
||||
return {
|
||||
|
||||
@@ -124,6 +124,16 @@ function getKeystaticCollections(path: string) {
|
||||
language: fields.text({ label: 'Language' }),
|
||||
order: fields.number({ label: 'Order' }),
|
||||
content: getContentField(),
|
||||
status: fields.select({
|
||||
defaultValue: 'draft',
|
||||
label: 'Status',
|
||||
options: [
|
||||
{ label: 'Draft', value: 'draft' },
|
||||
{ label: 'Published', value: 'published' },
|
||||
{ label: 'Review', value: 'review' },
|
||||
{ label: 'Pending', value: 'pending' },
|
||||
],
|
||||
}),
|
||||
},
|
||||
}),
|
||||
documentation: collection({
|
||||
@@ -149,6 +159,16 @@ function getKeystaticCollections(path: string) {
|
||||
}),
|
||||
categories: fields.array(fields.text({ label: 'Category' })),
|
||||
tags: fields.array(fields.text({ label: 'Tag' })),
|
||||
status: fields.select({
|
||||
defaultValue: 'draft',
|
||||
label: 'Status',
|
||||
options: [
|
||||
{ label: 'Draft', value: 'draft' },
|
||||
{ label: 'Published', value: 'published' },
|
||||
{ label: 'Review', value: 'review' },
|
||||
{ label: 'Pending', value: 'pending' },
|
||||
],
|
||||
}),
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type {
|
||||
WP_Post_Status_Name,
|
||||
WP_REST_API_Category,
|
||||
WP_REST_API_Post,
|
||||
WP_REST_API_Tag,
|
||||
@@ -104,7 +105,9 @@ class WordpressClient implements CmsClient {
|
||||
const total = totalHeader ? Number(totalHeader) : 0;
|
||||
const results = (await response.json()) as WP_REST_API_Post[];
|
||||
|
||||
const posts = await Promise.all(
|
||||
const status = options.status ?? 'published';
|
||||
|
||||
const postsResults = await Promise.allSettled(
|
||||
results.map(async (item: WP_REST_API_Post) => {
|
||||
let parentId: string | undefined;
|
||||
|
||||
@@ -116,6 +119,12 @@ class WordpressClient implements CmsClient {
|
||||
parentId = item.parent.toString();
|
||||
}
|
||||
|
||||
const mappedStatus = mapToStatus(item.status as WP_Post_Status_Name);
|
||||
|
||||
if (mappedStatus !== status) {
|
||||
throw new Error('Status does not match');
|
||||
}
|
||||
|
||||
const categories = await this.getCategoriesByIds(item.categories ?? []);
|
||||
const tags = await this.getTagsByIds(item.tags ?? []);
|
||||
const image = item.featured_media ? this.getFeaturedMedia(item) : '';
|
||||
@@ -130,6 +139,7 @@ class WordpressClient implements CmsClient {
|
||||
url: item.link,
|
||||
slug: item.slug,
|
||||
publishedAt: item.date,
|
||||
status: mappedStatus ?? 'draft',
|
||||
categories: categories,
|
||||
tags: tags,
|
||||
parentId,
|
||||
@@ -139,6 +149,10 @@ class WordpressClient implements CmsClient {
|
||||
}),
|
||||
);
|
||||
|
||||
const posts = postsResults
|
||||
.filter((item) => item.status === 'fulfilled')
|
||||
.map((item) => item.value);
|
||||
|
||||
return {
|
||||
total,
|
||||
items: posts,
|
||||
@@ -148,9 +162,11 @@ class WordpressClient implements CmsClient {
|
||||
async getContentItemBySlug({
|
||||
slug,
|
||||
collection,
|
||||
status,
|
||||
}: {
|
||||
slug: string;
|
||||
collection: string;
|
||||
status?: Cms.ContentItemStatus;
|
||||
}) {
|
||||
const searchParams = new URLSearchParams({
|
||||
_embed: 'true',
|
||||
@@ -174,6 +190,15 @@ class WordpressClient implements CmsClient {
|
||||
return;
|
||||
}
|
||||
|
||||
const mappedStatus = status
|
||||
? mapToStatus(item.status as WP_Post_Status_Name)
|
||||
: undefined;
|
||||
const statusMatch = status ? mappedStatus === status : true;
|
||||
|
||||
if (!statusMatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
const categories = await this.getCategoriesByIds(item.categories ?? []);
|
||||
const tags = await this.getTagsByIds(item.tags ?? []);
|
||||
const image = item.featured_media ? this.getFeaturedMedia(item) : '';
|
||||
@@ -189,6 +214,7 @@ class WordpressClient implements CmsClient {
|
||||
content: item.content.rendered,
|
||||
slug: item.slug,
|
||||
publishedAt: item.date,
|
||||
status: mappedStatus ?? 'draft',
|
||||
categories,
|
||||
tags,
|
||||
parentId: item.parent?.toString(),
|
||||
@@ -370,3 +396,23 @@ function mapSortByParam(sortBy: string) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function mapToStatus(status: WP_Post_Status_Name): Cms.ContentItemStatus {
|
||||
const Draft = 'draft' as WP_Post_Status_Name;
|
||||
const Publish = 'publish' as WP_Post_Status_Name;
|
||||
const Pending = 'pending' as WP_Post_Status_Name;
|
||||
|
||||
switch (status) {
|
||||
case Draft:
|
||||
return 'draft';
|
||||
|
||||
case Publish:
|
||||
return 'published';
|
||||
|
||||
case Pending:
|
||||
return 'pending';
|
||||
|
||||
default:
|
||||
return 'draft';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export function MagicLinkAuthContainer({
|
||||
}),
|
||||
),
|
||||
defaultValues: {
|
||||
email: defaultValues?.email ?? ''
|
||||
email: defaultValues?.email ?? '',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export function SignUpMethodsContainer(props: {
|
||||
}) {
|
||||
const redirectUrl = getCallbackUrl(props);
|
||||
const defaultValues = getDefaultValues();
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<If condition={props.inviteToken}>
|
||||
|
||||
@@ -102,7 +102,10 @@ class AccountInvitationsWebhookService {
|
||||
const { getMailer } = await import('@kit/mailers');
|
||||
|
||||
const mailer = await getMailer();
|
||||
const link = this.getInvitationLink(invitation.invite_token, invitation.email);
|
||||
const link = this.getInvitationLink(
|
||||
invitation.invite_token,
|
||||
invitation.email,
|
||||
);
|
||||
|
||||
const { html, subject } = await renderInviteEmail({
|
||||
link,
|
||||
|
||||
@@ -148,7 +148,7 @@ class AuthCallbackService {
|
||||
|
||||
const urlParams = new URLSearchParams({
|
||||
invite_token: inviteToken,
|
||||
email: emailParam ?? ''
|
||||
email: emailParam ?? '',
|
||||
});
|
||||
|
||||
nextUrl = `${params.joinTeamPath}?${urlParams.toString()}`;
|
||||
|
||||
@@ -22,7 +22,7 @@ export function GlobalLoader({
|
||||
<If condition={displaySpinner}>
|
||||
<div
|
||||
className={
|
||||
'flex flex-1 flex-col items-center justify-center duration-500 animate-in fade-in zoom-in-80 slide-in-from-bottom-12'
|
||||
'zoom-in-80 flex flex-1 flex-col items-center justify-center duration-500 animate-in fade-in slide-in-from-bottom-12'
|
||||
}
|
||||
>
|
||||
<LoadingOverlay displayLogo={displayLogo} fullPage={fullPage} />
|
||||
|
||||
Reference in New Issue
Block a user