feat(activities): editable stages with tab and kanban views

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-07 11:18:53 +03:30
co-authored by Cursor
parent b4ffef9b6f
commit aa2f39256a
15 changed files with 1860 additions and 88 deletions
+54
View File
@@ -66,6 +66,11 @@ export class ListActivitiesQueryDto {
@IsString()
assigneeId?: string;
/** شناسهٔ مرحله یا 'all' — حالت تب/کانبان مراحل */
@IsOptional()
@IsString()
stageId?: string;
@IsOptional()
@IsString()
personId?: string;
@@ -102,12 +107,61 @@ export class ListActivitiesQueryDto {
limit?: number = 50;
}
const STAGE_COLORS = ['green', 'orange', 'purple', 'blue', 'rose', 'slate'] as const;
export class CreateActivityStageDto {
@IsString()
@MinLength(1)
@MaxLength(80)
name!: string;
@IsOptional()
@IsIn(STAGE_COLORS)
color?: (typeof STAGE_COLORS)[number];
@IsOptional()
@IsIn(ACTIVITY_STATUSES)
kind?: (typeof ACTIVITY_STATUSES)[number];
}
export class UpdateActivityStageDto {
@IsOptional()
@IsString()
@MinLength(1)
@MaxLength(80)
name?: string;
@IsOptional()
@IsIn(STAGE_COLORS)
color?: (typeof STAGE_COLORS)[number];
@IsOptional()
@IsIn(ACTIVITY_STATUSES)
kind?: (typeof ACTIVITY_STATUSES)[number];
}
export class ReorderActivityStagesDto {
@IsArray()
@IsString({ each: true })
stageIds!: string[];
}
export class MoveActivityStageDto {
@IsString()
stageId!: string;
}
export class CreateActivityDto {
@IsString()
@MinLength(2)
@MaxLength(200)
title!: string;
@IsOptional()
@ValidateIf((_, v) => v !== '' && v != null)
@IsString()
stageId?: string | null;
@IsOptional()
@IsIn(ACTIVITY_TYPES)
type?: (typeof ACTIVITY_TYPES)[number];