Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7592cd6
add chs cron job (not fully functional)
functionzz Jun 3, 2026
474b32d
Update pontoon/insights/chs.py
functionzz Jun 4, 2026
39ed6cc
Update pontoon/insights/chs.py
functionzz Jun 8, 2026
db3fd41
Update pontoon/insights/chs.py
functionzz Jun 8, 2026
a7f24ff
add env variables over hardcoded constants
functionzz Jun 8, 2026
257014a
change LocaleChsSnapshot to LocaleHealthSnapshot, completion formula …
functionzz Jun 10, 2026
a064a00
dashboard frontend base
functionzz Jun 11, 2026
7df3b42
add configuration form + button + model changes, add staff authentica…
functionzz Jun 12, 2026
9da467a
add score/default view, change fields to Decimal, reform css, improv…
functionzz Jun 12, 2026
8dd04bd
missing dashboard.html addition
functionzz Jun 12, 2026
93d6417
add no locale check, order locales by code
functionzz Jun 15, 2026
56f737f
full feature parity with scripts
functionzz Jun 15, 2026
56a5929
add community health activity charts to Locale and Global insights
functionzz Jun 22, 2026
1ec9668
small snapshot logic, docs + DX changes
functionzz Jun 22, 2026
db983ac
fix global insights tests
functionzz Jun 23, 2026
7014e00
fix typo
functionzz Jun 23, 2026
8ba21ff
Delete config.js
functionzz Jun 23, 2026
3370eb7
fix small nits, add locales param to build_chs_snapshots
functionzz Jun 23, 2026
9869c0a
add snapshot + supporting function tests
functionzz Jun 23, 2026
c4b12d7
rename columns, rename graphs, remove CHS Y-axis
functionzz Jun 23, 2026
49b1681
move /dashboard contents into /insights + renaming work
functionzz Jun 24, 2026
c4ce014
renaming dashboards
functionzz Jun 24, 2026
836bd41
doc changes
functionzz Jun 24, 2026
e2f4802
Create 0118_merge_20260624_0350.py
functionzz Jun 24, 2026
e0eade8
run make format
functionzz Jun 24, 2026
3be5b90
revert temp stopgap
functionzz Jun 24, 2026
6b12b9a
streamline LocaleHealthSnapshot migrations
functionzz Jun 24, 2026
898c2e7
run make format
functionzz Jun 24, 2026
845b226
merge migration
functionzz Jun 24, 2026
bf7a7a3
run make format
functionzz Jun 24, 2026
7f6dc85
rename collect_chs_snapshot file, center Locale, show All in graphs
functionzz Jun 25, 2026
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
12 changes: 12 additions & 0 deletions documentation/docs/dev/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,18 @@ the day, every day.
./manage.py collect_insights
```

### Collect CHS Snapshot

Captures per-locale Contributor Health Score metrics - completion, key-project
enablement, active managers / translators / contributors & new signups into
`LocaleHealthSnapshot` model. Used via the Insights dashboard and pages for
month-over-month CHS comparisons and monthly trend charts. The job is designed
to run once a month on the first of each month.

``` bash
./manage.py collect_chs_snapshots
```

### Warm up cache

We cache data for some of the views (e.g. Contributors) for a day. Some
Expand Down
10 changes: 10 additions & 0 deletions pontoon/base/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,16 @@ class Meta:
fields = ("locales_order",)


class UserInsightsDashboardConfigForm(forms.ModelForm):
"""
Form is responsible for saving custom configurations of the Insights Dashboard.
"""

class Meta:
model = UserProfile
fields = ("dashboard_locales",)


class GetEntitiesForm(forms.Form):
"""
Form for parameters to the `entities` view.
Expand Down
24 changes: 24 additions & 0 deletions pontoon/base/migrations/0117_userprofile_dashboard_locales.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I assume only this migration should be part of your patch, the number and dependency updated, and the others removed?

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 5.2.14 on 2026-06-11 19:42

import django.contrib.postgres.fields

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("base", "0116_remove_systran_locale_fields"),
]

operations = [
migrations.AddField(
model_name="userprofile",
name="dashboard_locales",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.PositiveIntegerField(),
blank=True,
default=list,
size=None,
),
),
]
12 changes: 12 additions & 0 deletions pontoon/base/migrations/0118_merge_20260624_0350.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Django 5.2.14 on 2026-06-24 03:50

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("base", "0117_userprofile_dashboard_locales"),
("base", "0117_userprofile_editor_theme"),
]

operations = []
12 changes: 12 additions & 0 deletions pontoon/base/migrations/0119_merge_20260624_1835.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Django 5.2.14 on 2026-06-24 18:35

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("base", "0118_fix_terminology_entity_value"),
("base", "0118_merge_20260624_0350"),
]

operations = []
7 changes: 7 additions & 0 deletions pontoon/base/models/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ class EmailFrequencies(models.TextChoices):
search_match_whole_word = models.BooleanField(default=False)
search_rejected_translations = models.BooleanField(default=False)

# Dashboard configurations
dashboard_locales = ArrayField(
models.PositiveIntegerField(),
default=list,
blank=True,
)

# Used to redirect a user to a custom team page.
custom_homepage = models.CharField(max_length=20, blank=True, null=True)

Expand Down
6 changes: 5 additions & 1 deletion pontoon/base/static/js/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,11 @@ var Pontoon = (function (my) {
}

function getSort(el) {
return parseInt($(el).find('[data-sort]').data('sort'), 10) || 0;
const cell = $(el).find('td').eq(index);
const holder = cell.is('[data-sort]')
? cell
: cell.find('[data-sort]').first();
return parseFloat(holder.attr('data-sort')) || 0;
}

function getString(el) {
Expand Down
31 changes: 31 additions & 0 deletions pontoon/insights/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib import admin

from pontoon.insights.models import (
LocaleHealthSnapshot,
LocaleInsightsSnapshot,
ProjectLocaleInsightsSnapshot,
)
Expand Down Expand Up @@ -39,5 +40,35 @@ class ProjectLocaleInsightsSnapshotAdmin(admin.ModelAdmin):
readonly_fields = ("project_locale",)


class LocaleHealthSnapshotAdmin(admin.ModelAdmin):
search_fields = [
"pk",
"locale__code",
"locale__name",
]
list_display = (
"pk",
"locale",
"created_at",
"completion",
"key_projects_enabled",
"active_managers",
"active_translators",
"active_contributors",
"all_contributors",
"new_signups",
"completion_score",
"key_projects_enabled_score",
"active_managers_score",
"active_translators_score",
"active_contributors_score",
"all_contributors_score",
"new_signups_score",
"chs",
)
list_filter = ("created_at",)


admin.site.register(LocaleInsightsSnapshot, LocaleInsightsSnapshotAdmin)
admin.site.register(ProjectLocaleInsightsSnapshot, ProjectLocaleInsightsSnapshotAdmin)
admin.site.register(LocaleHealthSnapshot, LocaleHealthSnapshotAdmin)
Loading
Loading