Round out the index discovery so the lazy toolbox boots against the full
shipping tool set:
- ``scripts/tool_source/_discover.py`` now handles ``<tool_dir>`` panel
entries and reads YAML tool ids alongside XML, so multi-version tool
directories and YAML tools land in the index.
- ``LazyToolBox`` extends the bootstrap path to register every variant
discovered for a single tool id (was previously dropping siblings) and
uses the shared YAML id reader when chasing direct ``<tool file=...>``
references from the panel config.
- ``DatabaseToolSourceStore.store_index`` accepts the richer per-id
payload from the discovery script.
Test coverage is extended in ``test_tool_source_storage`` to assert that
the bootstrapped index sees both directory-based and YAML-defined tools.
Wires populate_store.py and ``use_lazy_toolbox: true`` into the api
and integration GitHub Actions workflows so the LazyToolBox path is
exercised in CI alongside the default eager toolbox.
- doc/source/admin/tool_source_storage.rst: operator-facing guide
covering backend choice, populate_store usage, watch mode, and the
per-conf composite story.
- doc/source/dev/tool_source_storage.rst: developer-facing
architecture overview of the store, LazyToolBox, and the batch
endpoint integration.
End-to-end test that boots Galaxy through the composite store +
LazyToolBox path and verifies tools are discoverable via /api/tools,
covering the wiring exercised by all of the preceding commits.
Replaces ad-hoc iteration over ``app.toolbox`` in the
``/api/tools``, ``/api/tool_panels``, tests-summary, and
``/api/tools/all_requirements`` endpoints with service methods that
query the LazyToolBox pre-computed index when available, falling
back to the existing toolbox path otherwise. This converts the
batch endpoints from O(N tools) to O(1) when the lazy toolbox is in
use, without changing behavior for the default eager toolbox.
LazyToolBox extends ToolBox and loads each Tool on demand from the
configured tool source store, backed by an LRU cache sized via
``lazy_toolbox_cache_size``. The pre-computed index lets batch
endpoints (panels, tests summary, requirements) avoid materializing
every tool object.
- tools/lazy_toolbox.py: the on-demand toolbox plus its index cache
invalidation hook.
- tool_util/toolbox/base.py and parser.py: small extension points
needed for lazy loading.
- tools/__init__.py: helpers shared with LazyToolBox.
- queue_worker/__init__.py: route ``_get_new_toolbox`` through
LazyToolBox when opted in, and add the
``reload_tool_source_cache`` control message used by
populate_store --watch to invalidate caches across processes.
- app/__init__.py and galaxy_mock.py: build the tool source store at
app startup and use LazyToolBox when ``use_lazy_toolbox`` is set.
_remap_container saved the directive line while looping over the
container's lines, but then re-matched GALAXY_MARKDOWN_FUNCTION_CALL_LINE
against the loop variable holding the container's *last* line. For stored
report markdown that was never validated (e.g. an unclosed ```galaxy
fence swallowing following prose), the re-match returned None and the
subsequent assert produced an unhandled 500 on
GET /api/invocations/{invocation_id}/report.
Keep the match object found in the loop instead, and turn the assert on
a second directive within one block into MalformedContents so malformed
user content yields a 4xx rather than an AssertionError.
Fixes#23175
Fixes USEGALAXY-EU-MAIN-61HFG00001W43
Adds a router guard that prompts users to confirm navigation when unsaved changes exist. This stops accidental data loss in editors. Also standardizes early returns in access control logic for consistency.
Sequence.display_data set the text/plain content-type only on the
non-truncated preview branch. Sequences larger than the 100 KB peek
limit were returned without a content-type, so the browser fell back to
text/html: newlines collapsed and the header line ran into the sequence
(the "horrible" fasta preview). Serve text/plain for both branches.
Also stop dropping the final byte of small previews -- the read-ahead
byte that chunk[:-1] removes is only present when the content is
truncated.
Fixes#22719
JobSelection and DatasetCollectionElementPicker used b-collapse with
is-nav inside a non-toggleable b-navbar, so the collapse never actually
collapses: the navbar-expand class forces it visible at every width.
Replace it with a static div.navbar-collapse, which renders identically
(same computed layout) without bootstrap-vue's BCollapse.
Finishes the BCollapse removal started in #21958 (part of #21956).
GCollapse is not used here because nothing toggles; it targets real
collapsible sections, not navbar plumbing.
GTable's row checkbox emits a "row-select" event, but SelectionDialog only
handled "row-click" — so toggling a checkbox was dropped. Clicking a folder's
checkbox did nothing (it reverted to its indeterminate/prior state) while
clicking the row selected the whole directory, an inconsistent, broken-looking
result. Forward "row-select" to the same "onClick" emit so a checkbox toggle
drives identical selection to a row click for both files and folders.
The row/select-all checkbox is a Bootstrap custom-control: the visible box is
the (empty) label's ::before and the real input is visually hidden, both
defaulting to the arrow cursor. Clicking already worked via the label, but the
non-pointer cursor made the checkbox look unclickable except at its top edge
(where the cell showed through). Force a pointer cursor across the control.
Producers set only selectionState; the redundant per-item 'class' field and
the any-cast/hasClass derivation are gone. SelectionDialog derives both
selected and indeterminate (MIXED) row indices from selectionState, so
partially-selected folders now show an indeterminate checkbox instead of
being dropped. Remove the dead allSelected prop (GTable derives it) and the
redundant manual syncSelectedItems() calls, thread the select-all direction
through to producers, drop the unused cellClass field, and restore the
DataDialogSearch v-model. Tests use SELECTION_STATES constants and cover the
indeterminate case.
Add an optional indeterminateItems prop so a row's selection checkbox can
render as indeterminate (e.g. a folder with only some children selected),
and pass the new checkbox state through the select-all event so parents no
longer have to re-derive the toggle direction. Promote the previously local
TableItemClassMeta type to GTable.types.ts as the canonical shape.
The import-datasets-from-history selenium flow first opens a history
(a non-leaf row) before selecting datasets. Opening requires the row's
label cell, whose onOpen handler drills into the history; clicking the
bare row only fires onClick (dataset selection), so the datasets view
never appeared and the 'search datasets' step timed out.
Target the label cell (td[id^="g-table-cell-label-"]) for the by-index
selector, matching the pre-migration behaviour. Verified locally with
the headless selenium test_library_contents suite.
The BTable-to-GTable migration dropped BTable's per-row test hooks
(data-pk from primary-key, aria-rowindex), breaking selenium selectors
that pick rows by dataset id or by position across library contents,
page embeds, workflow run inputs and the upload rule builder.
Add an optional primaryKey prop to GTable that emits data-pk on each
row, plus a 1-based aria-rowindex. SelectionDialog passes primary-key=
"id". Update the import-datasets-by-index selector to aria-rowindex
(fixing an off-by-one vs GTable's 0-based row ids) and the by-id
selectors to tr[data-pk] (tr already has an implicit row role).
The selection dialog 'options_ready' selenium selector waits on
.selection-dialog-table[aria-busy="false"], previously provided by
BTable. GTable did not emit aria-busy, so FilesDialog-based flows
(e.g. history export to FTP) timed out. Reflect the loading prop as
aria-busy on the table container to restore that contract and improve
accessibility.
- Change the selector for the busy spinner in the selection dialog to use a data attribute for better specificity.
- Update the corresponding import dataset selector to match the new structure.
Update FilesDialog tests to assert the GTable header checkbox state instead of the removed SelectionDialog selectAllVariant prop.\n\nAdd SelectionDialog regression tests that verify select-all checked/indeterminate behavior from incoming item selection metadata.\n\nKeep selected row indices synchronized with incoming table items so select-all state remains correct after directory navigation and recursive selection updates.
- Removed computed property for selectAllIcon.
- Updated props for selection dialog to use allSelected directly.
- Enhanced clarity in the selection handling for datasets.
- Remove unused select icon field and related props.
- Rename props for clarity: selectAllVariant to selectable, showSelectIcon to allSelected.
- Implement syncSelectedItems function to manage selected items based on item classes and selection state.
- Update event handling for row clicks and select all actions to utilize syncSelectedItems.
- Updated the variable name from _rowVariant to selectionState for clarity.
- Added a class binding based on the selection state to enhance UI feedback.
- Updated the FilesDialog component to use 'selectionState' instead of '_rowVariant' for better clarity.
- Adjusted related test cases to reflect this change.
- Ensured consistent handling of selection states across the component.
- Change the icon selection logic to use selectionState instead of _rowVariant.
- Update SelectionItem interface to replace _rowVariant with selectionState.
- Ensure proper type imports for TableClassValue in selectionTypes.
- Introduced TableClassValue type for better class management in GTable.
- Updated TableField interface to use TableClassValue for class and cellClass properties.
- Modified GTable.vue to utilize new class handling for rows and cells.