120 Commits

Author SHA1 Message Date
Klaas van Schelven
ca3934ad40 Improve default Sentry SDK settings for Python
Fix #298
2026-01-10 14:18:17 +01:00
Klaas van Schelven
fc85b16567 MAX_RETENTION[_PER_PROJECT] as a setting 2026-01-07 21:47:41 +01:00
Klaas van Schelven
7bb6673e39 Quota warning message: formatting 2026-01-07 14:51:08 +01:00
Klaas van Schelven
cdb9ef7fa7 Project-level quota exceeded: show a message 2026-01-07 14:34:02 +01:00
Klaas van Schelven
7b7cd66dfb Project quota: pick up on settings-changes 2026-01-07 14:02:43 +01:00
Klaas van Schelven
609e92935d Note about 'megaphone' icon 2025-11-26 10:46:28 +01:00
Klaas van Schelven
2a90d6ab1e Message service backend setup: switch config form per-service in the UI
See #281, which this commit prepares for
2025-11-26 09:10:14 +01:00
Klaas van Schelven
9b2acddf20 yesno filter: just don't return None ever
I had someone run into this on hosted Bugsink; couldn't reproduce it.
Thought I fixed it in e8fb9556f7 (specific to the Chinese translation)
but appararently there's other ways to reach this point.

No matter, just create a version of the yesno filter that's not sensitive
to any future mistranslation.
2025-11-24 21:24:44 +01:00
Klaas van Schelven
a93f369ad7 Fix member counts on project/team list
they were at most 1
2025-11-12 16:10:10 +01:00
Klaas van Schelven
afd31d2263 API: datetime objects always in UTC
i.e. avoid the pain of time-conversions when 'talking with computers'.
2025-09-26 15:01:55 +02:00
Klaas van Schelven
0ca3e33e1f API: remove 'is_deleted' as a field
it's implicit(ly not so): soft-deleted items should
not be returned, and everything that's returned isn't
deleted
2025-09-26 13:53:51 +02:00
Klaas van Schelven
e60fbb2cd5 Fix invalid focus:ring-3-* classnames from migration
Tailwind 3 -> 4 migration renamed `ring` -> `ring-3`, but colors like
`ring-cyan-200` were also changed to `ring-3-cyan-200` which doesn't
actually exist.

broken in ac8e2e8cd6

See #225 (the present commit is related, but not a full fix)
2025-09-22 09:50:35 +02:00
Klaas van Schelven
4d3756f621 API: leave notes on get_object's future 2025-09-18 20:12:28 +02:00
Klaas van Schelven
018e934bdb Reference sourcemaps instruction in JS SDK page 2025-09-17 20:49:22 +02:00
Klaas van Schelven
3156f05756 Refactoring into the factory style
done while trying to fix an unrelated error; keeping this as a
stylistic change regardless
2025-09-12 11:49:32 +02:00
Klaas van Schelven
a4e84fa0a3 Add Swagger using drf-spectacular
See #146

DRF 3.16 and Django 5.2 are not in drf-spectacular's published
list of supported but here's some sources that give reason to believe
they are supported _in practice_:

* https://github.com/tfranzel/drf-spectacular/issues/1417
* https://github.com/tfranzel/drf-spectacular/issues/1414
2025-09-12 11:46:44 +02:00
Klaas van Schelven
9ad66d7b50 API: adhere to Bugsink's DB-transactional model
as per https://www.bugsink.com/blog/database-transactions/
2025-09-11 18:01:05 +02:00
Klaas van Schelven
1c0745f24f API: support expand=...
(implemented only for project.team for now, but in a generic way
2025-09-11 17:38:42 +02:00
Klaas van Schelven
07b792775a API pagination 2025-09-11 16:52:14 +02:00
Klaas van Schelven
30ae7881aa Teams & Projects API
See #146
2025-09-11 09:55:32 +02:00
Klaas van Schelven
4c2c26743e Canonical API 'skeleton': urls & views
this gives me something to look at and work with, despite
being wildly incomplete

See #146
2025-09-09 10:07:10 +02:00
Klaas van Schelven
a4ecd386b6 Support hosting at subpath
"In principle" setting `SCRIPT_NAME` is enough. The way we do this is [1] using
`FORCE_SCRIPT_NAME` (which does not depend on messing with reverse proxy
settings and [2] by deducing the correct value from `BASE_URL` (which must be
set anyway) automatically.

By works I mean: `reverse` and `{% url` pick it up from there.

However, there are subtleties / extra work:

* `STATIC_URL` is needed too b/c https://code.djangoproject.com/ticket/34028

* in many pre-existing code I just created a path manually in the html. Such
  hrefs are obviously not magically fixed for script_name. Rather than doing
  the "full rewrite" (into `{% url`) this commit just prepends the
  `script_name` in those cases. That's the way forward that will least likely
  break and it gives us something to grep for if we ever want to 'do it
  right'.

* `LOGIN_REDIRECT_URL` and `LOGIN_URL` needed to use a view-name for this to
  work (using a view-name gets revolved using the thing that introduces
  `script_name`)

Checked, no work needed:

* views (`redirect` and `HttpResponseRedirect`)
* html uses of action="..."

Fix #93
2025-09-05 22:47:22 +02:00
Klaas van Schelven
ad8a2a5e4f Tailwind 3 => 4: bg-opacity "folded into bg"
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
Klaas van Schelven
610e7b1c17 Tailwind 3 => 4: rounded => rounded-sm
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
Klaas van Schelven
ac8e2e8cd6 Tailwind 3 => 4: ring => ring-3
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities
2025-09-04 13:20:22 +02:00
Klaas van Schelven
a0dc91c8c5 Push verbose_name to the model-level
at least for those fields where it is currently used.
this necessitates a patch to the migration machinery, which this commit adds

See #161
2025-08-28 16:03:27 +02:00
Klaas van Schelven
f38112f3df Pull markup out of translation files
it's bad enough that we do markup in views.py

See #161
2025-08-28 15:31:43 +02:00
Klaas van Schelven
a3cdeb9c8a Flake8 (including one breakage)
See #161
2025-08-28 15:01:05 +02:00
Klaas van Schelven
31fdf46a10 yesnomaybe translation fix
see https://code.djangoproject.com/ticket/36579

* remove workarounds; instead just provide a correctly formatted one in the .po file
* regen of .po file more generally

See #161
2025-08-28 14:17:31 +02:00
某亚瑟
2b5fb1bf67 Basically completed i18n support, and Chinese translation
Implement most Chinese text translations, adding default recognition browser language and user settings language
2025-08-02 10:25:19 +08:00
Klaas van Schelven
354af7ea0a Fix issues as reported by bandit or mark as nosec
Nothing worrying, but good to have checked this regardless
and important to have a green pipeline.

Fix #175
2025-07-30 12:16:40 +02:00
Klaas van Schelven
9b8409d8b2 Global trailing whitespace cleanup 2025-07-29 12:53:10 +02:00
Klaas van Schelven
91b99af08d project-alert edits: fix misalignments (by asking ChatGPT) 2025-07-28 22:18:02 +02:00
copilot-swe-agent[bot]
21ee428938 Add UI components to display alert backend failure status
Co-authored-by: vanschelven <223833+vanschelven@users.noreply.github.com>
2025-07-28 22:13:22 +02:00
Klaas van Schelven
2b46bfe9a1 Project-edit: redirect to list on-save 2025-07-14 16:08:30 +02:00
Klaas van Schelven
3baedcaab9 Project-delete: show success-message after delete 2025-07-07 12:48:35 +02:00
Klaas van Schelven
f21d9f989b Fix recently added UI elements to have dark mode too
the elements were added after the work on #125 was done but in a
branch w/o dark-mode, so they needed to still be fixed
2025-07-07 11:39:27 +02:00
Klaas van Schelven
d99f946665 Merge branch 'main' into feature/add_dark_theme 2025-07-07 11:08:00 +02:00
Klaas van Schelven
7b340fd8ff Hide in-progress deletions of Project & Issue from the UI
I've done a full grep on Issue.objects, Project.objects and get_object_or_404
equivelents, and applying some common sense. The goal: avoid having
confusing/half-broken pages in the UI.

On index-usage: I've decided not to update the indexes. The assumption is:
`is_deleted` items will be a tiny minority of items in general, making the
cost/benefit analysis not turn out favorably (just scanning them out as a final
step is more efficient).  Also: sqlite is able to use the correct index without
adding a special one, proof:

```
EXPLAIN QUERY PLAN SELECT [..] WHERE ("issues_issue"."project_id" = 1 AND "issues_issue"."is_muted" = (0) AND "issues_issue"."is_resolved" = (0)) ORDER BY "issues_issue"."last_seen" DESC LIMIT 250;
QUERY PLAN
`--SEARCH issues_issue USING INDEX issue_list_open (project_id=? AND is_resolved=? AND is_muted=?)

EXPLAIN QUERY PLAN SELECT [..] WHERE ("issues_issue"."project_id" = 1 AND "issues_issue"."is_muted" = (0) AND "issues_issue"."is_resolved" = (0) AND "issues_issue"."is_deleted" = 0) ORDER BY "issues_issue"."last_seen" DESC LIMIT 250;
QUERY PLAN
`--SEARCH issues_issue USING INDEX issue_list_open (project_id=? AND is_resolved=? AND is_muted=?)
```

See #139 for the 0/1 notation in the above.

(Project-indexes: not an issue, the scale is "below relevance for indexes")
2025-07-07 10:27:36 +02:00
Animesh Agrawal
72479fe982 add button for project-delete in UI
Implement delete functionality with confirmation modals for projects.

cherry picked (by Klaas) from commit 6764fbf343fb; but:

* projects only
* `delete_deferred`
* flake8

See #84 for the original PR
2025-07-04 17:33:02 +02:00
Klaas van Schelven
4900f0447e Project-deletion: slight optimization
Removes the following 2 redundant queries from the deletion process:

```
SELECT "tags_tagkey"."id" FROM "tags_tagkey" WHERE "tags_tagkey"."project_id" IN (1) ORDER BY "tags_tagkey"."project_id" ASC, "tags_tagkey"."id" ASC LIMIT 498
UPDATE "projects_project" SET "stored_event_count" = ("projects_project"."stored_event_count" - 1) WHERE "projects_project"."id" = 1
```
2025-07-03 22:04:51 +02:00
Klaas van Schelven
28b2ce0eaf Various models: .project SET_NULL => DO_NOTHING
Like e45c61d6f0, but for .project.

I originally thought `SET_NULL` would be a good way to "do stuff later", but
that's only so the degree that [1] updates are cheaper than deletes and [2]
2nd-order effects (further deletes in the dep-tree) are avoided.

Now that we have explicit Project-deletion (deps-first, delayed, properly batched)
the SET_NULL behavior is always a no-op (but with cost in queries).

As a result, in the test for project deletion (which has deletes for many
of the altered models), the following 12 queries are no longer done:

```
SELECT "projects_project"."id", [..many fields..] FROM "projects_project" WHERE "projects_project"."id" = 1
DELETE FROM "projects_projectmembership" WHERE "projects_projectmembership"."project_id" IN (1)
DELETE FROM "alerts_messagingserviceconfig" WHERE "alerts_messagingserviceconfig"."project_id" IN (1)
UPDATE "releases_release" SET "project_id" = NULL WHERE "releases_release"."project_id" IN (1)
UPDATE "issues_issue" SET "project_id" = NULL WHERE "issues_issue"."project_id" IN (1)
UPDATE "issues_grouping" SET "project_id" = NULL WHERE "issues_grouping"."project_id" IN (1)
UPDATE "events_event" SET "project_id" = NULL WHERE "events_event"."project_id" IN (1)
UPDATE "tags_tagkey" SET "project_id" = NULL WHERE "tags_tagkey"."project_id" IN (1)
UPDATE "tags_tagvalue" SET "project_id" = NULL WHERE "tags_tagvalue"."project_id" IN (1)
UPDATE "tags_eventtag" SET "project_id" = NULL WHERE "tags_eventtag"."project_id" IN (1)
UPDATE "tags_issuetag" SET "project_id" = NULL WHERE "tags_issuetag"."project_id" IN (1)
```
2025-07-03 21:49:49 +02:00
Klaas van Schelven
6b9e4d8011 Project.delete_deferred(): first version (WIP)
Implemented using a batch-wise dependency-scanner in delayed
(snappea) style.

* no real point-of-entry in the (regular, non-admin) UI yet.
* no hiding of Projects which are delete-in-progress from the UI

* lack of DRY
* some unnessary work (needed in the Issue-context, but not here)
  is still being done.

See #50
2025-07-03 21:01:28 +02:00
Fabien LEFEBVRE (d1ceward)
9cec248ad8 Add dark theme 2025-06-16 15:37:37 +02:00
Klaas van Schelven
fac5b19966 Slack Alerts
Fix #3
2025-06-10 22:00:37 +02:00
Klaas van Schelven
17fb9cc850 Remove open_issue_count from homepage; it's too expensive 2025-05-06 10:27:16 +02:00
Klaas van Schelven
6e0f1f0f54 Document team/project visibility/access design 2025-04-04 10:01:38 +02:00
Klaas van Schelven
8fc6f752cf Allow users to join their own team's projects
Fix #56

Looked into this for a while, but I think it was simply an oversight in
the logic-as-programmed; if you're part of a team, you should be able
to just click 'join' on any of that team's projects and be a project-member
2025-04-03 16:28:35 +02:00
Klaas van Schelven
427a2a341e Change tab header into "Team Projects"
It said "Other Team Projects", which has 2 ways to be read:

* "Other (Team Projects)" (the correct one)
* "(Other Team) Projects" (the incorrect one)
2025-04-03 16:23:06 +02:00
Klaas van Schelven
9e683d8c9d retention_max_event_count: in project settings form
somewhere, there's a case that such settings need a different level of
authorization; (just because you're the admin of the project doesn't mean you
should be able to do things that affect the system as a whole) but we don't
have such a level ATM.
2025-03-31 16:00:20 +02:00