diff --git a/app/web/templates/admin_access.html b/app/web/templates/admin_access.html index 8b40650..16bc7d7 100644 --- a/app/web/templates/admin_access.html +++ b/app/web/templates/admin_access.html @@ -806,6 +806,9 @@ document.getElementById("resources-filter").addEventListener("input", e => { }); // Pre-select a group via ?group= deep-link from /admin/groups/{id}. +// Pre-filter to a table via #table: deep-link from /admin/tables's +// per-row Manage access button — drops the table_id into the resource +// filter so the operator sees just that row once they pick a group. async function bootstrap() { await loadOverview(); const params = new URLSearchParams(window.location.search); @@ -813,6 +816,22 @@ async function bootstrap() { if (target && state.groups.some(g => g.id === target)) { selectGroup(target); } + // Hash-based deep link, e.g. #table:in.c-sales.orders → pre-fill the + // resource filter with the table_id. The filter is name-substring based + // and tables come through with the table_id as their `name`, so this + // narrows the visible items to just the clicked row across all groups. + const hash = window.location.hash || ""; + if (hash.startsWith("#table:")) { + const tableId = decodeURIComponent(hash.slice("#table:".length)); + if (tableId) { + const filterEl = document.getElementById("resources-filter"); + if (filterEl) { + filterEl.value = tableId; + state.filter = tableId; + renderResources(); + } + } + } } bootstrap(); diff --git a/app/web/templates/admin_tables.html b/app/web/templates/admin_tables.html index 5373194..23635ae 100644 --- a/app/web/templates/admin_tables.html +++ b/app/web/templates/admin_tables.html @@ -511,24 +511,11 @@ white-space: nowrap; } - .registry-table .col-strategy { - white-space: nowrap; - } - .registry-table .col-actions { width: 80px; text-align: right; } - .strategy-badge { - font-size: 11px; - font-weight: 500; - padding: 2px 8px; - border-radius: 4px; - background: var(--border-light); - color: var(--text-secondary); - } - /* ── Modal overlay ── */ .modal-overlay { display: none; @@ -730,10 +717,46 @@ margin: 16px; } } + + /* ── Tab nav (Phase D) ── */ + .tab-nav { + display: flex; + gap: 4px; + border-bottom: 1px solid var(--border); + margin-bottom: 16px; + } + .tab { + padding: 8px 16px; + background: transparent; + border: 0; + cursor: pointer; + font-family: inherit; + font-size: inherit; + color: var(--text-secondary); + } + .tab[aria-selected="true"] { + border-bottom: 2px solid var(--primary); + color: var(--text-primary); + font-weight: 600; + } + .tab-content { + padding: 16px 0; + } + .tab-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; + } + .tab-actions { + display: flex; + justify-content: flex-end; + margin-bottom: 16px; + } {% include '_theme.html' %} - + {% include '_app_header.html' %} @@ -747,209 +770,629 @@
- {% if data_source_type == 'bigquery' %} - -
-
-
-
- - - - -
-
-
Register BigQuery Table
-
Manually register a BQ table or view as a remote DuckDB view
-
-
- -
-
- BigQuery dataset/table discovery lands in Milestone 2 of issue #108. For now, enter the dataset + table by hand. -
-
- {% else %} - -
-
-
-
- - - - -
-
-
Discover Tables
-
Scan your data source for available tables
-
-
- -
-
-
- Click "Discover tables from source" to scan for available tables -
-
-
- {% endif %} + {# Phase D: tab-split scaffold. Per-connector tabs (BigQuery / + Keboola / Jira) replace the single mixed form. Each tab has its + own Register button + listing div + (later) form modals. The + initial active tab matches data_source.type from instance.yaml; + the operator can still switch tabs to manage a secondary source. - -
-
-
-
- - - - - - - + Phase E moves the BQ form into #tab-content-bigquery; Phase F + builds the Keboola form inside #tab-content-keboola. For now + the existing Jinja-branched panels below stay in place. #} + {% set initial_tab = data_source_type if data_source_type in ['bigquery', 'keboola', 'jira'] else 'keboola' %} + + + +
+
+ +
+
+ + +
+ +
+
+ +
+
+ + + + + + +
+ +
+

Jira tables are populated by webhooks. + To register a new Jira webhook integration, see + docs/connectors/jira.md.

+
+
+ + {# Legacy out-of-tab panels (BQ Register card, Keboola Discovery card, + shared Registered Tables wrapper) removed — each tab now owns its + own header (with Register button) and listing div. The Refresh + action is implicit: registration / edit / delete flows already + call loadRegistry(), which re-renders all three per-tab listings. #}
- - - + {# C3: legacy #registerModal removed. The Phase E #registerBqModal + (inside #tab-content-bigquery) and Phase F #registerKeboolaModal + (inside #tab-content-keboola) own the Register flows now. The + data-source-type marker moved to so DATA_SOURCE_TYPE still + has somewhere to read from. #} - +