fix: Correct priority not saving when creating new tickets#243
fix: Correct priority not saving when creating new tickets#243
Conversation
Root cause: The priorities API resolved to Custom.PriorityLevel (string values like "Low", "Medium") but workItemToTicket reads from Microsoft.VSTS.Common.Priority (integer field), which was never set and defaulted to 2 (High). Fix: When writing to a custom priority field, also set the built-in Microsoft.VSTS.Common.Priority with the mapped numeric value (Critical=1, High=2, Medium=3, Low=4). Also renames priority labels from Urgent/Normal to Critical/Medium across the entire codebase to match Azure DevOps terminology, and adds friendly labels to the priority dropdown in the new ticket dialog. Closes #242 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug where ticket priorities were incorrectly saved when creating new tickets. The root cause was that the system was writing priority values to a custom field (Custom.PriorityLevel) but reading from the built-in field (Microsoft.VSTS.Common.Priority), which defaulted to 2 (High) when not explicitly set. The fix ensures both fields are set correctly, and also renames priority labels from "Urgent"/"Normal" to "Critical"/"Medium" to match Azure DevOps standard terminology.
Changes:
- Fixed priority not saving correctly by setting both custom and built-in priority fields during ticket creation
- Renamed priority terminology from Urgent/Normal to Critical/Medium across the entire codebase (19 files)
- Added friendly labels to priority dropdown UI to show "Critical", "High", "Medium", "Low" instead of numeric values
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/index.ts | Updated TicketPriority type and SLAConfig interface to use Critical/Medium instead of Urgent/Normal |
| src/lib/sla.ts | Updated SLA configuration defaults and default priority fallbacks to use new terminology |
| src/lib/devops.ts | Core fix: added logic to set both custom priority field and Microsoft.VSTS.Common.Priority with mapped numeric values |
| src/config/process-templates/t-minus-15.ts | Updated priority value labels to match new terminology |
| src/config/process-templates/scrum.ts | Updated priority value labels to match new terminology |
| src/components/tickets/TicketList.tsx | Updated priority filter dropdown options to use new labels |
| src/components/tickets/TicketHistory.tsx | Updated priority number-to-label mapping for history display |
| src/components/tickets/TicketDetail.tsx | Updated priority options array to use new labels |
| src/components/monthly-checkpoint/KPICards.tsx | Updated CSS variable reference from --priority-urgent to --priority-critical |
| src/components/monthly-checkpoint/CheckpointTicketTable.tsx | Updated priority options, order mapping, and default fallbacks to use new terminology |
| src/components/layout/Header.tsx | Updated CSS variable reference for sign-out button color |
| src/components/dashboard/SLARiskPanel.tsx | Updated CSS variable references and priority display fallbacks |
| src/components/common/PriorityIndicator.tsx | Updated priority configuration object keys and default fallback |
| src/app/tickets/page.tsx | Updated priority filter dropdown options |
| src/app/team/page.tsx | Updated CSS variable references for error/alert indicators |
| src/app/profile/page.tsx | Updated CSS variable references for error messages |
| src/app/globals.css | Renamed CSS custom properties and classes from urgent/normal to critical/medium |
| src/app/api/devops/tickets/route.ts | Changed hasPriority parameter logic from Boolean(validatedFieldRef) to priority-based check |
| src/app/api/devops/projects/[project]/priorities/route.ts | Added NUMERIC_PRIORITY_LABELS mapping to show friendly labels in UI |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
hasPriority should indicate whether the template supports a priority field, not whether the user provided a value. The inner check in createTicketWithAssignee already guards against empty values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents falling back to Azure DevOps default of High (2) when an unexpected priority value is provided to the custom-to-builtin field mapping. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Tested, Copilot's comments addressed. @BenGWeeks please check and merge. |
BenGWeeks
left a comment
There was a problem hiding this comment.
Lots of duplication of the priority levels defined. Ideally read from DevOps in a single function that is re-used. Appreciate difficult to programmatically define icons / colours etc. when reading from DevOps. Perhaps mapping defined in the process template. Consiuder that the code must work with different process templates where (a) the priotity field might not even be there, and (b) the drop down options are different.
- Create src/lib/priority.ts as single source of truth for priority mappings - Widen TicketPriority type to string to support dynamic DevOps values - Derive filter dropdown options from actual ticket data instead of hardcoding - Update all components to use centralized constants - Fix inconsistent priority sort labels (Urgent/Normal → Critical/Medium) - Handle unknown priority values gracefully in PriorityIndicator Addresses review feedback from BenGWeeks on PR #243. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
How are these mapped to the process template? (which may have different priorities / field names).
There was a problem hiding this comment.
The priority.ts contains fallback labels only - the actual priorities are fetched dynamically from DevOps at runtime via the priorities endpoint, which queries 3 different API approaches to resolve the correct field and allowed values for each process template.
There was a problem hiding this comment.
What I mean is, if the process template defines the Priority field to match a field called "Contoso Urgency", and Contoso_Urgency has options:
- Really urgent
- Somewhat urgent
- Not very urgent
- Whenever really
How will you map the field and the values? E.g. Contoso_Urgency = Priority and:
- Really urgent = Critical
- Somewhat urgent = High
- Not very urgent = Medium
- Whenever really = Low
There was a problem hiding this comment.
Honest answer: we don't map them, and I think that's correct.
If a custom picklist field returns string values like "Really urgent", "Somewhat urgent", etc., the priorities endpoint passes them through as-is — both value and label would be the original DevOps string (line 224: DEFAULT_PRIORITY_LABELS[String(value)] || String(value) — the fallback is the raw value). The Create Ticket dropdown would show those custom labels directly.
However, you're right that there are downstream limitations with fully custom labels today:
- Sorting (
PRIORITY_ORDER): Unknown labels get?? 99, so they'd all sort last in ticket lists - Ticket detail dropdown (
DEFAULT_PRIORITY_OPTIONS): Would show Critical/High/Medium/Low instead of the project's custom labels - Numeric write-back (
PRIORITY_LABEL_TO_NUMBERindevops.ts): Would fail to map "Really urgent" → a number forMicrosoft.VSTS.Common.Priority
Trying to infer semantic equivalence between arbitrary labels (is "Somewhat urgent" = High or Medium?) would be brittle. The better approach would be to:
- Fetch the project's priority field + allowed values at render time (the endpoint already does this)
- Use the position/index in the allowed values array as the sort order, rather than matching against a hardcoded label map
That said, this is a broader enhancement — today ZapDesk only targets the three known priority fields (Microsoft.VSTS.Common.Priority, Custom.PriorityLevel, Microsoft.VSTS.CMMI.Priority). A field called "Urgency" with a completely custom reference name wouldn't be detected at all currently. Want me to open a separate issue to track this?
Summary
Custom.PriorityLevel(string values like "Low", "Medium") butworkItemToTicketreads fromMicrosoft.VSTS.Common.Priority(integer field), which was never set and defaulted to 2 (High)Microsoft.VSTS.Common.Prioritywith the mapped numeric value (Critical=1, High=2, Medium=3, Low=4)Test plan
Closes #242
🤖 Generated with Claude Code