Add org-scoped activity priority labels/colors and apply them across forms, boards, and routines.

Also fix activity leave-without-save confirm, kanban due-date labels with tone-colored peek chevron, and rename the types manager button.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-12 21:39:15 +03:30
co-authored by Cursor
parent a1ac677b3a
commit 7a55b84b81
20 changed files with 634 additions and 112 deletions
+65
View File
@@ -1874,6 +1874,71 @@ export interface DealActivitySummaryDto {
cue: Exclude<DealActivityCue, "none">;
}
export type ActivityPriority = "very_low" | "low" | "medium" | "high" | "very_high";
/** ترتیب نمایش ثابت (تعداد تغییر نمی‌کند) */
export const ACTIVITY_PRIORITY_KEYS: ActivityPriority[] = [
"very_high",
"high",
"medium",
"low",
"very_low",
];
export type ActivityPrioritySetting = {
key: ActivityPriority;
label: string;
/** رنگ متن/پرچم — #RRGGBB */
color: string;
};
export const DEFAULT_ACTIVITY_PRIORITY_SETTINGS: ActivityPrioritySetting[] = [
{ key: "very_high", label: "خیلی زیاد", color: "#dc2626" },
{ key: "high", label: "زیاد", color: "#ea580c" },
{ key: "medium", label: "متوسط", color: "#eab308" },
{ key: "low", label: "کم", color: "#16a34a" },
{ key: "very_low", label: "خیلی کم", color: "#94a3b8" },
];
const PRIORITY_KEY_SET = new Set<string>(ACTIVITY_PRIORITY_KEYS);
const HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
/** ادغام تنظیم ذخیره‌شده با پیش‌فرض‌ها؛ همیشه ۵ سطح کامل */
export function parseActivityPrioritySettings(raw: unknown): ActivityPrioritySetting[] {
const overrides = new Map<ActivityPriority, { label?: string; color?: string }>();
const bag =
raw && typeof raw === "object" && !Array.isArray(raw)
? (raw as Record<string, unknown>)
: Array.isArray(raw)
? Object.fromEntries(
raw
.filter((r): r is Record<string, unknown> => !!r && typeof r === "object")
.map((r) => [String(r.key ?? ""), r]),
)
: {};
for (const [key, val] of Object.entries(bag)) {
if (!PRIORITY_KEY_SET.has(key) || !val || typeof val !== "object" || Array.isArray(val)) continue;
const row = val as Record<string, unknown>;
const label = typeof row.label === "string" ? row.label.trim() : "";
const color = typeof row.color === "string" ? row.color.trim() : "";
overrides.set(key as ActivityPriority, {
...(label ? { label: label.slice(0, 40) } : {}),
...(HEX_COLOR.test(color) ? { color } : {}),
});
}
return DEFAULT_ACTIVITY_PRIORITY_SETTINGS.map((d) => {
const o = overrides.get(d.key);
return {
key: d.key,
label: o?.label || d.label,
color: o?.color || d.color,
};
});
}
export type UpdateActivityPrioritiesRequest = {
items: Array<{ key: ActivityPriority; label: string; color: string }>;
};
export type ActivityFilter = "today" | "overdue" | "upcoming" | "done" | "all";
export type ActivityStageColor = "green" | "orange" | "purple" | "blue" | "rose" | "slate";