feat: add generation_mode to RecentArticle and related components
- Updated RecentArticle interface to include generation_mode. - Modified workspace_service to map generation_mode from database. - Adjusted domain model for RecentArticle to accommodate generation_mode. - Enhanced SQL queries to retrieve generation_mode from generation_tasks. - Created ArticleActionGroup component for article action buttons. - Implemented ArticleGenerateStatus component to display generation status. - Developed ArticlePublishStatus component to show publish status and related platforms. - Introduced ArticleSourceMeta component to display article source information. - Added utility functions for article actions and clipboard content generation.
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
AppstoreOutlined,
|
||||
CalendarOutlined,
|
||||
ClockCircleOutlined,
|
||||
EditOutlined,
|
||||
ThunderboltOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
import { computed, type Component } from "vue";
|
||||
|
||||
import { formatDateTime, getSourceTypeLabel } from "@/lib/display";
|
||||
|
||||
const props = defineProps<{
|
||||
sourceType?: string | null;
|
||||
generationMode?: string | null;
|
||||
createdAt?: string | null;
|
||||
}>();
|
||||
|
||||
const sourceLabel = computed(() =>
|
||||
getSourceTypeLabel(props.sourceType, props.generationMode),
|
||||
);
|
||||
|
||||
const createdAtLabel = computed(() => formatDateTime(props.createdAt));
|
||||
|
||||
const sourceVariant = computed<
|
||||
"template" | "custom" | "instant" | "schedule" | "free-create" | "default"
|
||||
>(() => {
|
||||
if (props.sourceType === "template") {
|
||||
return "template";
|
||||
}
|
||||
if (props.sourceType === "free_create") {
|
||||
return "free-create";
|
||||
}
|
||||
if (props.sourceType === "custom_generation") {
|
||||
if (props.generationMode === "schedule") {
|
||||
return "schedule";
|
||||
}
|
||||
if (props.generationMode === "instant") {
|
||||
return "instant";
|
||||
}
|
||||
return "custom";
|
||||
}
|
||||
return "default";
|
||||
});
|
||||
|
||||
const badgeIcon = computed<Component>(() => {
|
||||
switch (sourceVariant.value) {
|
||||
case "template":
|
||||
return AppstoreOutlined;
|
||||
case "instant":
|
||||
return ThunderboltOutlined;
|
||||
case "schedule":
|
||||
return CalendarOutlined;
|
||||
case "custom":
|
||||
return ThunderboltOutlined;
|
||||
case "free-create":
|
||||
return EditOutlined;
|
||||
default:
|
||||
return AppstoreOutlined;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="article-source-meta">
|
||||
<span
|
||||
class="article-source-meta__badge"
|
||||
:class="`article-source-meta__badge--${sourceVariant}`"
|
||||
>
|
||||
<component :is="badgeIcon" />
|
||||
<span>{{ sourceLabel }}</span>
|
||||
</span>
|
||||
<span class="article-source-meta__time">
|
||||
<ClockCircleOutlined />
|
||||
<span>{{ createdAtLabel }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.article-source-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 10px 14px;
|
||||
}
|
||||
|
||||
.article-source-meta__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--template {
|
||||
border: 1px solid #d9e5ff;
|
||||
background: linear-gradient(180deg, #fbfcff 0%, #f3f7ff 100%);
|
||||
color: #225fd1;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--custom {
|
||||
border: 1px solid #d9ccff;
|
||||
background: linear-gradient(180deg, #f7f4ff 0%, #efe9ff 100%);
|
||||
color: #6941c6;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--instant {
|
||||
border: 1px solid #f3c796;
|
||||
background: linear-gradient(180deg, #fff5e9 0%, #ffe9d2 100%);
|
||||
color: #b54708;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--schedule {
|
||||
border: 1px solid #a7ddd3;
|
||||
background: linear-gradient(180deg, #eefaf7 0%, #def3ee 100%);
|
||||
color: #0b6b61;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--free-create {
|
||||
border: 1px solid #d4ead8;
|
||||
background: linear-gradient(180deg, #f7fcf8 0%, #eef8f1 100%);
|
||||
color: #18794e;
|
||||
}
|
||||
|
||||
.article-source-meta__badge--default {
|
||||
border: 1px solid #dde3ea;
|
||||
background: linear-gradient(180deg, #fbfcfd 0%, #f4f6f8 100%);
|
||||
color: #44546a;
|
||||
}
|
||||
|
||||
.article-source-meta__time {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: #667085;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.article-source-meta :deep(.anticon) {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user