feat: Complete Stage 2 frontend refactor
- Removed deprecated fields from Content and Task models, including entity_type, sync_status, and cluster_role. - Updated Content model to include new fields: content_type, content_structure, taxonomy_terms, source, external_id, and cluster_id. - Refactored Writer module components (Content, ContentView, Dashboard, Tasks) to align with new schema. - Enhanced Dashboard metrics and removed unused filters. - Implemented ClusterDetail page to display cluster information and associated content. - Updated API service interfaces to reflect changes in data structure. - Adjusted sorting and filtering logic across various components to accommodate new field names and types. - Improved user experience by providing loading states and error handling in data fetching.
This commit is contained in:
@@ -140,58 +140,6 @@ export const createTasksPageConfig = (
|
||||
width: '200px',
|
||||
render: (_value: string, row: Task) => row.cluster_name || '-',
|
||||
},
|
||||
// Stage 3: Metadata columns
|
||||
{
|
||||
key: 'entity_type',
|
||||
label: 'Entity Type',
|
||||
sortable: true,
|
||||
sortField: 'entity_type',
|
||||
width: '120px',
|
||||
defaultVisible: true,
|
||||
render: (value: string, row: Task) => {
|
||||
const entityType = value || row.entity_type;
|
||||
if (!entityType) {
|
||||
return <span className="text-gray-400 dark:text-gray-500">-</span>;
|
||||
}
|
||||
const typeLabels: Record<string, string> = {
|
||||
'blog_post': 'Blog Post',
|
||||
'article': 'Article',
|
||||
'product': 'Product',
|
||||
'service': 'Service',
|
||||
'taxonomy': 'Taxonomy',
|
||||
'page': 'Page',
|
||||
};
|
||||
return (
|
||||
<Badge color="info" size="sm" variant="light">
|
||||
{typeLabels[entityType] || entityType}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'cluster_role',
|
||||
label: 'Role',
|
||||
sortable: true,
|
||||
sortField: 'cluster_role',
|
||||
width: '100px',
|
||||
defaultVisible: false,
|
||||
render: (value: string, row: Task) => {
|
||||
const role = value || row.cluster_role;
|
||||
if (!role) {
|
||||
return <span className="text-gray-400 dark:text-gray-500">-</span>;
|
||||
}
|
||||
const roleColors: Record<string, 'primary' | 'success' | 'warning'> = {
|
||||
'hub': 'primary',
|
||||
'supporting': 'success',
|
||||
'attribute': 'warning',
|
||||
};
|
||||
return (
|
||||
<Badge color={roleColors[role] || 'primary'} size="sm" variant="light">
|
||||
{role.charAt(0).toUpperCase() + role.slice(1)}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'taxonomy_name',
|
||||
label: 'Taxonomy',
|
||||
@@ -210,29 +158,48 @@ export const createTasksPageConfig = (
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'content_type',
|
||||
label: 'Content Type',
|
||||
sortable: true,
|
||||
sortField: 'content_type',
|
||||
width: '120px',
|
||||
render: (value: string) => {
|
||||
const typeLabels: Record<string, string> = {
|
||||
'post': 'Post',
|
||||
'page': 'Page',
|
||||
'product': 'Product',
|
||||
'service': 'Service',
|
||||
'category': 'Category',
|
||||
'tag': 'Tag',
|
||||
};
|
||||
return (
|
||||
<Badge color="primary" size="sm" variant="light">
|
||||
{typeLabels[value] || value || '-'}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'content_structure',
|
||||
label: 'Structure',
|
||||
sortable: true,
|
||||
sortField: 'content_structure',
|
||||
width: '150px',
|
||||
render: (value: string) => (
|
||||
<Badge color="info" size="sm" variant="light">
|
||||
{value?.replace('_', ' ') || '-'}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'content_type',
|
||||
label: 'Type',
|
||||
sortable: true,
|
||||
sortField: 'content_type',
|
||||
width: '120px',
|
||||
render: (value: string) => (
|
||||
<Badge color="info" size="sm" variant="light">
|
||||
{value?.replace('_', ' ') || '-'}
|
||||
</Badge>
|
||||
),
|
||||
render: (value: string) => {
|
||||
const structureLabels: Record<string, string> = {
|
||||
'article': 'Article',
|
||||
'listicle': 'Listicle',
|
||||
'guide': 'Guide',
|
||||
'comparison': 'Comparison',
|
||||
'product_page': 'Product Page',
|
||||
};
|
||||
return (
|
||||
<Badge color="info" size="sm" variant="light">
|
||||
{structureLabels[value] || value || '-'}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
...statusColumn,
|
||||
@@ -362,39 +329,31 @@ export const createTasksPageConfig = (
|
||||
{ value: 'completed', label: 'Completed' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'content_structure',
|
||||
label: 'Structure',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '', label: 'All Structures' },
|
||||
{ value: 'cluster_hub', label: 'Cluster Hub' },
|
||||
{ value: 'landing_page', label: 'Landing Page' },
|
||||
{ value: 'pillar_page', label: 'Pillar Page' },
|
||||
{ value: 'supporting_page', label: 'Supporting Page' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'content_type',
|
||||
label: 'Type',
|
||||
label: 'Content Type',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '', label: 'All Types' },
|
||||
{ value: 'blog_post', label: 'Blog Post' },
|
||||
{ value: 'article', label: 'Article' },
|
||||
{ value: 'guide', label: 'Guide' },
|
||||
{ value: 'tutorial', label: 'Tutorial' },
|
||||
{ value: 'post', label: 'Post' },
|
||||
{ value: 'page', label: 'Page' },
|
||||
{ value: 'product', label: 'Product' },
|
||||
{ value: 'service', label: 'Service' },
|
||||
{ value: 'category', label: 'Category' },
|
||||
{ value: 'tag', label: 'Tag' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'source',
|
||||
label: 'Source',
|
||||
key: 'content_structure',
|
||||
label: 'Content Structure',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '', label: 'All Sources' },
|
||||
{ value: 'site_builder', label: 'Site Builder' },
|
||||
{ value: 'ideas', label: 'Ideas' },
|
||||
{ value: 'manual', label: 'Manual' },
|
||||
{ value: '', label: 'All Structures' },
|
||||
{ value: 'article', label: 'Article' },
|
||||
{ value: 'listicle', label: 'Listicle' },
|
||||
{ value: 'guide', label: 'Guide' },
|
||||
{ value: 'comparison', label: 'Comparison' },
|
||||
{ value: 'product_page', label: 'Product Page' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -409,21 +368,6 @@ export const createTasksPageConfig = (
|
||||
})(),
|
||||
dynamicOptions: 'clusters',
|
||||
},
|
||||
// Stage 3: Entity type filter
|
||||
{
|
||||
key: 'entity_type',
|
||||
label: 'Entity Type',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: '', label: 'All Entity Types' },
|
||||
{ value: 'blog_post', label: 'Blog Post' },
|
||||
{ value: 'article', label: 'Article' },
|
||||
{ value: 'product', label: 'Product' },
|
||||
{ value: 'service', label: 'Service' },
|
||||
{ value: 'taxonomy', label: 'Taxonomy' },
|
||||
{ value: 'page', label: 'Page' },
|
||||
],
|
||||
},
|
||||
],
|
||||
formFields: (clusters: Array<{ id: number; name: string }>) => [
|
||||
{
|
||||
@@ -473,28 +417,31 @@ export const createTasksPageConfig = (
|
||||
key: 'content_structure',
|
||||
label: 'Content Structure',
|
||||
type: 'select',
|
||||
value: handlers.formData.content_structure || 'blog_post',
|
||||
value: handlers.formData.content_structure || 'article',
|
||||
onChange: (value: any) =>
|
||||
handlers.setFormData({ ...handlers.formData, content_structure: value }),
|
||||
options: [
|
||||
{ value: 'cluster_hub', label: 'Cluster Hub' },
|
||||
{ value: 'landing_page', label: 'Landing Page' },
|
||||
{ value: 'pillar_page', label: 'Pillar Page' },
|
||||
{ value: 'supporting_page', label: 'Supporting Page' },
|
||||
{ value: 'article', label: 'Article' },
|
||||
{ value: 'listicle', label: 'Listicle' },
|
||||
{ value: 'guide', label: 'Guide' },
|
||||
{ value: 'comparison', label: 'Comparison' },
|
||||
{ value: 'product_page', label: 'Product Page' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'content_type',
|
||||
label: 'Content Type',
|
||||
type: 'select',
|
||||
value: handlers.formData.content_type || 'blog_post',
|
||||
value: handlers.formData.content_type || 'post',
|
||||
onChange: (value: any) =>
|
||||
handlers.setFormData({ ...handlers.formData, content_type: value }),
|
||||
options: [
|
||||
{ value: 'blog_post', label: 'Blog Post' },
|
||||
{ value: 'article', label: 'Article' },
|
||||
{ value: 'guide', label: 'Guide' },
|
||||
{ value: 'tutorial', label: 'Tutorial' },
|
||||
{ value: 'post', label: 'Post' },
|
||||
{ value: 'page', label: 'Page' },
|
||||
{ value: 'product', label: 'Product' },
|
||||
{ value: 'service', label: 'Service' },
|
||||
{ value: 'category', label: 'Category' },
|
||||
{ value: 'tag', label: 'Tag' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user