Skip to content

Fix Control Center groups query and redesign V2 Activity Logs - #1708

Merged
Paul Lizer (paullizer) merged 3 commits into
paullizer-react-v2-uifrom
paullizer-control-center-activity-logs-ux
Oct 8, 2026
Merged

Paul Lizer (paullizer) merged 3 commits into
paullizer-react-v2-uifrom
paullizer-control-center-activity-logs-ux

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Summary

  • Groups load again in the V2 Control Center. GROUP is a reserved word in Cosmos SQL, so the dotted path c.group.group_id was a syntax error (HTTP 400). It broke the Groups list, the group details drawer, the Activity Logs group filter, every Activity Logs search (group.group_name was a search field) and the classic group activity timeline. The nested object is now read as c['group']. A functional test now scans all Control Center SQL (classic routes included, plus the generated Activity Logs queries) for reserved keywords used as dotted names or aliases, so this can't quietly come back. Legacy group documents with a malformed owner, members or name no longer fail the whole list.
  • Activity Logs is much less convoluted. The stacked filter panels are replaced by one row of filter pills (search, Date, Activity, Person, Workspace, + Add filter) with a slim, clickable trend strip under it, so the log rows show without scrolling. Times default to local time with a remembered UTC toggle.
  • People and workspaces show by name instead of ID, resolved on the server the way V1 did it (batched lookups behind a 5-minute cache). Clicking a person, activity type or workspace in a row filters by it, and a detail drawer brings over V1's per-type details. Search also matches people's names and emails.
  • Saved views live on the admin's account (views saved in a browser are imported once), and CSV export gains readable name and summary columns.

Screenshots (Chromium, mocked data from the UI test fixture):

Activity Logs overview

Person filter pill searching by name

Activity detail drawer

Worth a careful look:

  • Two new read-only lookup routes back the pill comboboxes: GET /api/v2/control-center/activity-logs/people?q= and GET /api/v2/control-center/activity-logs/workspaces?q=, both with @swagger_route, @login_required and @control_center_required('activity_logs'). The existing page, summary and export routes also return names now (presentation, filter_labels, type_catalog). A failed name or people lookup is logged and degrades to IDs instead of failing the page.
  • Filters are broader on purpose. The Person filter matches all nine fields where writers record who acted, so approvals and admin changes count. A specific group or public workspace matches every record that references it, whatever workspace type was stored (membership removals, role changes, user agreements, ownership approvals). People matched by a search widen the query but are not part of the paging cursor's scope.
  • CSV export keeps its first five columns and still ends with raw_json, but six readable columns (user_name, user_email, activity, summary, workspace_id, workspace_name) now sit before it, so raw_json moves from column 6 to column 12.
  • v2ActivityLogSavedViews and v2ActivityLogPrefs are added to the user settings allowlist. While settings are loading or failed, the Views menu hides saving and the saved list, so a save can't overwrite views it couldn't read.
  • The branch merges the latest paullizer-react-v2-ui (workflow hand-off card, 0.261.295) and bumps to 0.261.296. The only conflict was VERSION.

Linked issue

N/A (no issue was filed for this work).

Release Notes & Latest Features

  • New Feature
  • Bug Fix
  • UI Enhancement
  • Breaking Change
  • Internal only

Is this visible to end users?

  • Yes
  • No

Is this admin-facing (Admin Settings, governance, deployment, config)?

  • Yes
  • No

Should this become a Latest Feature card?

  • Yes
  • No
  • Already added

Screenshot needed for the card?

  • Yes
  • No
  • Attached

Version bump

  • application/single_app/config.py VERSION third segment bumped, or not needed because this is docs-only (0.261.295 to 0.261.296)
  • deployers/version.txt bumped, or not needed because deployers/ was not changed (deployers/ not changed)

Testing / validation

All run on the final head 284ebe681 (merged with paullizer-react-v2-ui at cd333de9d). Python commands used a venv with Flask 3.1.3 and Werkzeug 3.1.6.

  • python scripts/check_xss_sinks.py --base-sha cd333de9d --head-sha 284ebe681 <17 changed application files>: passed (17 files)
  • python scripts/check_broken_access_control.py --base-sha cd333de9d --head-sha 284ebe681 <6 changed application .py files>: passed (6 files)
  • python -m pytest functional_tests/test_v2_control_center_*.py functional_tests/test_v2_user_settings_*.py functional_tests/test_user_settings_allowlist_keys.py -q -p no:cacheprovider: 223 passed
  • python functional_tests/route_tests/test_route_blueprint_policy_inventory.py: 12/12 passed
  • python functional_tests/route_tests/test_route_unauthenticated_policy_contract.py: 7/7 passed
  • python functional_tests/route_tests/test_route_policy_test_coverage.py: 3/3 passed
  • python functional_tests/test_docs_app_surface_coverage.py: 7/7 passed
  • python functional_tests/test_docs_site_quality.py: 6/6 passed
  • npm run build in application/v2_ui (tsc -b && vite build): passed
  • python -m pytest test_v2_control_center_activity_logs.py test_v2_control_center_dashboard.py test_v2_control_center_data_health_removed.py test_v2_control_center_groups.py test_v2_control_center_public_workspaces.py test_v2_control_center_users.py -q -p no:cacheprovider --browser chromium (from ui_tests/, after the build): 37 passed
  • Regression check (manual): the new UI tests for the search box keeping a trailing space and for relative date ranges after UTC midnight fail with those fixes reverted.
  • Manual: reviewed the page in Chromium at desktop (light and dark) and mobile widths, including the pill popovers, the filtered state and the detail drawer.
  • Known unrelated failure: python -m pytest functional_tests/test_v2_admin_settings_rail_collapse.py -q -p no:cacheprovider gives 1 failed, 3 passed both here and on the target tip cd333de9d. It asserts disabled={delegationDirty} in the admin settings rail, which this PR doesn't touch.

Documentation

  • Release notes updated, or not needed (not yet; a 0.261.296 entry still needs to be added)
  • Feature documentation updated, or not needed (docs/explanation/features/V2_CONTROL_CENTER.md, docs/guides/v2-control-center.md)
  • Fix documentation updated, or not needed (new docs/explanation/fixes/V2_CONTROL_CENTER_RESERVED_KEYWORD_QUERY_FIX.md, follow-up note in V2_CONTROL_CENTER_COSMOS_QUERY_COMPATIBILITY_FIX.md)

Security checklist

  • New Flask routes include @swagger_route(security=get_auth_security())
  • Settings sent to non-admin frontends use sanitize_settings_for_user() (no app settings are returned by the new or changed routes)
  • Browser JavaScript is served from local SimpleChat static assets only; no CDN-hosted JS
  • No secrets, keys, connection strings, or local-only artifacts are included

Paul Lizer (paullizer) and others added 3 commits October 7, 2026 20:10
GROUP is a reserved Cosmos SQL keyword, so dotted access such as
c.group.group_id returned HTTP 400 and broke the V2 groups inventory,
the group detail drawer, the Activity Logs group filter, every Activity
Logs search (group.group_name was a search field) and the classic group
activity timeline. Group paths are now bracket-quoted (c['group']) and
the Cosmos query guard rejects dotted access to reserved keywords across
all Control Center SQL. The groups inventory also tolerates malformed
legacy group documents.

Activity Logs now uses an Azure-portal-style filter pill bar, a slim
clickable trend strip and a log table that shows people and workspace
names (resolved server-side, cached and batched) instead of raw IDs.
People, activity types and workspaces cross-filter in one click; a
detail drawer ports V1's per-type details. Search also matches people
names and emails. Times show in local time with a remembered UTC
toggle. Saved views move to the account (one-time import from this
browser). CSV export adds readable name and summary columns. New
people and workspace lookup routes back the pill comboboxes.

Version 0.261.294.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…s UX branch

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The V2 branch moved to 0.261.295 (workflow hand-off card), so this
change and its docs and tests move from 0.261.294 to 0.261.296.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit fe9ea87 into paullizer-react-v2-ui Oct 8, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant