feat(activities): split customer column, wider search, custom activity types with type-specific fields
- Table: separate assignee and customer columns; search by assignee and activity type - ActivityTypeDef model with per-type field definitions (text, select, checklist, participants, ...) - Default types incl. meeting subject/participants and task checklist; admins manage types - Participants see activities in their lists and get notified Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1199,6 +1199,152 @@ export interface ActivityStageCountsDto {
|
||||
total: number;
|
||||
}
|
||||
|
||||
/** برچسب نوع پایه (برای گزارشها و فعالیتهای بدون نوع سفارشی) */
|
||||
export const ACTIVITY_TYPE_LABELS: Record<ActivityType, string> = {
|
||||
call: "تماس",
|
||||
meeting: "جلسه",
|
||||
task: "وظیفه",
|
||||
note: "پیام",
|
||||
};
|
||||
|
||||
export type ActivityFieldType =
|
||||
| "text"
|
||||
| "textarea"
|
||||
| "number"
|
||||
| "date"
|
||||
| "url"
|
||||
| "select"
|
||||
| "multiselect"
|
||||
| "checkbox"
|
||||
| "checklist"
|
||||
| "participants";
|
||||
|
||||
export const ACTIVITY_FIELD_TYPES: ActivityFieldType[] = [
|
||||
"text",
|
||||
"textarea",
|
||||
"number",
|
||||
"date",
|
||||
"url",
|
||||
"select",
|
||||
"multiselect",
|
||||
"checkbox",
|
||||
"checklist",
|
||||
"participants",
|
||||
];
|
||||
|
||||
export const ACTIVITY_FIELD_TYPE_LABELS: Record<ActivityFieldType, string> = {
|
||||
text: "متن کوتاه",
|
||||
textarea: "متن بلند",
|
||||
number: "عدد",
|
||||
date: "تاریخ",
|
||||
url: "لینک",
|
||||
select: "انتخاب از لیست",
|
||||
multiselect: "چندانتخابی",
|
||||
checkbox: "بله / خیر",
|
||||
checklist: "چکلیست (لیست کارها)",
|
||||
participants: "شرکتکنندگان",
|
||||
};
|
||||
|
||||
/** فیلدهایی که گزینه لازم دارند */
|
||||
export const ACTIVITY_FIELD_TYPES_WITH_OPTIONS: ActivityFieldType[] = ["select", "multiselect"];
|
||||
|
||||
export interface ActivityFieldDef {
|
||||
/** کلید پایدار (a-z، 0-9، _) — با تغییر برچسب عوض نمیشود */
|
||||
key: string;
|
||||
label: string;
|
||||
type: ActivityFieldType;
|
||||
options?: string[];
|
||||
required?: boolean;
|
||||
placeholder?: string | null;
|
||||
}
|
||||
|
||||
export interface ActivityChecklistItem {
|
||||
id: string;
|
||||
text: string;
|
||||
done: boolean;
|
||||
}
|
||||
|
||||
export interface ActivityParticipantsValue {
|
||||
/** کاربران سازمان — فعالیت در لیست آنها هم دیده میشود */
|
||||
userIds: string[];
|
||||
/** اشخاص (مشتریان) */
|
||||
people: Array<{ id: string; name: string }>;
|
||||
/** مهمانان آزاد (نام) */
|
||||
guests: string[];
|
||||
}
|
||||
|
||||
export type ActivityFieldValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| string[]
|
||||
| ActivityChecklistItem[]
|
||||
| ActivityParticipantsValue
|
||||
| null;
|
||||
|
||||
export type ActivityFieldValues = Record<string, ActivityFieldValue>;
|
||||
|
||||
export const ACTIVITY_TYPE_ICONS = [
|
||||
"phone",
|
||||
"users",
|
||||
"check",
|
||||
"chat",
|
||||
"mail",
|
||||
"building",
|
||||
"calendar",
|
||||
"star",
|
||||
"flag",
|
||||
"briefcase",
|
||||
"document",
|
||||
"target",
|
||||
"truck",
|
||||
"send",
|
||||
"megaphone",
|
||||
"pin",
|
||||
"bell",
|
||||
"sparkle",
|
||||
] as const;
|
||||
|
||||
export type ActivityTypeIcon = (typeof ACTIVITY_TYPE_ICONS)[number];
|
||||
|
||||
export interface ActivityTypeSummaryDto {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: ActivityTypeIcon;
|
||||
color: ActivityStageColor;
|
||||
}
|
||||
|
||||
export interface ActivityTypeDefDto extends ActivityTypeSummaryDto {
|
||||
/** نوع پایه — مبنای گزارشها و سازگاری */
|
||||
baseType: ActivityType;
|
||||
fields: ActivityFieldDef[];
|
||||
position: number;
|
||||
isActive: boolean;
|
||||
/** چهار نوع اصلی — حذفشدنی نیستند */
|
||||
isSystem: boolean;
|
||||
}
|
||||
|
||||
export interface CreateActivityTypeRequest {
|
||||
name: string;
|
||||
baseType?: ActivityType;
|
||||
icon?: ActivityTypeIcon;
|
||||
color?: ActivityStageColor;
|
||||
fields?: ActivityFieldDef[];
|
||||
}
|
||||
|
||||
export interface UpdateActivityTypeRequest {
|
||||
name?: string;
|
||||
baseType?: ActivityType;
|
||||
icon?: ActivityTypeIcon;
|
||||
color?: ActivityStageColor;
|
||||
fields?: ActivityFieldDef[];
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export interface ReorderActivityTypesRequest {
|
||||
typeIds: string[];
|
||||
}
|
||||
|
||||
export type CustomFieldEntity = "person" | "company" | "deal";
|
||||
export type CustomFieldType = "text" | "number" | "date" | "boolean" | "select";
|
||||
|
||||
@@ -1267,6 +1413,14 @@ export interface ActivityDto {
|
||||
createdBy: UserSummaryDto | null;
|
||||
/** مرحلهٔ مؤثر (ستون کانبان) */
|
||||
stageId?: string | null;
|
||||
/** نوع مؤثر (سفارشی یا نوع اصلیِ همان type) */
|
||||
typeDef?: ActivityTypeSummaryDto | null;
|
||||
/** مقادیر فیلدهای اختصاصی نوع */
|
||||
fields?: ActivityFieldValues;
|
||||
/** کاربران شرکتکننده (از فیلدهای شرکتکنندگان) */
|
||||
participantIds?: string[];
|
||||
/** نام کاربران شرکتکننده — فقط در جزئیات فعالیت */
|
||||
participantUsers?: UserSummaryDto[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
@@ -1276,6 +1430,9 @@ export interface CreateActivityRequest {
|
||||
/** مرحلهٔ اولیه؛ وضعیت فعالیت از نوع مرحله گرفته میشود */
|
||||
stageId?: string | null;
|
||||
type?: ActivityType;
|
||||
/** نوع سفارشی؛ type از نوع پایهٔ آن گرفته میشود */
|
||||
typeDefId?: string | null;
|
||||
fields?: ActivityFieldValues;
|
||||
priority?: ActivityPriority;
|
||||
description?: string;
|
||||
dueAt?: string | null;
|
||||
@@ -1296,6 +1453,8 @@ export interface CreateActivityRequest {
|
||||
export interface UpdateActivityRequest {
|
||||
title?: string;
|
||||
type?: ActivityType;
|
||||
typeDefId?: string | null;
|
||||
fields?: ActivityFieldValues;
|
||||
status?: ActivityStatus;
|
||||
priority?: ActivityPriority;
|
||||
description?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user