feat: add project action modals and APIs
This commit is contained in:
@@ -99,6 +99,25 @@ type ProjectWorkspace struct {
|
||||
CronPlans []CronPlan `json:"cronPlans"`
|
||||
}
|
||||
|
||||
type CreateTaskInput struct {
|
||||
Title string
|
||||
Description string
|
||||
Status string
|
||||
DueAt *time.Time
|
||||
}
|
||||
|
||||
type CreateFileSourceInput struct {
|
||||
Title string
|
||||
FilePath string
|
||||
}
|
||||
|
||||
type CreateCronPlanInput struct {
|
||||
Title string
|
||||
Schedule string
|
||||
Enabled bool
|
||||
NextRunAt *time.Time
|
||||
}
|
||||
|
||||
func NewService() *Service {
|
||||
return &Service{}
|
||||
}
|
||||
@@ -118,6 +137,75 @@ func (s *Service) ListProjects(ownerID uint) ([]models.SenlinAgentProject, error
|
||||
return projects, err
|
||||
}
|
||||
|
||||
func (s *Service) CreateTask(ownerID uint, projectID uint, input CreateTaskInput) (*models.SenlinAgentTask, error) {
|
||||
if err := ensureProjectOwner(ownerID, projectID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
title := strings.TrimSpace(input.Title)
|
||||
if title == "" {
|
||||
return nil, errors.New("task title is required")
|
||||
}
|
||||
status := strings.TrimSpace(input.Status)
|
||||
if status == "" {
|
||||
status = "open"
|
||||
}
|
||||
task := &models.SenlinAgentTask{
|
||||
ProjectID: projectID,
|
||||
CreatedBy: ownerID,
|
||||
Title: title,
|
||||
Description: strings.TrimSpace(input.Description),
|
||||
Status: status,
|
||||
DueAt: input.DueAt,
|
||||
}
|
||||
return task, models.DBService.Create(task).Error
|
||||
}
|
||||
|
||||
func (s *Service) CreateFileSource(ownerID uint, projectID uint, input CreateFileSourceInput) (*models.SenlinAgentSource, error) {
|
||||
if err := ensureProjectOwner(ownerID, projectID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
title := strings.TrimSpace(input.Title)
|
||||
if title == "" {
|
||||
return nil, errors.New("source title is required")
|
||||
}
|
||||
filePath := strings.TrimSpace(input.FilePath)
|
||||
if filePath == "" {
|
||||
return nil, errors.New("source file path is required")
|
||||
}
|
||||
source := &models.SenlinAgentSource{
|
||||
ProjectID: projectID,
|
||||
CreatedBy: ownerID,
|
||||
Kind: "file",
|
||||
Title: title,
|
||||
FilePath: filePath,
|
||||
}
|
||||
return source, models.DBService.Create(source).Error
|
||||
}
|
||||
|
||||
func (s *Service) CreateCronPlan(ownerID uint, projectID uint, input CreateCronPlanInput) (*models.SenlinAgentCronPlan, error) {
|
||||
if err := ensureProjectOwner(ownerID, projectID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
title := strings.TrimSpace(input.Title)
|
||||
if title == "" {
|
||||
return nil, errors.New("cron plan title is required")
|
||||
}
|
||||
schedule := strings.TrimSpace(input.Schedule)
|
||||
if schedule == "" {
|
||||
return nil, errors.New("cron schedule is required")
|
||||
}
|
||||
plan := &models.SenlinAgentCronPlan{
|
||||
ProjectID: projectID,
|
||||
CreatedBy: ownerID,
|
||||
Title: title,
|
||||
Schedule: schedule,
|
||||
Enabled: input.Enabled,
|
||||
NextRunAt: input.NextRunAt,
|
||||
LastResult: "Not run yet",
|
||||
}
|
||||
return plan, models.DBService.Create(plan).Error
|
||||
}
|
||||
|
||||
func (s *Service) CreateTag(projectID uint, name string) (*models.SenlinAgentTag, error) {
|
||||
name = strings.TrimSpace(name)
|
||||
if name == "" {
|
||||
@@ -134,8 +222,7 @@ func (s *Service) ListTags(projectID uint) ([]models.SenlinAgentTag, error) {
|
||||
}
|
||||
|
||||
func (s *Service) Dashboard(ownerID uint, projectID uint) (Dashboard, error) {
|
||||
var project models.SenlinAgentProject
|
||||
if err := models.DBService.Where("id = ? AND owner_id = ?", projectID, ownerID).First(&project).Error; err != nil {
|
||||
if err := ensureProjectOwner(ownerID, projectID); err != nil {
|
||||
return Dashboard{}, err
|
||||
}
|
||||
dashboard := Dashboard{ProjectID: projectID}
|
||||
@@ -212,6 +299,17 @@ func (s *Service) Workspace(ownerID uint, projectID uint) (ProjectWorkspace, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ensureProjectOwner(ownerID uint, projectID uint) error {
|
||||
var count int64
|
||||
if err := models.DBService.Model(&models.SenlinAgentProject{}).Where("id = ? AND owner_id = ?", projectID, ownerID).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
return errors.New("project not found")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type workspaceCounts struct {
|
||||
inbox int64
|
||||
tasks int64
|
||||
|
||||
Reference in New Issue
Block a user