Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nimbus): Summary page timeline #11393

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions experimenter/experimenter/experiments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,29 @@ def recipe_json(self):
.replace("\\n", "\n") # Handle hard coded newlines in targeting
)

def get_changelog_date(self, status_field=None, status_value=None):
queryset = self.changes.order_by("changed_on")
if status_field and status_value:
queryset = queryset.filter(**{status_field: status_value})
changelog = queryset.first()
return changelog.changed_on.date() if changelog else None

@property
def draft_date(self):
return self.get_changelog_date()

@property
def preview_date(self):
return self.get_changelog_date(
status_field="new_status", status_value=self.Status.PREVIEW
)

@property
def review_date(self):
return self.get_changelog_date(
status_field="new_publish_status", status_value=self.PublishStatus.REVIEW
)


class NimbusBranch(models.Model):
experiment = models.ForeignKey(
Expand Down
47 changes: 47 additions & 0 deletions experimenter/experimenter/experiments/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,53 @@ def test_computed_end_date_returns_proposed_with_actual_enrollment_duration(self
),
)

def test_draft_date_uses_first_changelog_if_no_start_date(self):
experiment = NimbusExperimentFactory.create(_start_date=None)
first_changelog = NimbusChangeLogFactory.create(
experiment=experiment, changed_on=datetime.datetime(2023, 2, 1)
)
self.assertEqual(experiment.draft_date, first_changelog.changed_on.date())

def test_preview_date_returns_first_preview_change(self):
experiment = NimbusExperimentFactory.create()
preview_change = NimbusChangeLogFactory.create(
experiment=experiment,
old_status=NimbusExperiment.Status.DRAFT,
new_status=NimbusExperiment.Status.PREVIEW,
changed_on=datetime.datetime(2023, 3, 1),
)
self.assertEqual(experiment.preview_date, preview_change.changed_on.date())

def test_preview_date_returns_none_if_no_preview_status(self):
experiment = NimbusExperimentFactory.create()
NimbusChangeLogFactory.create(
experiment=experiment,
old_status=NimbusExperiment.Status.DRAFT,
new_status=NimbusExperiment.Status.DRAFT,
changed_on=datetime.datetime(2023, 4, 1),
)
self.assertIsNone(experiment.preview_date)

def test_review_date_returns_first_review_change(self):
experiment = NimbusExperimentFactory.create()
review_change = NimbusChangeLogFactory.create(
experiment=experiment,
old_publish_status=NimbusExperiment.Status.PREVIEW,
new_publish_status=NimbusExperiment.PublishStatus.REVIEW,
changed_on=datetime.datetime(2023, 5, 1),
)
self.assertEqual(experiment.review_date, review_change.changed_on.date())

def test_review_date_returns_none_if_no_review_status(self):
experiment = NimbusExperimentFactory.create()
NimbusChangeLogFactory.create(
experiment=experiment,
old_publish_status=NimbusExperiment.Status.DRAFT,
new_publish_status=NimbusExperiment.Status.PREVIEW,
changed_on=datetime.datetime(2023, 6, 1),
)
self.assertIsNone(experiment.review_date)

def test_monitoring_dashboard_url_is_valid_when_experiment_not_begun(self):
experiment = NimbusExperimentFactory.create(
slug="experiment",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
}
}
}
.mode-sensitive {
background-color: var(--bg-light-color);
}
}

@include color-mode(dark) {
Expand Down Expand Up @@ -123,4 +126,8 @@
}
}
}
.mode-sensitive {
background-color: var(--bs-secondary);
/* Bootstrap's secondary color */
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@
{% endblock %}

{% block main_content %}
<div class="container-fluid py-4">
<div class="container-fluid">
<!-- Experiment Details Card -->
<div class="card mb-3">
<div class="card-header">
<h4>Experiment Details</h4>
</div>
<div class="card-body">
<p>
<strong>Slug:</strong> {{ experiment.slug }}
</p>
<p>
<strong>Name:</strong> {{ experiment.name }}
</p>
<div class="row">
<div class="col-6">
<h4 class="mb-0">{{ experiment.name }}</h4>
<p class="text-secondary">{{ experiment.slug }}</p>
</div>
{% include "nimbus_experiments/timeline.html" %}

</div>
<!-- Takeaways Card -->
{% include "nimbus_experiments/takeaways_card.html" %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div class="col-6">
<ul class="list-group list-group-horizontal justify-content-between mb-3">
<!-- Draft Status -->
<li class="list-group-item flex-fill text-center d-flex flex-column justify-content-center {% if experiment.status == 'Draft' and experiment.publish_status == 'Idle' %} bg-primary text-light {% else %} mode-sensitive text-dark {% endif %}">
Copy link
Collaborator

@jaredlockhart jaredlockhart Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def timeline_dates(self):
    return [
        (self.Status.DRAFT.value, self.......),
        .....
    ]
<ul class="....">
  {% for status, date in experiment.timeline_dates %}
    <li class="list-group-item .....>
      <strong>{{ status}}</strong>
      <small>{{ date|default:"---" }}</small>
    </li>
  {% endfor %}
</ul>

<strong>Draft</strong>
<small>{{ experiment.draft_date|default:'---' }}</small>
</li>
<!-- Preview Status -->
<li class="list-group-item flex-fill text-center d-flex flex-column justify-content-center {% if experiment.status == 'Preview' and experiment.publish_status == 'Idle' %} bg-primary text-light {% else %} mode-sensitive text-dark {% endif %}">
<strong>Preview</strong>
<small>{{ experiment.preview_date|default:'---' }}</small>
</li>
<!-- Review Status -->
<li class="list-group-item flex-fill text-center d-flex flex-column justify-content-center {% if experiment.publish_status != 'Idle' %} {% if experiment.status == 'Preview' or experiment.status == 'Draft' %} bg-primary text-light {% else %} mode-sensitive text-dark {% endif %} {% else %} mode-sensitive text-dark {% endif %}">
<strong>Review</strong>
<small>{{ experiment.review_date|default:'---' }}</small>
</li>
<!-- Live Status -->
<li class="list-group-item flex-fill text-center d-flex flex-column justify-content-center {% if experiment.status == 'Live' %} bg-primary text-light {% else %} mode-sensitive text-dark {% endif %}">
<strong>Live</strong>
<small>{{ experiment.start_date|default:'---' }}</small>
</li>
<!-- Complete Status -->
<li class="list-group-item flex-fill text-center d-flex flex-column justify-content-center {% if experiment.status == 'Complete' %} bg-primary text-light {% else %} mode-sensitive text-dark {% endif %}">
<strong>Complete</strong>
<small>{{ experiment.end_date|default:'---' }}</small>
</li>
</ul>
</div>