Login Dialog Label Filter
Table of Contents
Problem
The login dialog's saved-connections combo is a flat list that shows every server bookmark and every connection, making it hard to find what you need when there are many entries spanning different servers.
In practice a developer running from a local1 checkout is almost exclusively
interested in connections pointing at local1. The same concept applies to any
end-user context: a prod user wants prod connections, a barclays user wants
Barclays-tagged connections. Surfacing everything at once adds friction.
A second gap: there is no reliable signal telling the application which checkout it was started from, so no automatic pre-selection is possible.
Both problems share a root: connections and environments have no first-class label that the login dialog can filter on. The tag system already exists in the database; it just needs a filter surface in the dialog, auto-population at startup, and an env-var hook to pre-select the right label.
Terminology
| Term | Meaning |
|---|---|
| Environment | A server bookmark (host + port, no credentials). |
| Unchanged from current domain model. | |
| Connection | Saved credentials linked to an environment. |
| Tag / Label | An arbitrary string attached to environments. |
| Used here as the filter axis. | |
| Checkout label | The ORES_CHECKOUT_LABEL env var — identifies the current |
development checkout (e.g. local1, local2). |
The domain model (environment, connection, folder, tag) is not renamed or restructured in this story. The terminology clean-up proposed in the original plan (environment → instance, new tier concept) is deferred to a later story.
Current State
Database
The tags and environment_tags tables already exist. Typical content:
| tags | dev, local, acme, example |
| env tags | all environments tagged "dev" and "local" |
What is missing: each environment has no label identifying which checkout it
belongs to (e.g. local1, local2). There are no tags at that granularity.
ORES_CHECKOUT_LABEL
.env (generated by init-environment.sh) sets ORES_CHECKOUT_LABEL=local1.
The variable is already exported and available to child processes launched from
start-client.sh, but the Qt application does not currently read it.
Connection browser
Tags are already visible in the connection browser. The browser can be used to add or remove tags manually. This story automates the checkout-label tagging.
Login dialog
The quick-connect combo is a flat, unfiltered list. No filter control exists.
Design
Auto-tag environments at startup
When ORES_CHECKOUT_LABEL is set (e.g. local1), the application automatically
ensures that:
- A tag named
local1exists in thetagstable (created if absent). - Every environment whose
subject_prefixends with.local1is tagged withlocal1. The subject prefix format isores.{tier}.{instance}, so the last dot-separated component is the instance/checkout name.
This is idempotent — restarting the app with the same label is safe. It
requires a new connection_manager method:
/** * Ensure tag @p label exists and is applied to every environment whose * subject_prefix ends with ".{label}". No-op if @p label is empty. */ void auto_tag_environments_by_label(const std::string& label);
Login dialog filter combo
A Label filter row appears above the quick-connect combo:
Label: [ All ▼ ] ← hidden when fewer than 2 tags exist Quick connect: [ ── ▼ ]
Filter options: "All", then each tag sorted alphabetically. An entry appears only when at least one environment carries that tag.
When a label is selected:
- Environments section: only environments carrying that tag are shown.
- Connections section: only connections whose linked environment carries that tag are shown.
The filter is purely a narrowing control; it does not fill form fields.
QuickConnectItem additions
struct QuickConnectItem { enum class Type { Environment, Connection }; Type type; QString name; QString subtitle; // ── new ── QStringList tags; // tags on the linked environment };
MainWindow populates tags for each item by calling
get_tags_for_environment(environment_id) when building the combo list.
ORES_CHECKOUT_LABEL env-var pre-selection
MainWindow reads std::getenv("ORES_CHECKOUT_LABEL") after the connection
manager is initialised:
- Call
auto_tag_environments_by_label(label)to ensure the tag exists. - Call
login_dialog.setActiveLabel(QString::fromStdString(label))to pre-select the filter. - Store the label for display purposes (see window title, below).
If the variable is unset or empty, the filter defaults to "All" and no auto-tagging occurs.
Window label display
When a checkout label is active, append it in curly braces to the window title and toolbar (optional, can be done in the same or a follow-up PR):
ORE Studio v1.2.3 (no label)
ORE Studio v1.2.3 {local1} (ORES_CHECKOUT_LABEL=local1)
start-client.sh env-var check
After sourcing .env, the script checks that ORES_CHECKOUT_LABEL is set.
Because the variable was introduced in a specific version of
init-environment.sh, its absence signals a stale .env:
if [[ -z "${ORES_CHECKOUT_LABEL:-}" ]]; then echo "warning: ORES_CHECKOUT_LABEL is not set in .env" echo " Your .env may be out of date — consider re-running:" echo " ./build/scripts/init-environment.sh --preset <preset>" fi
The variable reaches ores.qt automatically via the exported environment; no
extra CLI flag is needed.
Non-goals
- Renaming
environment→instancein the domain model (deferred). - Introducing a first-class deployment-tier concept (deferred).
- Rebuilding the connection browser tree (deferred).
- Persisting the last-used filter across sessions.
- CLI flag for the label (the env var is sufficient; a flag can be added later).
Implementation
Item 1 — start-client.sh: add env-var check
File: build/scripts/start-client.sh.
After sourcing .env and resolving PRESET, warn if ORES_CHECKOUT_LABEL is
unset.
Item 2 — connection_manager: auto_tag_environments_by_label()
Files: connection_manager.hpp, connection_manager.cpp.
Implementation:
- If label is empty, return immediately.
- Call
get_tag_by_name(label); create tag if absent. - Call
get_all_environments(); for each environment whosesubject_prefixends with".{label}", calladd_tag_to_environment(env.id, tag.id)(no-op if already tagged).
Item 3 — QuickConnectItem: add tags field
File: LoginDialog.hpp.
Add QStringList tags to the struct.
Item 4 — MainWindow: populate tags and read env var
File: MainWindow.cpp.
- In the method that builds the quick-connect list, call
get_tags_for_environment()for each environment and populate thetagsfield. - After
initializeConnectionManager()succeeds, readORES_CHECKOUT_LABEL, callauto_tag_environments_by_label(), and pass the label to the login dialog.
Item 5 — LoginDialog: add filter combo
Files: LoginDialog.hpp, LoginDialog.cpp.
- Add
QLabel* labelFilterLabel_andQComboBox* labelFilterCombo_. - Both hidden when the tag list has fewer than 2 entries.
setActiveLabel(const QString& label)public method — selects the entry in the combo (or "All" if not found).onLabelFilterChanged()private slot — rebuilds the visible quick-connect list from the cached full list.- Full item list cached; visible list filtered in the slot.
Item 6 — Tests
Update service_connection_manager_tests.cpp with a test for
auto_tag_environments_by_label: create environments with known
subject_prefix values, call the method, verify tags are applied.