Skip to content

[pull] develop from baserow:develop - #449

Merged
pull[bot] merged 3 commits into
code:developfrom
baserow:develop
Sep 16, 2026
Merged

pull[bot] merged 3 commits into
code:developfrom
baserow:develop

Conversation

@pull

@pull pull Bot commented Sep 16, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

alamin-br and others added 3 commits September 16, 2026 11:05
* feat: record who triggered an automation workflow run

* feat: name the clicker on a workflow a button started

* feat: carry the trigger user on the automation dispatch context

* feat: expose who triggered a run on the workflow history API

* feat: audit log a button field click

* feat: show who started a run in the workflow history

* docs: say a periodic trigger can be started and how a click is recorded

* fix: give the history actor label room for a full name

* fix: keep the trigger user off the dispatch context actor

A Local Baserow node with no integration acts as the context actor, so a run would act as whoever clicked.

* fix: audit a click only once it holds the lock

* feat: record who started a test run

* fix: honour is_test_run in the workflow history fixture

* refactor: resolve who started a run through the workspace user store

* test: drop a start workflow test whose deny patch never fires

* test: e2e for who started a workflow a button or a test run began

* test: e2e for picking a workflow in the button field editor

* refactor: read the trigger user lazily from the run's history

No per-node user join; the context exposes history.triggered_by on demand.

* refactor: plain serializer for who triggered a run

* test: forward history fixture kwargs and hoist imports

* fix: put the run's starter on its own line in the history panel

The header row is 327px wide; a name beside the title wrapped it. Name resolution reuses the collaborator mixin.

* docs: say exactly when a click is audited and what a nested run records

* test: share e2e job polling and AI panel suppression

* fix: annotate the automation dispatch context's history as a workflow history

* fix: cap the button action form so a helper sentence cannot stretch the editor

* fix: keep the automation dispatch context's history required

The simulation's history=None is a sample-data-only exception, not the norm.

* refactor: carry the dispatch context actor through own_properties

Contexts that take an actor list it like any other property; the rest keep the base None.

* refactor: record who started a workflow run as a subject

Stores id, type and name instead of a user foreign key, so an agent can start a run
without a data migration and the name survives the user being deleted.

* fix: record who started a test run that waits for its event

The starter is kept on the workflow with the other test state, so the event that
starts the run later can still name them.

* fix: forget a test run's starter when its window closes

Opening or closing the test run window through a workflow update left the earlier
starter in place, so a later run could name the wrong person.

* fix: keep a test run's starter when undo restores an unchanged window

Undo and redo send every workflow field back, so only a real change to the test run
window may replace who started it.

* fix: reset a test run's starter type along with its id

* fix: return None from get_subject for subject types without a table

anonymous, user_source.user and builder_preview_actor have no manager, so the lookup raised AttributeError.

* refactor: resolve collaborator names through a core util

The history panel called a mixin method without its component, which only worked while the method ignored this.

* refactor: name the history's started-by line after what it shows

* docs: note that a button with no actions logs no click

* refactor: drop the unused triggered_by from the automation dispatch context

Left over from when the clicker was the context's actor; the history already records who started the run.
)

`sendMessage` only guarded against a missing `currentChatId`, not against
`currentChatId` pointing at a chat absent from `state.chats`. The chat was
then passed into mutations that dereference it, so the commit threw and the
send was aborted with no feedback — the user's message was silently lost.

`SET_CHATS` is how the store got there: a chat created client-side is only
persisted once its first message is sent, so replacing the list with the
fetched one dropped it while `currentChatId` still pointed at it.

Keep the unsaved chat across a fetch, re-create it in `sendMessage` when the
lookup misses, and fix `REMOVE_CHAT` to match on `id` like every other lookup
rather than a `uid` that is never set.

Closes #6094
* fix(database): keep many to many value order when updating a row

RowHandler.update_row_by_id wrote m2m values with Django's `set`, which bulk
creates the through rows while iterating a Python set. The rows therefore
landed in hash bucket order rather than the order they were given, so a
multiple select cell written as [A, B] could read back as [B, A]. Around one
in eight consecutive id pairs reverses, which also made sorting on multiple
select and link row fields non-deterministic, since their `get_order`
aggregates on the through row id to follow insertion order.

Replaces `set` with the delete-then-ordered-bulk_create that `update_rows`
already uses, reusing _prepare_m2m_field_related_objects so self-referencing
link rows keep working, and invalidating the prefetch cache the way `set`
does so row history and undo/redo do not read stale relations.

Closes #6091

* docs: describe the retained-relation behaviour accurately

* fix(database): route single row create and update through the bulk paths

create_row and update_row each carried their own copy of the write path,
including a bespoke _set_m2m_values_in_order helper added for the ordering
fix. They now delegate to force_create_rows and force_update_rows, so the
single row and bulk APIs share one implementation and cannot drift again.

This also fixes updating a row whose link field still points at a trashed
row. Related managers hide trashed rows while their through rows remain, so
re-inserting those links raised a unique violation; the bulk create now
matches Django's set() and ignores the conflict.

force_create_rows additionally collects dependant row updates for rows
changed by cascading field rules, which the single row path used to do on
its own.
@pull pull Bot locked and limited conversation to collaborators Sep 16, 2026
@pull pull Bot added the ⤵️ pull label Sep 16, 2026
@pull
pull Bot merged commit d5e91d4 into code:develop Sep 16, 2026
4 of 5 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants