Skip to content

Show date as source subtitle when measuring time remaining with Jira as source #13277

Description

@fniessink

Show the end date of the active sprint as subtitle of the source name, the same way the calendar source shows its configured date as subtitle.

Background

The source-name subtitle is currently driven entirely by parameters: Source.identifying_parameters lists parameter keys, and the frontend (identifyingParameterValues / formatParameterValue) reads and formats the source's configured parameter values. This works for the calendar source, whose date is a date parameter (identifying_parameters=["date"]).

For Jira with the time remaining metric, the end date is not a parameter — it is computed by the collector from the active sprint's endDate and turned into a day count. There is currently no mechanism to display a measured value as the source subtitle.

Approach

Store the active sprint(s) as measurement entities, with the sprint name, start date, and end date as attributes. Two pieces of information determine what to display as the subtitle:

  • Which attribute to display — declared statically in the data model. Add an identifying_attribute field to the Entity model (the end date), mirroring the existing measured_attribute field. Because entities are keyed per metric, this is automatically scoped to time_remaining only.
  • Which entity to display it from — determined dynamically per measurement by the collector. Add an identifying_entity field to the source measurement holding the key of the entity that drove the measurement value (the sprint with the earliest end date), rather than relying on the convention that e.g. the first entity is the value-driving one.

Work

  1. Entity meta model (meta/entity.py): add identifying_attribute: str | None = None, with a validator (shaped like check_measured_attribute) asserting the referenced attribute exists on the entity. No type restriction is needed — the frontend formats dates specially and renders any other type as a string, matching how identifying_parameters already handles non-date parameters.

  2. Source measurement model (collector/model/measurement.py): add identifying_entity: str | None = None to SourceMeasurement and include it in as_dict().

  3. Jira data model (sources/jira.py): add a time_remaining entity for the active sprints, with identifying_attribute pointing at the end date, e.g.:

    "time_remaining": Entity(
        name="sprint",
        attributes=[
            EntityAttribute(name="Sprint name", url="url"),
            EntityAttribute(name="Start date", type=EntityAttributeType.DATE),
            EntityAttribute(name="End date", type=EntityAttributeType.DATE),
        ],
        identifying_attribute="end_date",
    ),
    
  4. Collector (JiraTimeRemaining):

    • Emit one measurement entity per active sprint, with the sprint id as key and sprint_name, start_date, and end_date attributes.
    • Compute the measurement value from the minimum (earliest) end date of the active sprints instead of the first active sprint. Note that the time_remaining metric is more-is-better, so the base TimeCollector.minimum() selects the latest date — the collector must override this to use the earliest end date.
    • Set identifying_entity to the key of the sprint with the earliest end date.
    • Point _landing_url at the earliest-ending sprint as well, instead of the first active sprint, so the link is consistent with the measured value and the subtitle.
  5. Frontend: add an identifyingEntityValues(measurementSource, dataModelSource, metricType) companion to identifyingParameterValues that looks up the entity named by measurementSource.identifying_entity, reads the attribute named by dataModelSource.entities[metricType].identifying_attribute off it, and formats date/datetime attributes with dayjs(...).format("ll") — the same format used for the calendar source's date. When identifying_entity is absent (e.g. older measurements), render no entity-based subtitle. SourceStatus concatenates the parameter-based and entity-based identifying values into the same caption subtitle.

Out of scope

  • Switching all time collectors to storing a timestamp instead of days left/to go.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Source(s)New, enhanced, or removed metric sourceUXUser experience

    Fields

    No fields configured for Feature.

    Projects

    Status
    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions