Remove unreachable WorkPackageCostlogController
The controller has no route in the application and is referenced nowhere,
so it can never be dispatched. The similarly named cost-report redirect
flow is served elsewhere, leaving this as dead code.
Moves the `click->reporting--page#removeFilter` Stimulus action from
the inner `<a>` element to the outer `<div>` wrapper. This ensures the
entire remove-filter area is a valid click target, so the hidden
`fields[]` value is cleared reliably when removing a filter.
Extract operator application and query-value preparation from
`sql_statement` to keep the blank-value fix while bringing the method
back under RuboCop metric limits.
Skip positive-arity reporting operators when no value is present, which
otherwise causes sporadic feature spec failures. Cover the blank-value
case through the filter SQL path and keep direct operator specs focused
on explicit nil values.
The `value == value.to_i.to_s` round-trip check that filters leading-
zero ID forms ("0123") was duplicated across the WP link handler, the
PDF export macro, and the cost-query filter.
A new `WorkPackage::SemanticIdentifier.numeric_id?(value)` predicate
captures the canonical-numeric check at one site. It pairs with
`semantic_id?` as the WP-finder shape gate; the two answer different
questions (shape vs routing) and so are kept independent rather than
expressed as one another's negation.
The cost-query filter switches to the predicate in this slice; the
text-formatting and PDF callers convert in a follow-up.
Adds two test layers that would have caught the plain-hash bug the
widget fix addressed:
- Widget unit spec (modules/reporting/spec/lib/widget/filters/work_package_spec.rb)
asserts map_filter_values emits id/displayId/formattedId/subject/name
with the right values in both modes. Fast feedback, pins the
Rails-to-Angular contract the autocompleter template depends on.
- work_package_costlog_spec is now parameterised over classic and
semantic modes via shared_examples, asserting the pre-populated
autocompleter renders "#42 subject" and "MYPROJ-1 subject"
respectively. End-to-end confidence that the widget, template, and
formattedId helper agree in a real browser.
The reporting filter widget pre-populates opce-autocompleter with
plain hashes ({id:, name:}). When the autocompleter template switched
from `#{item.id}` to `{{ item.formattedId }}`, those hashes had no
formattedId key and the ID prefix disappeared from the selected-value
label, breaking work_package_costlog_spec and time_entry_activity_spec.
Extend Widget::Filters::WorkPackage#map_filter_values to emit
formattedId, displayId, and subject alongside id/name so the
autocompleter template has the data it needs.
Centralise the formatting logic in a new WorkPackage#formatted_id
model method, mirroring the frontend formatWorkPackageId helper:
semantic identifiers pass through (PROJ-42); numeric ids are
prefixed with # (#42).