feat: reorganize project task planning UI
This commit is contained in:
@@ -54,14 +54,16 @@ type InboxMessage struct {
|
||||
}
|
||||
|
||||
type WorkTask struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
Completed bool `json:"completed"`
|
||||
Owner string `json:"owner"`
|
||||
Due string `json:"due"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
Tag string `json:"tag"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
Completed bool `json:"completed"`
|
||||
Owner string `json:"owner"`
|
||||
Due string `json:"due"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
CompletedAt string `json:"completedAt"`
|
||||
Duration string `json:"duration"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
type AISessionItem struct {
|
||||
@@ -550,15 +552,24 @@ func (s *Service) workspaceTasks(projectID uint) ([]WorkTask, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
completed := task.Status == "done"
|
||||
completedAt := ""
|
||||
duration := ""
|
||||
if completed {
|
||||
completedAt = displayTime(task.UpdatedAt)
|
||||
duration = displayDuration(task.CreatedAt, task.UpdatedAt)
|
||||
}
|
||||
items = append(items, WorkTask{
|
||||
ID: fmt.Sprint(task.ID),
|
||||
Title: task.Title,
|
||||
Summary: task.Description,
|
||||
Completed: task.Status == "done",
|
||||
Owner: owner,
|
||||
Due: displayOptionalTime(task.DueAt),
|
||||
CreatedAt: displayTime(task.CreatedAt),
|
||||
Tag: tagNames[task.ID],
|
||||
ID: fmt.Sprint(task.ID),
|
||||
Title: task.Title,
|
||||
Summary: task.Description,
|
||||
Completed: completed,
|
||||
Owner: owner,
|
||||
Due: displayOptionalTime(task.DueAt),
|
||||
CreatedAt: displayTime(task.CreatedAt),
|
||||
CompletedAt: completedAt,
|
||||
Duration: duration,
|
||||
Tag: tagNames[task.ID],
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
@@ -740,6 +751,26 @@ func displayOptionalTime(value *time.Time) string {
|
||||
return displayTime(*value)
|
||||
}
|
||||
|
||||
func displayDuration(start time.Time, end time.Time) string {
|
||||
if start.IsZero() || end.IsZero() || end.Before(start) {
|
||||
return ""
|
||||
}
|
||||
duration := end.Sub(start)
|
||||
days := int(duration.Hours()) / 24
|
||||
if days > 0 {
|
||||
return fmt.Sprintf("%d 天", days)
|
||||
}
|
||||
hours := int(duration.Hours())
|
||||
if hours > 0 {
|
||||
return fmt.Sprintf("%d 小时", hours)
|
||||
}
|
||||
minutes := int(duration.Minutes())
|
||||
if minutes > 0 {
|
||||
return fmt.Sprintf("%d 分钟", minutes)
|
||||
}
|
||||
return "1 分钟内"
|
||||
}
|
||||
|
||||
func sourceDisplayName(source models.SenlinAgentSource) string {
|
||||
switch source.Kind {
|
||||
case "file":
|
||||
|
||||
Reference in New Issue
Block a user