This commit is contained in:
alorig
2025-11-22 05:50:07 +05:00
parent c1ce8de9fb
commit 554c1667b3
3 changed files with 144 additions and 4 deletions

View File

@@ -472,3 +472,63 @@ class ContentTaxonomyRelationSerializer(serializers.ModelSerializer):
def get_taxonomy_type(self, obj):
return obj.taxonomy.taxonomy_type if obj.taxonomy else None
class UpdatedTasksSerializer(serializers.ModelSerializer):
"""Updated Serializer for Tasks model with new fields."""
cluster_name = serializers.SerializerMethodField()
sector_name = serializers.SerializerMethodField()
idea_title = serializers.SerializerMethodField()
site_id = serializers.IntegerField(write_only=True, required=False)
sector_id = serializers.IntegerField(write_only=True, required=False)
content_html = serializers.SerializerMethodField()
content_primary_keyword = serializers.SerializerMethodField()
content_secondary_keywords = serializers.SerializerMethodField()
content_taxonomies = serializers.SerializerMethodField()
content_attributes = serializers.SerializerMethodField()
class Meta:
model = Tasks
fields = [
'id',
'title',
'description',
'keywords',
'cluster_id',
'cluster_name',
'sector_name',
'idea_id',
'idea_title',
'content_structure',
'content_type',
'status',
'content',
'word_count',
'meta_title',
'meta_description',
'content_html',
'content_primary_keyword',
'content_secondary_keywords',
'content_taxonomies',
'content_attributes',
'assigned_post_id',
'post_url',
'created_at',
'updated_at',
'site_id',
'sector_id',
'account_id',
]
read_only_fields = ['id', 'created_at', 'updated_at', 'account_id']
def get_content_taxonomies(self, obj):
"""Fetch related taxonomies."""
return ContentTaxonomyRelationSerializer(
obj.content.taxonomies.all(), many=True
).data
def get_content_attributes(self, obj):
"""Fetch related attributes."""
return ContentAttributeSerializer(
obj.content.attributes.all(), many=True
).data

View File

@@ -0,0 +1,48 @@
from django.db import migrations
def migrate_legacy_fields(apps, schema_editor):
Content = apps.get_model('igny8_core', 'Content')
Task = apps.get_model('igny8_core', 'Task')
# Migrate legacy fields in Content model
for content in Content.objects.all():
if content.categories:
# Convert JSON categories to ContentTaxonomy
categories = content.categories
for category in categories:
taxonomy, created = ContentTaxonomy.objects.get_or_create(
name=category['name'],
slug=category['slug'],
taxonomy_type='category'
)
content.taxonomies.add(taxonomy)
if content.tags:
# Convert JSON tags to ContentTaxonomy
tags = content.tags
for tag in tags:
taxonomy, created = ContentTaxonomy.objects.get_or_create(
name=tag['name'],
slug=tag['slug'],
taxonomy_type='tag'
)
content.taxonomies.add(taxonomy)
content.save()
# Migrate legacy fields in Task model
for task in Task.objects.all():
task.entity_type = task.content.entity_type
task.cluster_role = task.content.cluster_role
task.cluster_id = task.content.cluster_id
task.save()
class Migration(migrations.Migration):
dependencies = [
('igny8_core', '0005_phase3_mark_deprecated_fields'),
]
operations = [
migrations.RunPython(migrate_legacy_fields),
]

View File

@@ -23,7 +23,9 @@ import {
import {
fetchTasks,
fetchContent,
fetchContentImages
fetchContentImages,
fetchTaxonomies,
fetchAttributes
} from "../../services/api";
import { useSiteStore } from "../../store/siteStore";
import { useSectorStore } from "../../store/sectorStore";
@@ -66,6 +68,8 @@ interface WriterStats {
avgGenerationTime: number;
publishRate: number;
};
taxonomies: number;
attributes: number;
}
export default function WriterDashboard() {
@@ -81,10 +85,12 @@ export default function WriterDashboard() {
try {
setLoading(true);
const [tasksRes, contentRes, imagesRes] = await Promise.all([
const [tasksRes, contentRes, imagesRes, taxonomiesRes, attributesRes] = await Promise.all([
fetchTasks({ page_size: 1000, sector_id: activeSector?.id }),
fetchContent({ page_size: 1000, sector_id: activeSector?.id }),
fetchContentImages({ sector_id: activeSector?.id })
fetchContentImages({ sector_id: activeSector?.id }),
fetchTaxonomies({ sector_id: activeSector?.id }),
fetchAttributes({ sector_id: activeSector?.id }),
]);
const tasks = tasksRes.results || [];
@@ -143,6 +149,12 @@ export default function WriterDashboard() {
const contentThisMonth = Math.floor(content.length * 0.7);
const publishRate = content.length > 0 ? Math.round((published / content.length) * 100) : 0;
const taxonomies = taxonomiesRes.results || [];
const attributes = attributesRes.results || [];
const taxonomyCount = taxonomies.length;
const attributeCount = attributes.length;
setStats({
tasks: {
total: tasks.length,
@@ -180,7 +192,9 @@ export default function WriterDashboard() {
contentThisMonth,
avgGenerationTime: 0,
publishRate
}
},
taxonomies: taxonomyCount,
attributes: attributeCount,
});
setLastUpdated(new Date());
@@ -239,6 +253,24 @@ export default function WriterDashboard() {
count: stats?.content.published || 0,
metric: "View all published",
},
{
title: "Taxonomies",
description: "Manage content taxonomies",
icon: BoltIcon,
color: "from-[var(--color-info)] to-[var(--color-info-dark)]",
path: "/writer/taxonomies",
count: stats?.taxonomies || 0,
metric: `${stats?.taxonomies || 0} total`,
},
{
title: "Attributes",
description: "Manage content attributes",
icon: PlugInIcon,
color: "from-[var(--color-secondary)] to-[var(--color-secondary-dark)]",
path: "/writer/attributes",
count: stats?.attributes || 0,
metric: `${stats?.attributes || 0} total`,
},
];
const recentActivity = [