feat: add tenant and user management with migrations, handlers, and tests
- Implemented tenant and user management features including: - Tenant creation and management with associated migrations. - User creation and management with associated migrations. - Tenant membership management with associated migrations. - Platform user roles management with associated migrations. - Quota management with associated migrations. - Article and template management with associated migrations. - Added HTTP handlers for templates and workspaces. - Created tests for protected and public routes. - Introduced a script to check tenant scope in SQL queries. - Documented task plan for backend completion and frontend foundation.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { i18n } from "@/i18n";
|
||||
|
||||
const generateStatusMap: Record<string, { label: string; color: string }> = {
|
||||
draft: { label: "status.generate.draft", color: "default" },
|
||||
generating: { label: "status.generate.generating", color: "processing" },
|
||||
running: { label: "status.generate.running", color: "processing" },
|
||||
completed: { label: "status.generate.completed", color: "success" },
|
||||
failed: { label: "status.generate.failed", color: "error" },
|
||||
};
|
||||
|
||||
const publishStatusMap: Record<string, { label: string; color: string }> = {
|
||||
unpublished: { label: "status.publish.unpublished", color: "default" },
|
||||
publishing: { label: "status.publish.publishing", color: "processing" },
|
||||
published: { label: "status.publish.published", color: "success" },
|
||||
publish_success: { label: "status.publish.publish_success", color: "success" },
|
||||
publish_failed: { label: "status.publish.publish_failed", color: "error" },
|
||||
pending_review: { label: "status.publish.pending_review", color: "warning" },
|
||||
};
|
||||
|
||||
export function formatDateTime(value?: string | null, pattern = "YYYY-MM-DD HH:mm"): string {
|
||||
if (!value) {
|
||||
return "--";
|
||||
}
|
||||
const parsed = dayjs(value);
|
||||
return parsed.isValid() ? parsed.format(pattern) : value;
|
||||
}
|
||||
|
||||
export function getGenerateStatusMeta(status?: string | null): { label: string; color: string } {
|
||||
if (!status) {
|
||||
return { label: "--", color: "default" };
|
||||
}
|
||||
const meta = generateStatusMap[status];
|
||||
return meta ? { label: i18n.global.t(meta.label), color: meta.color } : { label: status, color: "default" };
|
||||
}
|
||||
|
||||
export function getPublishStatusMeta(status?: string | null): { label: string; color: string } {
|
||||
if (!status) {
|
||||
return { label: "--", color: "default" };
|
||||
}
|
||||
const meta = publishStatusMap[status];
|
||||
return meta ? { label: i18n.global.t(meta.label), color: meta.color } : { label: status, color: "default" };
|
||||
}
|
||||
|
||||
export function getSourceTypeLabel(sourceType?: string | null): string {
|
||||
if (!sourceType) {
|
||||
return "--";
|
||||
}
|
||||
if (sourceType === "template") {
|
||||
return i18n.global.t("status.sourceType.template");
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
export function getTemplateMeta(templateKey: string): {
|
||||
eyebrow: string;
|
||||
helper: string;
|
||||
accent: string;
|
||||
action: string;
|
||||
} {
|
||||
const key = [
|
||||
"top_x_article",
|
||||
"product_review",
|
||||
"research_report",
|
||||
"brand_search_expansion",
|
||||
].includes(templateKey)
|
||||
? templateKey
|
||||
: "default";
|
||||
|
||||
return {
|
||||
eyebrow: i18n.global.t(`templateMeta.${key}.eyebrow`),
|
||||
helper: i18n.global.t(`templateMeta.${key}.helper`),
|
||||
accent: i18n.global.t(`templateMeta.${key}.accent`),
|
||||
action: i18n.global.t(`templateMeta.${key}.action`),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user