Issue Resolution Requirements Feature

Overview

The Issue Resolution Requirements feature allows organizations to enforce comment and attachment requirements when resolving issues. This ensures proper documentation and accountability when issues are marked as resolved, helping maintain audit trails and quality standards.

Business Purpose

  • Accountability: Ensures users provide clear explanations when resolving issues
  • Documentation: Maintains a comprehensive record of how issues were resolved
  • Quality Control: Requires evidence (attachments) when configured, ensuring proper verification
  • Compliance: Helps organizations meet documentation and audit trail requirements

Settings Configuration

Location

The settings are configured in the Issue Tracker Settings page under the General Settings section:

Path: Settings → Issue Tracker Settings → General Settings → “Resolve issue with comments”

Implementation Files:

Configuration Options

The feature provides three distinct configurations controlled by two boolean flags:

ConfigurationrequireCommentOnResolverequireAttachmentOnResolveBehavior
No RequirementsfalsefalseUsers can resolve issues without any comments or attachments (default behavior)
Comment Required (Attachments Optional)truefalseUsers must provide a comment when resolving. Attachments are optional but can be added.
Comment + Attachment RequiredfalsetrueUsers must provide both a comment AND at least one attachment when resolving.

Settings Storage

The settings are stored in the organization’s Issue Tracker Settings document with the following properties:

interface IssueTrackerSettings {
  // ... other settings
  requireCommentOnResolve?: boolean
  requireAttachmentOnResolve?: boolean
}

Default Values: Both flags default to false (no requirements)

How Settings are Applied

Settings are accessed throughout the application using the useIssueResolutionRequirements hook, which:

  1. Reads settings from Redux store
  2. Computes derived requirements:
    • showCommentModal: Whether to show the resolution modal (true if either flag is enabled)
    • requireComment: Whether comment is required (true if requireCommentOnResolve is true)
    • requireAttachment: Whether attachment is required (true if requireAttachmentOnResolve is true)

Implementation: issueResolutionRequirements.ts


Technical Implementation

Core Components

1. Settings Hook: useIssueResolutionRequirements

Location: utils/issueResolutionRequirements.ts

export interface IssueResolutionRequirements {
  showCommentModal: boolean // Show modal when resolving
  requireComment: boolean // Comment is required
  requireAttachment: boolean // Attachment is required
}

Logic:

  • Returns showCommentModal: true when either requireCommentOnResolve OR requireAttachmentOnResolve is enabled
  • Centralizes settings access across all components

2. Resolution Modal: ResolvedIssueModal

Location: IssueDetail/ResolvedIssueModal.tsx

Key Features:

  • Comment input with character validation (10-250 characters)
  • File attachment support (up to 10 files)
  • Dynamic UI based on requireAttachment prop
  • Real-time validation and error messaging

Validation Rules:

  • Comment:
    • Minimum: 10 characters
    • Maximum: 250 characters
    • Required when modal is shown
  • Attachments:
    • Required: At least 1 file when requireAttachment is true
    • Optional: Any number of files (0-10) when requireAttachment is false
    • Supported formats: Images (.gif, .jpg, .jpeg, .png), Documents (.pdf, .doc, .docx, .xls, .xlsx, .csv), Videos (.mp4, .mov, .avi)
    • Max file size: 7 MB per file

3. Status Update Controllers

Primary Controller: IssueStatusController

Handles status transitions and determines when to show resolution modal based on:

  • New status being set to “resolved”
  • Settings from useIssueResolutionRequirements

Feature Application Points

The resolution requirements are enforced across 6 different locations in the application:

1. Table View

Component: TableItemStatusSelect.tsx

Location: Issues page → Table view → Status dropdown

Flow:

  1. User selects “Resolved” from status dropdown
  2. System checks resolutionRequirements.showCommentModal (line 131)
  3. If true, shows ResolvedIssueModal with requireAttachment prop (line 236)
  4. User enters comment and attachments (if required)
  5. Comment is submitted first, then status is updated

2. Kanban View

Component: KanbanStatusDialog.tsx

Location: Issues page → Kanban view → Drag issue to “Resolved” column or use status dropdown

Flow:

  1. User attempts to change status to “Resolved”
  2. System checks resolutionRequirements.showCommentModal (line 41)
  3. If true, shows ResolvedIssueModal
  4. Validates comment and attachments before allowing status change

3. List Details View (Issue Listing Header)

Component: StatusSelect.tsx

Location: Issues page → List view with details panel → Status button in header

Implementation:

  • Uses same StatusSelect component as details view
  • Shows resolution modal when changing to “Resolved” status (line 131)
  • Enforces comment/attachment requirements (line 236)

4. Issue Details View

Component: StatusSelect.tsx (shared)

Location: Issue Details page (dedicated page) → Status button in header

Flow: Same as List Details View

5. Legacy Issue Detail Form

Component: IssueDetailForm.tsx

Location: Legacy issue detail view → Status dropdown

Flow:

  1. User selects “Resolved” from status dropdown
  2. handleChangeStatus checks resolutionRequirements.showCommentModal (line 171)
  3. If true, sets isResolvedModalOpen to show modal (line 172)
  4. Modal validates and submits comment with attachments
  5. Status is updated only after successful comment submission (line 210)

6. Bulk Edit

Components:

Location: Issues page → Select multiple issues → Bulk Actions → Edit

Flow:

  1. User selects multiple issues and chooses “Resolved” status in bulk edit modal
  2. System checks resolutionRequirements.showCommentModal (line 152)
  3. If true, stores form values and shows BulkResolveModal (line 156)
  4. User enters comment and attachments (applies to all selected issues)
  5. Comment is submitted to ALL selected issues via bulkSubmitIssueMesage (line 66)
  6. Status is updated for all issues only after successful comment submission

Special Handling:

  • Single comment/attachment set is added to ALL selected issues
  • Customer Feedback issues are filtered out when using additional statuses (blocked, in-review)
  • Uses ResolvedIssueModal component, ensuring consistent validation

User Flow & Validation

Resolution Flow (When Requirements are Enabled)

1. User changes issue status to "Resolved"
   ↓
2. System checks resolution requirements
   ↓
3. If requirements enabled → Show Resolution Modal
   ├── User enters comment (10-250 chars)
   └── User attaches files (if required: minimum 1, optional: 0-10)
   ↓
4. User clicks "Save"
   ├── Validate comment length
   ├── Validate attachment count (if required)
   └── Validate all attachments uploaded successfully
   ↓
5. Submit comment with attachments
   ├── If successful → Update issue status to "Resolved"
   └── If failed → Keep modal open, show error

Validation Details

Comment Validation

Rules:

  • Minimum: 10 characters
  • Maximum: 250 characters
  • Required: Always when modal is shown

Error Messages:

  • Less than 10 chars: “Character should be more than 10”
  • More than 250 chars: “Character should be less than 250”

Implementation: Yup schema validation in ResolvedIssueModal.tsx

Attachment Validation

Rules (when requireAttachment is true):

  • Minimum: 1 attachment
  • Maximum: 10 attachments
  • File Size: 7 MB per file
  • Formats: Images, Documents, Videos (see supported formats below)

Supported File Formats:

  • Images: .gif, .jpg, .jpeg, .png
  • Documents: .pdf, .doc, .docx, .xls, .xlsx, .csv
  • Videos: .mp4, .mov, .avi

Error Handling:

  • Missing required attachment: “At least one attachment is required”
  • Invalid file format: Handled by useUploadFileAttachment hook
  • Upload errors: Displayed via handleAttachmentFailures utility

Save Button State:

// Button is disabled when:
disabled={
  !isAttachmentsUploaded ||     // Attachments still uploading
  isSubmittingComment ||         // Comment being submitted
  !isMessageValid ||             // Comment validation failed
  !hasRequiredAttachments        // Missing required attachments
}

UI Changes Based on Configuration

No Requirements (requireCommentOnResolve: false, requireAttachmentOnResolve: false)

  • No modal shown
  • Issue resolved immediately on status change

Comment Required (requireCommentOnResolve: true, requireAttachmentOnResolve: false)

  • Modal title: “Resolve Issue”
  • Subtitle: “Please describe how the issue was resolved before proceeding.”
  • Comment label: “Resolution details”
  • Attachment label: “Attachment (Optional)”
  • Attachment placeholder: “Select up to 10 files”

Comment + Attachment Required (requireCommentOnResolve: false, requireAttachmentOnResolve: true)

  • Modal title: “Resolve Issue”
  • Subtitle: “Please describe how the issue was resolved before proceeding.”
  • Comment label: “Resolution details”
  • Attachment label: “Attachment” (no “Optional”)
  • Attachment description: “Attach at least one image, document, or video to this resolution”
  • Attachment placeholder: “Select at least 1 file (max 10)”
  • Error shown if no attachment: “At least one attachment is required”

Translation Keys: modal.json


API Integration

Comment Submission

Single Issue

  • Function: handleSubmitComment (from useHandleSubmitComment hook)
  • Location: IssueDetail.tsx
  • Payload:
    {
      message: string,
      messageType: 'comment',
      attachments?: string[] // Reference IDs
    }

Bulk Issues

  • Function: bulkSubmitIssueMesage
  • Location: issues.service.ts
  • Payload:
    {
      createdAt: string,
      createdBy: string,
      createdByName: string,
      message: string,
      messageType: 'comment',
      attachments?: string[] // Reference IDs
    }

Status Update

Single Issue

  • Uses: IssueStatusController.updateStatus()
  • Timing: Called AFTER successful comment submission

Bulk Issues

  • Function: bulkEditIssues
  • Payload: { status: 'resolved', ...otherChanges }
  • Timing: Called AFTER successful bulk comment submission

Code References

Key Files

FilePurposeLines of Interest
issueResolutionRequirements.tsHook for accessing requirements22-47 (hook definition)
ResolvedIssueModal.tsxResolution modal UI & validation54 (attachment check), 69 (save button state)
GeneralSettings.tsxSettings UI107-138 (radio buttons)
IssueTrackerSettings.reducer.tsSettings state management9-12 (interface), 71-72 (defaults), 210-229 (reducers)
TableItemStatusSelect.tsxTable view implementation131-133 (check), 228-239 (modal)
KanbanStatusDialog.tsxKanban view implementation41-43 (check), 163-174 (modal)
StatusSelect.tsxList/Details view implementation131-133 (check), 228-239 (modal)
IssueDetailForm.tsxLegacy detail form171-173 (check), 250-258 (modal)
IssueBulkEdit.tsxBulk edit implementation152-158 (check), 68-80 (modal usage)
BulkResolveModal.tsxBulk resolution modal45-89 (comment submission)

Translation Keys

Modal Text (modal.json):

  • modal.issuePage.resolvedIssue.title: “Resolve Issue”
  • modal.issuePage.resolvedIssue.subtitle: “Please describe how the issue was resolved before proceeding.”
  • modal.issuePage.resolvedIssue.reasonLabel: “Resolution details”
  • modal.issuePage.resolvedIssue.reasonPlaceholder: “Enter resolution details”
  • modal.issuePage.resolvedIssue.reasonLessThanMinimum: “Character should be more than 10”
  • modal.issuePage.resolvedIssue.reasonExceedsLimit: “Character should be less than 250”
  • modal.issuePage.resolvedIssue.attachmentLabel: “Attachment (Optional)”
  • modal.issuePage.resolvedIssue.attachmentLabelRequired: “Attachment”
  • modal.issuePage.resolvedIssue.attachmentDescription: “Attach images, documents, or videos to this resolution”
  • modal.issuePage.resolvedIssue.attachmentDescriptionRequired: “Attach at least one image, document, or video to this resolution”
  • modal.issuePage.resolvedIssue.attachmentPlaceholder: “Select up to 10 files”
  • modal.issuePage.resolvedIssue.attachmentPlaceholderRequired: “Select at least 1 file (max 10)”
  • modal.issuePage.resolvedIssue.attachmentRequiredError: “At least one attachment is required”

Settings Text (label.json):

  • label.settingPage.resolveIssueWithComments: “Resolve issue with comments”
  • label.settingPage.no: “No”
  • label.settingPage.requireComment: “Comment Required (attachments optional)”
  • label.settingPage.requireCommentAndAttachment: “Comment + Attachment Required”

Testing Scenarios

Test Case 1: No Requirements

Setup: requireCommentOnResolve: false, requireAttachmentOnResolve: false

Steps:

  1. Open any issue
  2. Change status to “Resolved”

Expected: Status changes immediately without showing modal

Test Case 2: Comment Required

Setup: requireCommentOnResolve: true, requireAttachmentOnResolve: false

Steps:

  1. Open any issue
  2. Change status to “Resolved”
  3. Modal appears
  4. Enter comment less than 10 characters
  5. Enter valid comment (10-250 chars)
  6. Click Save without attachment

Expected:

  • Modal shows with “Attachment (Optional)” label
  • Error shown for short comment
  • Save succeeds with valid comment only

Test Case 3: Comment + Attachment Required

Setup: requireCommentOnResolve: false, requireAttachmentOnResolve: true

Steps:

  1. Open any issue
  2. Change status to “Resolved”
  3. Modal appears
  4. Enter valid comment
  5. Click Save (no attachment)
  6. Add 1 attachment
  7. Click Save

Expected:

  • Modal shows “Attachment” label (not optional)
  • Save disabled without attachment
  • Error message shown
  • Save succeeds after adding attachment

Test Case 4: Bulk Edit with Requirements

Setup: requireCommentOnResolve: true, requireAttachmentOnResolve: false

Steps:

  1. Select 5 issues
  2. Open bulk edit modal
  3. Change status to “Resolved”
  4. Click Save
  5. Enter comment in resolution modal
  6. Click Save

Expected:

  • Resolution modal appears
  • Same comment added to all 5 issues
  • All 5 issues marked as resolved

Test Case 5: All Views Consistency

Setup: Any configuration with requirements enabled

Steps:

  1. Resolve issue from Table View
  2. Resolve issue from Kanban View
  3. Resolve issue from List Details View
  4. Resolve issue from Issue Details page
  5. Resolve issue from Legacy Detail Form

Expected: All views show consistent modal and validation


Troubleshooting

Issue: Modal not showing when requirements are enabled

Possible Causes:

  1. Settings not saved properly
  2. Redux store not updated
  3. Component not using useIssueResolutionRequirements hook

Solution: Check Redux DevTools for issueTrackerSettings.issueTrackerSettings.requireCommentOnResolve and requireAttachmentOnResolve values

Issue: Attachments not validating

Possible Causes:

  1. requireAttachment prop not passed to ResolvedIssueModal
  2. Attachment upload hook not initialized

Solution: Verify requireAttachment={resolutionRequirements.requireAttachment} is passed to modal component

Issue: Bulk edit not requiring comments

Possible Causes:

  1. BulkResolveModal not being shown
  2. Check in handleSubmit not working

Solution: Verify line 152 in IssueBulkEdit.tsx is checking resolutionRequirements.showCommentModal


Future Enhancements

Potential improvements to consider:

  1. Configurable character limits: Allow admins to set min/max comment length
  2. Custom validation rules: Organization-specific attachment requirements
  3. Template comments: Pre-defined resolution reasons
  4. Attachment type restrictions: Require specific file types (e.g., only images)
  5. Different requirements per issue type: Standard issues vs Customer Feedback
  6. Audit trail: Track when settings are changed and by whom

  • Issue Tracker Settings: Main settings configuration page
  • Issue Status Management: Controls available issue statuses
  • Blocked Issues: Similar modal for marking issues as blocked/invalid
  • Bulk Edit: Mass operations on multiple issues
  • Issue Comments: Comment and attachment system

Document Version: 1.0 Last Updated: 2025-10-06 Author: Development Team