add pagination approval flows
This commit is contained in:
parent
239f052a9a
commit
3717b0b53c
@ -245,7 +245,8 @@ type ApprovalFlowStepResponse struct {
|
||||
|
||||
type ListApprovalFlowsRequest struct {
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
Page int `json:"page"`
|
||||
Search *string `json:"search"`
|
||||
DepartmentID *uuid.UUID `json:"department_id,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
}
|
||||
|
||||
@ -159,42 +159,47 @@ func (h *AdminApprovalFlowHandler) DeleteApprovalFlow(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *AdminApprovalFlowHandler) ListApprovalFlows(c *gin.Context) {
|
||||
// Parse query params
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
offset := (page - 1) * limit
|
||||
|
||||
departmentIDStr := c.Query("department_id")
|
||||
isActiveStr := c.Query("is_active")
|
||||
|
||||
// Parse department_id
|
||||
var departmentID *uuid.UUID
|
||||
var isActive *bool
|
||||
|
||||
if departmentIDStr != "" {
|
||||
if departmentIDStr := c.Query("department_id"); departmentIDStr != "" {
|
||||
if id, err := uuid.Parse(departmentIDStr); err == nil {
|
||||
departmentID = &id
|
||||
}
|
||||
}
|
||||
|
||||
if isActiveStr != "" {
|
||||
if isActiveStr == "true" {
|
||||
active := true
|
||||
isActive = &active
|
||||
} else if isActiveStr == "false" {
|
||||
active := false
|
||||
// Parse is_active
|
||||
var isActive *bool
|
||||
if isActiveStr := c.Query("is_active"); isActiveStr != "" {
|
||||
if active, err := strconv.ParseBool(isActiveStr); err == nil {
|
||||
isActive = &active
|
||||
}
|
||||
}
|
||||
|
||||
// Parse search
|
||||
var search *string
|
||||
if searchStr := c.Query("search"); searchStr != "" {
|
||||
search = &searchStr
|
||||
}
|
||||
|
||||
// Build request - pass PAGE, bukan OFFSET
|
||||
req := &contract.ListApprovalFlowsRequest{
|
||||
Page: page, // ✅ Pass page number
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
DepartmentID: departmentID,
|
||||
IsActive: isActive,
|
||||
Search: search, // tambahkan ini juga
|
||||
}
|
||||
|
||||
resp, err := h.svc.ListApprovalFlows(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: http.StatusInternalServerError})
|
||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{
|
||||
Error: err.Error(),
|
||||
Code: http.StatusInternalServerError,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@ -210,7 +215,7 @@ func (h *AdminApprovalFlowHandler) ListApprovalFlowsByDepartment(c *gin.Context)
|
||||
|
||||
req := &contract.ListApprovalFlowsRequest{
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Page: offset,
|
||||
DepartmentID: &appCtx.DepartmentID,
|
||||
}
|
||||
|
||||
|
||||
@ -368,7 +368,7 @@ func (p *NotificationProcessorImpl) SendOutgoingLetterNotification(ctx context.C
|
||||
}
|
||||
|
||||
// Build notification URL for outgoing letters
|
||||
url := fmt.Sprintf("/en/apps/surat-menyurat/keluar-detail/%s", letterID.String())
|
||||
url := fmt.Sprintf("/en/apps/surat-keluar-detail/%s", letterID.String())
|
||||
|
||||
// Use workflow ID from config (defaults to "notification-dashbpard")
|
||||
workflowID := p.workflowID
|
||||
|
||||
@ -66,37 +66,64 @@ func (r *ApprovalFlowRepository) Delete(ctx context.Context, id uuid.UUID) error
|
||||
|
||||
type ListApprovalFlowsFilter struct {
|
||||
DepartmentID *uuid.UUID
|
||||
Search *string
|
||||
IsActive *bool
|
||||
}
|
||||
|
||||
func (r *ApprovalFlowRepository) List(ctx context.Context, filter ListApprovalFlowsFilter, limit, offset int) ([]entities.ApprovalFlow, int64, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
query := db.WithContext(ctx).Model(&entities.ApprovalFlow{})
|
||||
var list []entities.ApprovalFlow
|
||||
var total int64
|
||||
|
||||
// Build base query for counting
|
||||
countQuery := r.db.WithContext(ctx).Model(&entities.ApprovalFlow{})
|
||||
|
||||
if filter.DepartmentID != nil {
|
||||
query = query.Where("department_id = ?", *filter.DepartmentID)
|
||||
}
|
||||
if filter.IsActive != nil {
|
||||
query = query.Where("is_active = ?", *filter.IsActive)
|
||||
countQuery = countQuery.Where("department_id = ?", *filter.DepartmentID)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
if filter.IsActive != nil {
|
||||
countQuery = countQuery.Where("is_active = ?", *filter.IsActive)
|
||||
}
|
||||
|
||||
if filter.Search != nil && *filter.Search != "" {
|
||||
like := "%" + *filter.Search + "%"
|
||||
countQuery = countQuery.Where("name ILIKE ? OR description ILIKE ?", like, like)
|
||||
}
|
||||
|
||||
// Get total count
|
||||
if err := countQuery.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var list []entities.ApprovalFlow
|
||||
if err := query.
|
||||
// Build query for fetching data - BUAT QUERY BARU DARI AWAL
|
||||
dataQuery := r.db.WithContext(ctx).Model(&entities.ApprovalFlow{})
|
||||
|
||||
if filter.DepartmentID != nil {
|
||||
dataQuery = dataQuery.Where("department_id = ?", *filter.DepartmentID)
|
||||
}
|
||||
|
||||
if filter.IsActive != nil {
|
||||
dataQuery = dataQuery.Where("is_active = ?", *filter.IsActive)
|
||||
}
|
||||
|
||||
if filter.Search != nil && *filter.Search != "" {
|
||||
like := "%" + *filter.Search + "%"
|
||||
dataQuery = dataQuery.Where("name ILIKE ? OR description ILIKE ?", like, like)
|
||||
}
|
||||
|
||||
// Fetch data with pagination and preloads
|
||||
if err := dataQuery.
|
||||
Order("created_at DESC").
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Preload("Department").
|
||||
Preload("Steps", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("step_order ASC, parallel_group ASC")
|
||||
}).
|
||||
Order("created_at DESC").
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&list).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
|
||||
@ -173,10 +173,26 @@ func (s *ApprovalFlowServiceImpl) DeleteApprovalFlow(ctx context.Context, id uui
|
||||
func (s *ApprovalFlowServiceImpl) ListApprovalFlows(ctx context.Context, req *contract.ListApprovalFlowsRequest) (*contract.ListApprovalFlowsResponse, error) {
|
||||
filter := repository.ListApprovalFlowsFilter{
|
||||
DepartmentID: req.DepartmentID,
|
||||
Search: req.Search,
|
||||
IsActive: req.IsActive,
|
||||
}
|
||||
|
||||
flows, total, err := s.flowRepo.List(ctx, filter, req.Limit, req.Offset)
|
||||
page := req.Page
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
limit := req.Limit
|
||||
if limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
if limit > 100 {
|
||||
limit = 100 // Max limit to prevent performance issues
|
||||
}
|
||||
|
||||
offset := (page - 1) * limit
|
||||
|
||||
flows, total, err := s.flowRepo.List(ctx, filter, limit, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user