payload-kanban-board
Version:
A kanban board plugin for Payload CMS
144 lines (143 loc) • 6.34 kB
JavaScript
import { APIError } from 'payload';
import generateOrderRank from './hooks/generateOrderRank.js';
// export * from './types.js'
export const payloadKanbanBoard = (pluginOptions)=>(config)=>{
if (!config.collections) {
config.collections = [];
}
if (pluginOptions.collections) {
config.collections = config.collections.map((collection)=>{
const pluginConfig = pluginOptions.collections[collection.slug];
if (!pluginConfig || !pluginConfig.enabled) {
return collection;
}
// Prepare statuses for the kanbanStatus field
const statuses = pluginConfig.config.statuses.map((status)=>({
label: status.label,
value: status.value
}));
// Add kanban-specific fields
const kanbanStatusField = {
name: 'kanbanStatus',
label: 'Kanban status',
type: 'select',
options: statuses,
defaultValue: pluginConfig.config.defaultStatus,
admin: {
...pluginConfig.config.fieldAdmin,
position: 'sidebar'
},
access: pluginConfig.config.fieldAccess || {},
hooks: {
...pluginConfig.config.fieldHooks,
beforeValidate: [
...pluginConfig.config.fieldHooks?.beforeChange || [],
async ({ value, data, req })=>{
// Find the collection configuration for the current collection
const statusList = pluginConfig.config.statuses;
if (!statusList) {
return; // No configuration found, skip validation
}
// Find the status object that matches the new value
const newStatus = statusList.find((status)=>status.value === value);
if (!newStatus) {
throw new Error(`Invalid status: ${value}`) // New status is not in the allowed list
;
}
// If the status has a dropValidation function, call it
if (newStatus.dropValidation) {
const validationResult = newStatus.dropValidation({
data,
user: req.user
});
if (validationResult) {
data.kanbanMeta = validationResult;
if (!validationResult?.dropAble) {
throw new APIError(validationResult?.message || '', 401);
}
}
}
}
]
}
};
const kanbanOrderRankField = {
name: 'kanbanOrderRank',
type: 'text',
admin: {
hidden: true
}
};
// Update fields
const updatedFields = [
...collection.fields || [],
kanbanStatusField,
kanbanOrderRankField
];
// Update hooks
const updatedHooks = {
...collection.hooks,
beforeChange: [
...collection.hooks?.beforeChange || [],
generateOrderRank
]
};
// Update admin configuration
const updatedAdmin = {
...collection.admin,
pagination: {
...collection.admin?.pagination,
defaultLimit: collection.admin?.pagination?.defaultLimit ?? 100
},
components: {
...collection.admin?.components,
views: {
...collection.admin?.components?.views,
...pluginConfig.enabled ? {
list: {
Component: 'payload-kanban-board/dist/exports/client.js#WorkflowView',
// Component: 'payload-kanban-board/client#WorkflowView',
props: {
config: pluginConfig.config,
pluginConfig: pluginConfig.config
}
}
} : {}
}
},
custom: {
hideNoStatusColumn: pluginConfig.config.hideNoStatusColumn || false
}
};
return {
...collection,
fields: updatedFields,
hooks: updatedHooks,
admin: updatedAdmin
};
});
}
if (pluginOptions.disabled) {
return config;
}
if (!config.endpoints) {
config.endpoints = [];
}
if (!config.admin) {
config.admin = {};
}
if (!config.admin.components) {
config.admin.components = {};
}
if (!config.admin.components.beforeDashboard) {
config.admin.components.beforeDashboard = [];
}
const incomingOnInit = config.onInit;
config.onInit = async (payload)=>{
if (incomingOnInit) {
await incomingOnInit(payload);
}
};
return config;
};
//# sourceMappingURL=index.js.map