From 3d14986b0ac27bbbfdad6073e52a2721d967f04f Mon Sep 17 00:00:00 2001 From: Greg Karelin Date: Tue, 5 Mar 2024 19:03:36 +0400 Subject: [PATCH] Stylize cards --- README.md | 24 ++++++++- .../components/CategoryCard/CategoryCard.tsx | 6 +++ dev/src/payload.config.ts | 11 ++++ src/components/BoardCard/BoardCard.tsx | 15 ++---- src/components/BoardCard/sytles.scss | 9 ---- .../BoardCardDefaultContent.tsx | 29 +++++++++++ .../BoardCardDefaultContent/styles.scss | 7 +++ src/components/WorkflowView/WorkflowView.tsx | 50 ++++++++++--------- .../WorkflowViewConfigContext.ts | 6 +++ src/index.ts | 4 ++ 10 files changed, 117 insertions(+), 44 deletions(-) create mode 100644 dev/src/components/CategoryCard/CategoryCard.tsx create mode 100644 src/components/BoardCardDefaultContent/BoardCardDefaultContent.tsx create mode 100644 src/components/BoardCardDefaultContent/styles.scss create mode 100644 src/components/WorkflowViewConfigContext/WorkflowViewConfigContext.ts diff --git a/README.md b/README.md index 8b9b4cd..38aef34 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,28 @@ const config = buildConfig({ }); ``` +## Stylizing the cards + +```typescript +import { payloadWorkflow } from 'payload-workflow'; +import type { BoardCardDefaultContentProps } from 'payload-workflow'; +import { Link } from "react-router-dom"; + +const config = buildConfig({ + collections: [ ... ], + plugins: [ + payloadWorkflow({ + 'my-collection-slug': { + statuses: [ ... ], + cardContentComponent: ({admin, data, link}: BoardCardDefaultContentProps) => ( + { data.title } + ) + } + }) + ], +}); +``` + ## Differences with the draft/publish system of Payload. The workflow plugin introduces a new field called `workflowStatus`. This field does not interact with the draft/publish @@ -56,7 +78,7 @@ For example: Automatically publish the document when the `workflowStatus` has be Upcoming Features / Ideas. Have a suggestion for the plugin? Feel free to open an issue or contribute! - [X] Payload 2.0 support -- [ ] Customize card properties (currently displays `title` and `createdAt`) +- [X] Customize card properties (currently displays `title` and `createdAt`) - [ ] Edit relationships directly from the card (e.g., assigning users to a document) - [X] Toggleable column for posts without a workflow status (Currently, documents lacking `workflowStatus` aren't visible on the board) diff --git a/dev/src/components/CategoryCard/CategoryCard.tsx b/dev/src/components/CategoryCard/CategoryCard.tsx new file mode 100644 index 0000000..eb3bcd4 --- /dev/null +++ b/dev/src/components/CategoryCard/CategoryCard.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import { BoardCardDefaultContentProps } from "../../../../src"; + +const CategoryCard = ({ data }: BoardCardDefaultContentProps) =>
{data.name}
+ +export default CategoryCard \ No newline at end of file diff --git a/dev/src/payload.config.ts b/dev/src/payload.config.ts index 0b1c89d..5177447 100644 --- a/dev/src/payload.config.ts +++ b/dev/src/payload.config.ts @@ -8,6 +8,7 @@ import Media from './collections/Media'; import { mongooseAdapter } from "@payloadcms/db-mongodb"; import { slateEditor } from "@payloadcms/richtext-slate"; import { webpackBundler } from "@payloadcms/bundler-webpack"; +import CategoryCard from "./components/CategoryCard/CategoryCard"; import { payloadWorkflow } from "../../src/index"; @@ -59,6 +60,16 @@ export default buildConfig({ ], defaultStatus: 'draft', hideNoStatusColumn: false + }, + [Categories.slug]: { + statuses: [ + {value: 'planned', label: 'Planned'}, + {value: 'active', label: 'Active'}, + {value: 'archived', label: 'Archived'}, + ], + defaultStatus: 'active', + hideNoStatusColumn: true, + cardContentComponent: CategoryCard } }) ], diff --git a/src/components/BoardCard/BoardCard.tsx b/src/components/BoardCard/BoardCard.tsx index 37a2bfd..7794512 100644 --- a/src/components/BoardCard/BoardCard.tsx +++ b/src/components/BoardCard/BoardCard.tsx @@ -1,9 +1,9 @@ import React, { forwardRef } from 'react' import { CollectionConfig } from "payload/types"; import { useConfig } from "payload/components/utilities"; -import { formatDate } from "payload/dist/admin/utilities/formatDate"; -import { Link } from 'react-router-dom'; +import { usePluginConfig } from "../WorkflowViewConfigContext/WorkflowViewConfigContext"; import './sytles.scss'; +import BoardCardDefaultContent from "../BoardCardDefaultContent/BoardCardDefaultContent"; const baseClass = 'board-card'; @@ -14,8 +14,9 @@ interface BoardCardProps { const BoardCard = forwardRef((props: BoardCardProps, ref: React.Ref) => { const {collection, data, ...rest} = props - const {admin: {dateFormat}, routes: {admin: payloadAdmin}} = useConfig(); + const {routes: {admin: payloadAdmin}} = useConfig(); const {slug, admin} = collection; + const {cardContentComponent: CardContent = BoardCardDefaultContent} = usePluginConfig(); return (
) => { ref={ ref } { ...rest } > -
- - { admin?.useAsTitle && data[admin.useAsTitle] } - { !admin?.useAsTitle && data.id } - -
- { formatDate(data.createdAt, dateFormat) } +
) }) diff --git a/src/components/BoardCard/sytles.scss b/src/components/BoardCard/sytles.scss index 7c91661..34f7011 100644 --- a/src/components/BoardCard/sytles.scss +++ b/src/components/BoardCard/sytles.scss @@ -1,15 +1,6 @@ @import "payload/scss"; .board-card { - - &__title { - overflow: hidden; - display: -webkit-box; - -webkit-line-clamp: 2; - line-clamp: 2; - -webkit-box-orient: vertical; - } - background: var(--theme-elevation-50); padding: base(1.25) $baseline; margin-bottom: 1rem; diff --git a/src/components/BoardCardDefaultContent/BoardCardDefaultContent.tsx b/src/components/BoardCardDefaultContent/BoardCardDefaultContent.tsx new file mode 100644 index 0000000..d43da6e --- /dev/null +++ b/src/components/BoardCardDefaultContent/BoardCardDefaultContent.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import { CollectionConfig } from "payload/types"; +import { Link } from "react-router-dom"; +import {formatDate} from "payload/dist/admin/utilities/formatDate"; +import {useConfig} from "payload/components/utilities"; + +export interface BoardCardDefaultContentProps { + link: string + admin: CollectionConfig['admin'] + data: any +} + +const baseClass = 'board-card-content'; + +const BoardCardDefaultContent = ({admin, data, link}: BoardCardDefaultContentProps) => { + const {admin: {dateFormat}} = useConfig(); + + return ( +
+ + {admin?.useAsTitle && data[admin.useAsTitle]} + {!admin?.useAsTitle && data.id} + +
{formatDate(data.createdAt, dateFormat)}
+
+ ) +} + +export default BoardCardDefaultContent; \ No newline at end of file diff --git a/src/components/BoardCardDefaultContent/styles.scss b/src/components/BoardCardDefaultContent/styles.scss new file mode 100644 index 0000000..1f4c3c3 --- /dev/null +++ b/src/components/BoardCardDefaultContent/styles.scss @@ -0,0 +1,7 @@ +.board-card-content { + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} \ No newline at end of file diff --git a/src/components/WorkflowView/WorkflowView.tsx b/src/components/WorkflowView/WorkflowView.tsx index 02f6103..5518113 100644 --- a/src/components/WorkflowView/WorkflowView.tsx +++ b/src/components/WorkflowView/WorkflowView.tsx @@ -15,6 +15,7 @@ import { useConfig } from "payload/components/utilities"; import { SelectionProvider } from "payload/dist/admin/components/views/collections/List/SelectionProvider"; import { ListControls } from 'payload/dist/admin/components/elements/ListControls' import DefaultList from "payload/dist/admin/components/views/collections/List/Default"; +import {WorkflowViewConfigContext} from "../WorkflowViewConfigContext/WorkflowViewConfigContext"; const baseClass = 'scrumboard'; @@ -83,32 +84,33 @@ const WorkflowView = (config: PluginCollectionConfig) => (props: ListProps) => { totalDocs={ data.totalDocs } > + + setShowingWorkflow(false) } + /> - setShowingWorkflow(false) } - /> - - + - + + diff --git a/src/components/WorkflowViewConfigContext/WorkflowViewConfigContext.ts b/src/components/WorkflowViewConfigContext/WorkflowViewConfigContext.ts new file mode 100644 index 0000000..66ecec4 --- /dev/null +++ b/src/components/WorkflowViewConfigContext/WorkflowViewConfigContext.ts @@ -0,0 +1,6 @@ +import React, {useContext} from "react"; +import {PluginCollectionConfig} from "../../index"; + +export const WorkflowViewConfigContext = React.createContext(undefined) + +export const usePluginConfig = () => useContext(WorkflowViewConfigContext); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 19285a3..b9dea72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,13 +2,17 @@ import { Config, Plugin } from "payload/config"; import { CollectionConfig, OptionObject } from "payload/types"; import generateOrderRank from "./hooks/generateOrderRank"; import WorkflowView from "./components/WorkflowView/WorkflowView"; +import { BoardCardDefaultContentProps } from "./components/BoardCardDefaultContent/BoardCardDefaultContent"; export interface PluginCollectionConfig { statuses: OptionObject[], defaultStatus?: string; hideNoStatusColumn?: boolean; + cardContentComponent?: React.ElementType } +export type { BoardCardDefaultContentProps } from "./components/BoardCardDefaultContent/BoardCardDefaultContent"; + const extendCollectionConfig = ( pluginConfig: Record, collections: CollectionConfig[]