From 2f6f391cb2bf9791732bf299db228c89647447b0 Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Mon, 17 Aug 2026 17:22:34 -0400 Subject: [PATCH] Reorder workspace sections into a consistent order of operations Workspace sections were ordered differently on every surface that listed them, and none of those orders communicated how the pieces relate. Adopt a single canonical order across the tab strip, the collapsed Section dropdown, and the left-hand sidebar submenus: Documents, Prompts, Identities, Sync, Endpoints, Actions, Agents, Workflows Each section depends on the ones before it, so the list now reads as how a workspace is actually built up: Identities feed both Sync and Actions, Endpoints feed Actions and Agents, Agents assemble everything, and Workflows run Agents. Sections still appear only when their existing feature gates are enabled. Moving Actions ahead of Agents and Endpoints ahead of both required unwinding nested Jinja conditionals while preserving identical effective conditions. Tab panes are deliberately not reordered: Bootstrap resolves panes by id and hides inactive ones, so pane DOM order has no visual or accessibility effect, and leaving them keeps the diff reviewable. Public workspaces already satisfied the canonical relative order and are unchanged. Also fixes sidebar navigation gating that could surface links to tabs that were never rendered: - Add the missing Group Workflows sidebar link, which left group workflows unreachable from the left-hand navigation. - Personal Agents and Actions links now respect allow_user_agents and allow_user_plugins. - Group Agents and Actions links now respect per_user_semantic_kernel and allow_group_plugins. - Both Identities links now match their tab's File Sync and Semantic Kernel conditions. Validation: - New test_workspace_section_order.py renders all six section lists with Jinja and asserts the canonical order, that disabled features only remove sections, and that all three surfaces stay in gating lockstep across every combination of the eight relevant feature flags per scope. Verified to fail against the pre-change templates. - test_endpoints_tab_order_visibility.py updated for Endpoints then Actions then Agents; pane assertions reduced to presence-only. - All 74 functional tests referencing the edited templates produce an identical failure set to the merge-base baseline, so no regressions. - All 50 templates parse cleanly through Jinja. Refs #1255 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- application/single_app/config.py | 2 +- .../single_app/templates/_sidebar_nav.html | 79 ++-- .../templates/group_workspaces.html | 104 ++--- .../single_app/templates/workspace.html | 104 ++--- docs/explanation/features/index.md | 1 + .../v0.250.211/WORKSPACE_SECTION_ORDER.md | 174 ++++++++ docs/explanation/release_notes.md | 22 + .../test_endpoints_tab_order_visibility.py | 43 +- .../test_workspace_section_order.py | 404 ++++++++++++++++++ 9 files changed, 773 insertions(+), 160 deletions(-) create mode 100644 docs/explanation/features/v0.250.211/WORKSPACE_SECTION_ORDER.md create mode 100644 functional_tests/test_workspace_section_order.py diff --git a/application/single_app/config.py b/application/single_app/config.py index 657017bd0..bc094a2aa 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -96,7 +96,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.250.210" +VERSION = "0.250.211" IS_DEVELOPMENT = is_development_env_enabled() SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax') diff --git a/application/single_app/templates/_sidebar_nav.html b/application/single_app/templates/_sidebar_nav.html index a19406c23..96e89d150 100644 --- a/application/single_app/templates/_sidebar_nav.html +++ b/application/single_app/templates/_sidebar_nav.html @@ -120,7 +120,7 @@ - {% if sidebar_settings.allow_user_workflows %} + {% if file_sync_enabled or sidebar_settings.enable_semantic_kernel %} {% endif %} - {% if sidebar_settings.per_user_semantic_kernel and sidebar_settings.enable_semantic_kernel %} - + {% if file_sync_enabled %} {% endif %} @@ -161,24 +156,31 @@ {% endif %} - {% if file_sync_enabled %} + {% if sidebar_settings.per_user_semantic_kernel and sidebar_settings.enable_semantic_kernel and sidebar_settings.allow_user_agents %} + {% if sidebar_settings.allow_user_plugins %} {% endif %} - {% if file_sync_enabled or sidebar_settings.enable_semantic_kernel or sidebar_settings.enable_multi_model_endpoints %} + {% endif %} + {% if sidebar_settings.allow_user_workflows %} + {% endif %} {% else %} - + Personal {% endif %} @@ -188,7 +190,7 @@ - {% if sidebar_settings.allow_group_agents and sidebar_settings.enable_semantic_kernel %} - + {% endif %} + {% if file_sync_enabled %} {% endif %} @@ -222,24 +226,31 @@ {% endif %} - {% if file_sync_enabled %} + {% if sidebar_settings.per_user_semantic_kernel and sidebar_settings.enable_semantic_kernel and sidebar_settings.allow_group_agents %} + {% if sidebar_settings.allow_group_plugins %} + + {% endif %} {% endif %} - {% if file_sync_enabled or sidebar_settings.enable_semantic_kernel or sidebar_settings.enable_multi_model_endpoints %} - {% endif %} {% else %} - + Groups {% endif %} diff --git a/application/single_app/templates/group_workspaces.html b/application/single_app/templates/group_workspaces.html index 6fbffd10f..017374ca0 100644 --- a/application/single_app/templates/group_workspaces.html +++ b/application/single_app/templates/group_workspaces.html @@ -491,26 +491,26 @@

No active group selected

@@ -533,23 +533,21 @@

No active group selected

Documents - {% if file_sync_enabled %} - {% endif %} {% if group_workspace_identities_enabled %} {% endif %} + {% if file_sync_enabled %} - {% if settings.allow_group_workflows %} - {% endif %} {% if settings.per_user_semantic_kernel and settings.enable_semantic_kernel %} - {% if settings.allow_group_agents %} + {% if settings.enable_semantic_kernel and settings.allow_group_custom_endpoints and settings.enable_multi_model_endpoints %} - + {% endif %} + {% if settings.allow_group_agents %} {% if settings.enable_semantic_kernel and settings.allow_group_plugins %} {% endif %} - {% endif %} - {% if settings.enable_semantic_kernel and settings.allow_group_custom_endpoints and settings.enable_multi_model_endpoints %} + {% endif %} {% endif %} + {% if settings.allow_group_workflows %} + + {% endif %} diff --git a/application/single_app/templates/workspace.html b/application/single_app/templates/workspace.html index 8e39062f8..e4f72124e 100644 --- a/application/single_app/templates/workspace.html +++ b/application/single_app/templates/workspace.html @@ -604,27 +604,27 @@

Personal Workspace

@@ -646,23 +646,21 @@

Personal Workspace

Documents - {% if file_sync_enabled %} - {% endif %} {% if workspace_identities_enabled %} {% endif %} + {% if file_sync_enabled %} + {% endif %} + {% if settings.allow_user_custom_endpoints and settings.enable_multi_model_endpoints %} + + {% endif %} {% if settings.per_user_semantic_kernel and settings.enable_semantic_kernel %} {% if settings.allow_user_agents %} - - {% if settings.allow_user_plugins %} {% endif %} + + {% endif %} {% endif %} {% if settings.allow_user_workflows %} @@ -749,23 +766,6 @@

Personal Workspace

{% endif %} - {% if settings.allow_user_custom_endpoints and settings.enable_multi_model_endpoints %} - - {% endif %} diff --git a/docs/explanation/features/index.md b/docs/explanation/features/index.md index 9c2512908..66720f2f2 100644 --- a/docs/explanation/features/index.md +++ b/docs/explanation/features/index.md @@ -47,6 +47,7 @@ category: Version History - [Data Management Durable Backup Jobs](DATA_MANAGEMENT_BACKUP_MIGRATION.md) - [Data Management Migration Resilience](DATA_MANAGEMENT_MIGRATION_RESILIENCE.md) - [Migration Provenance](MIGRATION_PROVENANCE.md) +- [Workspace Section Order](v0.250.211/WORKSPACE_SECTION_ORDER.md) - [Microsoft Teams App SSO](v0.242.072/TEAMS_APP_SSO.md) - [Tabular SK Large Result Pagination](v0.242.067/TABULAR_SK_LARGE_RESULT_PAGINATION.md) - [Model Endpoint Model Icon Picker](v0.242.060/MODEL_ENDPOINT_MODEL_ICON_PICKER.md) diff --git a/docs/explanation/features/v0.250.211/WORKSPACE_SECTION_ORDER.md b/docs/explanation/features/v0.250.211/WORKSPACE_SECTION_ORDER.md new file mode 100644 index 000000000..d349d57c4 --- /dev/null +++ b/docs/explanation/features/v0.250.211/WORKSPACE_SECTION_ORDER.md @@ -0,0 +1,174 @@ +# Workspace Section Order + +## Overview + +Workspace sections now render in a single canonical order of operations across every surface +that lists them. Previously each surface used its own ordering, which made it hard for users and +admins to see how the pieces relate — that Identities feed both Sync and Actions, that Actions +belong to Agents, and that Workflows consume Agents. + +- **Version implemented:** 0.250.211 +- **Related issue:** [#1255](https://github.com/microsoft/simplechat/issues/1255) +- **Dependencies:** none — this change is presentation-only and adds no new settings + +## Canonical order + +Sections still appear only when their existing feature gates are enabled. When a section is +enabled it always appears in this position relative to the others: + +| # | Section | Why it sits here | +|---|---------|------------------| +| 1 | **Documents** | The knowledge you bring into the workspace | +| 2 | **Prompts** | The instructions you reuse against that knowledge | +| 3 | **Identities** | The credentials both Sync and Actions resolve against | +| 4 | **Sync** | Uses Identities to pull Documents in automatically | +| 5 | **Endpoints** | The models that Actions, Agents, and Workflows run on | +| 6 | **Actions** | Governed tools, built on Identities and Endpoints | +| 7 | **Agents** | Assemble Documents, Prompts, Actions, and Endpoints | +| 8 | **Workflows** | Run Agents manually, on a schedule, or on a trigger | + +Each entry depends on the ones above it, so reading the tab strip left to right now describes how +a workspace is actually built up. + +## Architecture + +### Surfaces kept in sync + +Three separate surfaces list workspace sections, and all three now use the canonical order: + +| Surface | Personal | Group | +|---------|----------|-------| +| Top `nav-tabs` bar | `#workspaceTab` in `templates/workspace.html` | `#groupWorkspaceTab` in `templates/group_workspaces.html` | +| Collapsed/mobile **Section** dropdown | `#workspace-section-select` | `#group-workspace-section-select` | +| Left-hand sidebar submenu | `#personal-workspace-submenu` in `templates/_sidebar_nav.html` | `#group-workspace-submenu` in `templates/_sidebar_nav.html` | + +`static/js/workspace_section_switcher.js` maps the dropdown's option values onto tab button ids, +so the dropdown and the tab strip must be edited together — the switcher does not derive one from +the other. + +### Public workspaces + +Public workspaces already satisfied the canonical relative order and were left unchanged: + +- `templates/public_workspaces.html` lists **Documents** then **Prompts**. +- `templates/manage_public_workspace.html` lists **Identities** before **Sync** among its + management tabs (General, Membership, Stats, Identities, Sync, Settings). + +### Tab panes are deliberately not reordered + +Bootstrap resolves tab panes by `id` / `data-bs-target`, and inactive panes are hidden, so pane +DOM order has no visual or accessibility effect. Panes were left in place to keep the change +reviewable — `group_workspaces.html` alone is roughly 389 KB. + +### Gate restructuring + +Moving Actions ahead of Agents, and Endpoints ahead of both, required unwinding nested Jinja +conditionals without changing their effective conditions. For example, the personal workspace +Actions tab was nested inside the Agents gate: + +```jinja +{% if settings.per_user_semantic_kernel and settings.enable_semantic_kernel %} + {% if settings.allow_user_agents %} + {% if settings.allow_user_plugins %} + {# Actions #} + {% endif %} + {# Agents #} + {% endif %} +{% endif %} +``` + +Actions still requires `per_user_semantic_kernel`, `enable_semantic_kernel`, `allow_user_agents`, +and `allow_user_plugins` — only its render position changed. + +## Navigation gating fixes + +The sidebar previously used gates that did not match the tabs they linked to, so a sidebar link +could point at a tab that was never rendered. Those gates are now aligned: + +| Navigation item | Previous gate | Corrected gate | +|-----------------|---------------|----------------| +| Personal → Your Agents | `per_user_semantic_kernel and enable_semantic_kernel` | added `allow_user_agents` | +| Personal → Your Actions | `per_user_semantic_kernel and enable_semantic_kernel` | added `allow_user_agents and allow_user_plugins` | +| Personal → Identities | `file_sync_enabled or enable_semantic_kernel or enable_multi_model_endpoints` | `file_sync_enabled or enable_semantic_kernel` | +| Group → Group Agents | `allow_group_agents and enable_semantic_kernel` | added `per_user_semantic_kernel` | +| Group → Group Actions | `allow_group_agents and enable_semantic_kernel` | added `per_user_semantic_kernel and allow_group_plugins` | +| Group → Identities | `file_sync_enabled or enable_semantic_kernel or enable_multi_model_endpoints` | `file_sync_enabled or enable_semantic_kernel` | +| Group → Group Workflows | *link did not exist* | added, gated by `allow_group_workflows` | + +The group sidebar had no Workflows entry at all even though the group Workflows tab has shipped +for some time, so group workflows were unreachable from the left-hand navigation. + +## Configuration + +No new configuration. The sections that appear continue to be controlled by the existing settings: + +| Section | Personal gate | Group gate | +|---------|---------------|------------| +| Documents | always | always | +| Prompts | always | always | +| Identities | `enable_file_sync*` or `enable_semantic_kernel` | `enable_file_sync*` or `enable_semantic_kernel` | +| Sync | `enable_file_sync*` | `enable_file_sync*` | +| Endpoints | `allow_user_custom_endpoints` + `enable_multi_model_endpoints` | `per_user_semantic_kernel` + `enable_semantic_kernel` + `allow_group_custom_endpoints` + `enable_multi_model_endpoints` | +| Actions | `per_user_semantic_kernel` + `enable_semantic_kernel` + `allow_user_agents` + `allow_user_plugins` | `per_user_semantic_kernel` + `enable_semantic_kernel` + `allow_group_agents` + `allow_group_plugins` | +| Agents | `per_user_semantic_kernel` + `enable_semantic_kernel` + `allow_user_agents` | `per_user_semantic_kernel` + `enable_semantic_kernel` + `allow_group_agents` | +| Workflows | `allow_user_workflows` | `allow_group_workflows` | + +`enable_file_sync*` is the resolved per-scope File Sync availability computed by +`is_file_sync_enabled_for_user` / `is_file_sync_enabled_for_group`. + +## File structure + +| File | Change | +|------|--------| +| `application/single_app/templates/workspace.html` | Reordered `#workspaceTab` and `#workspace-section-select` | +| `application/single_app/templates/group_workspaces.html` | Reordered `#groupWorkspaceTab` and `#group-workspace-section-select` | +| `application/single_app/templates/_sidebar_nav.html` | Reordered both submenus, added the group Workflows link, aligned gates, refreshed parent tooltips | +| `application/single_app/config.py` | `VERSION` bumped to `0.250.211` | +| `functional_tests/test_workspace_section_order.py` | New coverage for the canonical order and gating parity | +| `functional_tests/test_endpoints_tab_order_visibility.py` | Updated for the new Endpoints → Actions → Agents order | + +## Usage + +Nothing to enable. Users see the new order the next time they open a workspace page. Sections that +an admin has disabled remain hidden, and the remaining sections close up while preserving their +relative positions. + +## Testing and validation + +`functional_tests/test_workspace_section_order.py` renders each of the six section lists in +isolation with Jinja and checks: + +1. **Canonical order when everything is enabled** — all six surfaces render exactly the eight + sections in the canonical order. +2. **Disabled features only remove sections** — every combination of the eight relevant feature + flags (256 per scope) still yields a subsequence of the canonical order, with no duplicates and + with Documents and Prompts always leading. +3. **Gating lockstep** — for every flag combination, the tab strip, the Section dropdown, and the + sidebar submenu expose an identical set of sections. This is what guards the navigation gating + fixes above. +4. **Permission markers survive** — the permission-aware group Identities markers + (`data-group-identities-tab-nav`, `data-group-identities-sidebar-nav`, + `data-group-identities-section-option`) are still present after the reordering. +5. **Public workspaces** — Documents precedes Prompts, and Identities precedes Sync on the manage + page. + +The test was verified against the pre-change templates and fails there, confirming it is not +vacuous. + +### Known limitations + +- Tab pane DOM order still reflects the historical ordering. This is intentional and has no user + impact, but it means pane order and tab order no longer visually correspond when reading the + template source. +- The personal workspace guided tutorial (`static/js/workspace/workspace-tutorial.js`) still walks + Documents → Prompts → Agents → Actions. Its selectors are id-based so it functions correctly, + but its narrative sequence no longer mirrors the tab order. +- Section grouping (dividers or group labels such as Content / Connections / Automation) is a + possible follow-up; this change establishes the ordering those groups would build on. + +## Related documentation + +- `docs/explanation/fixes/v0.241.001/ENDPOINTS_TAB_ORDER_VISIBILITY_FIX.md` — earlier work that + introduced the endpoints tab gating this change reorders +- `docs/explanation/features/v0.229.001/LEFT_HAND_NAVIGATION_MENU.md` — the left-hand navigation + this change keeps in sync with the tab strip diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index 6fd25b120..9b7490e80 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -2,6 +2,28 @@ For feature-focused and fix-focused drill-downs by version, see [Features by Version](/explanation/features/) and [Fixes by Version](/explanation/fixes/). +### **(v0.250.211)** + +#### User Interface Enhancements + +* **Consistent Workspace Section Order** + * Workspace sections now follow a single order of operations everywhere they are listed: Documents, Prompts, Identities, Sync, Endpoints, Actions, Agents, Workflows. + * The order reflects how a workspace is actually built up, so it is clearer that Identities feed both Sync and Actions, that Actions belong to Agents, and that Workflows run Agents. + * Applied to the tab strip, the collapsed Section dropdown, and the left-hand sidebar submenus for personal and group workspaces. Public workspaces already matched this order and were left unchanged. + * Sections that an admin has disabled stay hidden; the remaining sections simply close up while keeping their relative positions. + * (Ref: #1255, `workspace.html`, `group_workspaces.html`, `_sidebar_nav.html`, `WORKSPACE_SECTION_ORDER.md`) + +#### Bug Fixes + +* **Group Workflows Missing From Sidebar Navigation** + * Added the missing Group Workflows link to the left-hand group workspace submenu. Group workflows previously had a working tab but no way to reach it from the sidebar. + * (Ref: #1255, `_sidebar_nav.html`, group workflows navigation) + +* **Sidebar Links Pointing At Unrendered Workspace Tabs** + * Fixed left-hand navigation links whose visibility rules did not match the tabs they opened, so a link could appear for a section that was never rendered. + * Personal Agents and Actions links now respect the user agent and plugin permissions, group Agents and Actions links now respect per-user Semantic Kernel and group plugin permissions, and both Identities links now match their tab's File Sync and Semantic Kernel conditions. + * (Ref: #1255, `_sidebar_nav.html`, `test_workspace_section_order.py`) + ### **(v0.250.210)** #### Bug Fixes diff --git a/functional_tests/test_endpoints_tab_order_visibility.py b/functional_tests/test_endpoints_tab_order_visibility.py index cde0fd669..90eed4254 100644 --- a/functional_tests/test_endpoints_tab_order_visibility.py +++ b/functional_tests/test_endpoints_tab_order_visibility.py @@ -2,13 +2,20 @@ # test_endpoints_tab_order_visibility.py """ Functional test for workspace/group endpoints tab order and visibility. -Version: 0.239.197 +Version: 0.250.211 Implemented in: 0.239.197 +Reordered in: 0.250.211 This test ensures endpoints tabs only render when multi-endpoint management is enabled, the personal and group admin-controlled toggles stay hidden, and the admin multi-endpoint toggle is removed after migration while its script keeps the endpoint editor initialized. + +Since 0.250.211 the workspace sections follow a canonical order of operations +(Documents, Prompts, Identities, Sync, Endpoints, Actions, Agents, Workflows), so +Endpoints now renders ahead of Actions and Agents. Tab pane DOM order is +deliberately not asserted: Bootstrap resolves panes by id and hides inactive ones, +so pane order has no visual or accessibility effect. """ import os @@ -29,20 +36,17 @@ def read_file_text(file_path): def test_workspace_endpoints_tab_order_visibility(): content = read_file_text(WORKSPACE_TEMPLATE) - agents_idx = content.find('id="agents-tab-btn"') - actions_idx = content.find('id="plugins-tab-btn"') endpoints_idx = content.find('id="endpoints-tab-btn"') + actions_idx = content.find('id="plugins-tab-btn"') + agents_idx = content.find('id="agents-tab-btn"') - assert agents_idx != -1, "Agents tab button missing in workspace template." - assert actions_idx != -1, "Actions tab button missing in workspace template." assert endpoints_idx != -1, "Endpoints tab button missing in workspace template." - assert agents_idx < actions_idx < endpoints_idx, "Workspace tab order should be Agents -> Actions -> Endpoints." + assert actions_idx != -1, "Actions tab button missing in workspace template." + assert agents_idx != -1, "Agents tab button missing in workspace template." + assert endpoints_idx < actions_idx < agents_idx, "Workspace tab order should be Endpoints -> Actions -> Agents." - actions_pane_idx = content.find('id="plugins-tab"') - endpoints_pane_idx = content.find('id="endpoints-tab"') - assert actions_pane_idx != -1, "Actions tab pane missing in workspace template." - assert endpoints_pane_idx != -1, "Endpoints tab pane missing in workspace template." - assert actions_pane_idx < endpoints_pane_idx, "Endpoints tab pane should appear after actions pane." + assert content.find('id="plugins-tab"') != -1, "Actions tab pane missing in workspace template." + assert content.find('id="endpoints-tab"') != -1, "Endpoints tab pane missing in workspace template." expected_gate = "{% if settings.allow_user_custom_endpoints and settings.enable_multi_model_endpoints %}" assert content.count(expected_gate) >= 2, "Workspace endpoints tab button and pane should share the multi-endpoint gate." @@ -55,20 +59,17 @@ def test_workspace_endpoints_tab_order_visibility(): def test_group_endpoints_tab_order_visibility(): content = read_file_text(GROUP_TEMPLATE) - agents_idx = content.find('id="group-agents-tab-btn"') - actions_idx = content.find('id="group-plugins-tab-btn"') endpoints_idx = content.find('id="group-endpoints-tab-btn"') + actions_idx = content.find('id="group-plugins-tab-btn"') + agents_idx = content.find('id="group-agents-tab-btn"') - assert agents_idx != -1, "Group agents tab button missing in group workspace template." - assert actions_idx != -1, "Group actions tab button missing in group workspace template." assert endpoints_idx != -1, "Group endpoints tab button missing in group workspace template." - assert agents_idx < actions_idx < endpoints_idx, "Group tab order should be Agents -> Actions -> Endpoints." + assert actions_idx != -1, "Group actions tab button missing in group workspace template." + assert agents_idx != -1, "Group agents tab button missing in group workspace template." + assert endpoints_idx < actions_idx < agents_idx, "Group tab order should be Endpoints -> Actions -> Agents." - actions_pane_idx = content.find('id="group-plugins-tab"') - endpoints_pane_idx = content.find('id="group-endpoints-tab"') - assert actions_pane_idx != -1, "Group actions tab pane missing in group workspace template." - assert endpoints_pane_idx != -1, "Group endpoints tab pane missing in group workspace template." - assert actions_pane_idx < endpoints_pane_idx, "Group endpoints tab pane should appear after actions pane." + assert content.find('id="group-plugins-tab"') != -1, "Group actions tab pane missing in group workspace template." + assert content.find('id="group-endpoints-tab"') != -1, "Group endpoints tab pane missing in group workspace template." expected_gate = "{% if settings.enable_semantic_kernel and settings.allow_group_custom_endpoints and settings.enable_multi_model_endpoints %}" assert content.count(expected_gate) >= 2, "Group endpoints tab button and pane should share the multi-endpoint gate." diff --git a/functional_tests/test_workspace_section_order.py b/functional_tests/test_workspace_section_order.py new file mode 100644 index 000000000..272d5b173 --- /dev/null +++ b/functional_tests/test_workspace_section_order.py @@ -0,0 +1,404 @@ +#!/usr/bin/env python3 +# test_workspace_section_order.py +""" +Functional test for the canonical workspace section order. +Version: 0.250.211 +Implemented in: 0.250.211 + +This test ensures every surface that lists workspace sections renders them in the +canonical order of operations (Documents, Prompts, Identities, Sync, Endpoints, +Actions, Agents, Workflows), and that each surface shows exactly the same sections +for a given set of feature flags so a navigation link can never point at a tab that +was never rendered. +""" + +import itertools +import re +import traceback +from pathlib import Path + +from jinja2 import Environment + +from test_support.versioning import assert_app_version_at_least + +IMPLEMENTED_VERSION = "0.250.211" + +REPO_ROOT = Path(__file__).resolve().parents[1] +TEMPLATE_DIR = REPO_ROOT / "application" / "single_app" / "templates" +WORKSPACE_TEMPLATE = TEMPLATE_DIR / "workspace.html" +GROUP_TEMPLATE = TEMPLATE_DIR / "group_workspaces.html" +SIDEBAR_TEMPLATE = TEMPLATE_DIR / "_sidebar_nav.html" +PUBLIC_TEMPLATE = TEMPLATE_DIR / "public_workspaces.html" +MANAGE_PUBLIC_TEMPLATE = TEMPLATE_DIR / "manage_public_workspace.html" + +CANONICAL_ORDER = [ + "documents", + "prompts", + "identities", + "sync", + "endpoints", + "actions", + "agents", + "workflows", +] + +NAV_BUTTON_RE = re.compile(r'\bid="([a-z-]+-tab-btn)"') +SELECT_OPTION_RE = re.compile(r'