fix(web): UI consistency — code tokens, label-qualifier, radio cards, Keboola edit-modal JS (#347)
* fix(web): UI consistency — code tokens, label-qualifier, radio card selected state
I-UI-01: Add .sync-option-card:has(input:checked) rule — border + background
feedback when a radio option card is selected. Add class sync-option-card to
all 14 radio label cards in admin_tables.html.
I-UI-02: Add .label-qualifier / .optional to style-custom.css. Remove the
duplicate local definition from admin_tables.html <style> block.
I-UI-03: Migrate inline code rule to design tokens (--font-mono, --text-sm,
--border-light, --border, --radius-sm). Add background + border so inline
code is visually distinct across all pages.
I-UI-05 (partial): Replace hardcoded #c4c4c4 / #fafafa in .btn-google:hover
with var(--border) / var(--background) so theme overrides apply.
* fix(web): expose entire Keboola edit-modal JS to all instance types
openEditKeboolaModal, closeEditKeboolaModal, saveKeboolaTabEdit,
onEditKbStrategyChange and helpers were still inside {% if keboola %}
but called from always-rendered HTML (openEditModal dispatcher,
Escape key handler, modal overlay click, Cancel/Save buttons).
Removed the Phase F2 if-guard entirely — only prefillFromKeboolaTable
stays conditional (its callers are inside {% if keboola %} HTML blocks).
* fix(ui): promote .form-textarea to global CSS with design tokens
Removes the local hardcoded .form-textarea definition from admin_tables.html
and adds it globally to style-custom.css using design tokens, making
description textareas visually consistent with other form fields.
* fix(ui): restore .form-textarea to local style block for visual consistency
Tokens --text-sm (12px) and --radius-md (6px) differ from the local override
values (13px, 8px) used by .form-input on this page, causing a visible mismatch.
.form-textarea rejoins the shared local selector so all three classes render
identically; global .form-textarea in style-custom.css remains as a baseline
for other pages.
* fix(ui): use textarea.form-textarea in global CSS to override .form-group textarea
.form-group textarea (specificity 0,1,1) was overriding .form-textarea (0,1,0)
with a legacy monospace font and different padding. Raising the selector to
textarea.form-textarea matches specificity and wins via source order, making
description textareas consistent with other form inputs. Local admin_tables.html
overrides for .form-textarea removed — styling now comes entirely from global CSS.
* fix(ui): add border:none to .code-block code + add CHANGELOG entries
Fixes light-gray border leaking into dark .code-block backgrounds.
Adds required CHANGELOG.md entries for all user-visible changes in this PR.
* fix(ui): add --border-dark token + reset border-radius in .code-block code
- Adds --border-dark: #C4C4C4 design token for hover border states
- Uses var(--border-dark) in both .btn-google:hover rules so hover border
is visually distinct from the base border (was a no-op with var(--border))
- Adds border-radius: 0 to .code-block code override to fully reset the
new global code border-radius on dark code-block backgrounds
* fix(ui): reset code border/bg inside .use-case-prompt dark container
Adds .plugin-detail .use-case-prompt code override to prevent the new
global code border and background from leaking into the dark #1e1e2e
pre block in marketplace_plugin_detail.html.
* fix(ui): reset code border in all dark-background containers
Global code { border } leaks into dark-themed containers across templates.
Adds border: none (+ border-radius: 0 where needed) to:
- marketplace_plugin_detail.html: lead-rendered pre code, sample-assistant-body code/pre code
- marketplace_item_detail.html: same three selectors
- home_onboarded.html, home_not_onboarded.html, admin_welcome.html: inline code on hero dark backgrounds
* fix(ui): uniform form typography — chip-input font, data-package desc textarea, orphan endif
- .chip-input container gets font-family/size tokens so inner input
inherits correctly (inline `font: inherit` was pulling browser default)
- cdp-desc / edp-desc switched from form-input to form-textarea so
description fields render Inter, not monospace
- Removed orphan {% endif %} left in admin_tables.html after rebase
(caused TemplateSyntaxError breaking all admin-tables tests in CI)
- .item-detail .use-case-prompt code: border/bg reset for dark container
* fix: relax test_keboola_discover_buttons assertion + CHANGELOG bullet for #347
The test_keboola_discover_buttons_hidden_on_bigquery_instance test
asserted bare-string `prefillFromKeboolaTable` not in the rendered
HTML on a non-Keboola instance. That made sense when the function
DEFINITION lived behind the keboola Jinja guard. #347 moves
several Keboola edit-modal helpers out from under the guard so
they're now defined as dead code on every instance, but the actual
call sites (`onclick="prefillFromKeboolaTable(...)"` + the
Discover buttons themselves) still respect the guard — which is
what actually matters for runtime behavior.
Updated the assertions to match `onclick="<fn>(` so they pin the
call-site contract, not the function-definition substring.
---------
Co-authored-by: ZdenekSrotyr <zdenek.srotyr@keboola.com>
This commit is contained in:
parent
318802854c
commit
caae12d02f
9 changed files with 113 additions and 53 deletions
|
|
@ -11,6 +11,7 @@ CalVer image tags (`stable-YYYY.MM.N`, `dev-YYYY.MM.N`) are produced for every C
|
|||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **UI consistency pass** (I-UI-01..05): radio-card selected state on `/admin/tables` (14 cards get blue border + light bg highlight via `.sync-option-card:has(input:checked)`); promoted `.label-qualifier` / `.optional` to global rule (drops local duplicate); inline `<code>` migrated to design tokens with bg + border; `.btn-google` hover hardcoded swatches replaced with vars; `.code-block code` border + radius reset for dark containers; `.form-textarea` promoted to global. Plus #340 follow-up: removed leftover Phase F2 `{% if data_source_type == 'keboola' %}` guard around edit-modal JS so handlers ship to every instance type (Discover button onclick call sites still respect the guard). Closes #347 (credit @MonikaFeigler).
|
||||
- `agnes refresh-marketplace` (non-bootstrap path) now re-applies
|
||||
`chmod +x` to every `.sh` under `~/.agnes/marketplace` after each
|
||||
`git reset --hard FETCH_HEAD`, not just on the initial bootstrap
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
--surface: #FFFFFF;
|
||||
--border: #E5E7EB;
|
||||
--border-light: #F3F4F6;
|
||||
--border-dark: #C4C4C4;
|
||||
--success: #10B77F;
|
||||
--warning: #F59F0A;
|
||||
--error: #EA580C;
|
||||
|
|
@ -254,8 +255,8 @@ nav {
|
|||
|
||||
.btn-google:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
border-color: #c4c4c4;
|
||||
background-color: #fafafa;
|
||||
border-color: var(--border-dark);
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.btn-google:active {
|
||||
|
|
@ -386,10 +387,28 @@ nav {
|
|||
|
||||
/* Code blocks */
|
||||
code {
|
||||
font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", monospace;
|
||||
font-size: 0.875rem;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-sm);
|
||||
background: var(--border-light);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1px var(--space-1);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Label qualifiers — optional, default, hint text next to form labels */
|
||||
.label-qualifier,
|
||||
.optional {
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--font-normal);
|
||||
color: var(--text-secondary);
|
||||
margin-left: var(--space-1);
|
||||
}
|
||||
|
||||
/* Radio option cards — visual selected state */
|
||||
.sync-option-card:has(input:checked) {
|
||||
border-color: var(--primary) !important;
|
||||
background: var(--primary-light) !important;
|
||||
}
|
||||
|
||||
.code-block {
|
||||
|
|
@ -405,6 +424,8 @@ code {
|
|||
.code-block code,
|
||||
.code-block pre {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
font-size: 0.8125rem;
|
||||
color: inherit;
|
||||
|
|
@ -2885,8 +2906,8 @@ a.slack-badge:hover {
|
|||
|
||||
.login-page .btn-google:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
border-color: #c4c4c4;
|
||||
background-color: #fafafa;
|
||||
border-color: var(--border-dark);
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.login-page .btn-google:active {
|
||||
|
|
@ -3970,6 +3991,29 @@ textarea.form-input {
|
|||
line-height: 1.5;
|
||||
}
|
||||
|
||||
textarea.form-textarea {
|
||||
width: 100%;
|
||||
min-height: 80px;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
font-family: var(--font-primary);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-primary);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
resize: vertical;
|
||||
line-height: normal;
|
||||
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
|
||||
}
|
||||
|
||||
textarea.form-textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
|
||||
textarea.form-textarea::placeholder { color: var(--text-muted); }
|
||||
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
|
|
@ -3978,6 +4022,14 @@ textarea.form-input {
|
|||
|
||||
.form-input::placeholder { color: var(--text-muted); }
|
||||
|
||||
/* chip-input widget — set font on the container so the inner input's
|
||||
`font: inherit` inline style picks up the right value */
|
||||
.chip-input {
|
||||
font-family: var(--font-primary);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* =====================================================
|
||||
Page-header primitive (Task 6)
|
||||
.page-header + __main / __title / __subtitle / __actions / __eyebrow
|
||||
|
|
|
|||
|
|
@ -727,15 +727,8 @@
|
|||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-label .optional {
|
||||
font-weight: 400;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-input,
|
||||
.form-select,
|
||||
.form-textarea {
|
||||
.form-select {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--border);
|
||||
|
|
@ -748,8 +741,7 @@
|
|||
}
|
||||
|
||||
.form-input:focus,
|
||||
.form-select:focus,
|
||||
.form-textarea:focus {
|
||||
.form-select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(0, 115, 209, 0.1);
|
||||
|
|
@ -761,11 +753,6 @@
|
|||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
min-height: 80px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
|
|
@ -1021,7 +1008,7 @@
|
|||
<div class="form-group">
|
||||
<label class="form-label">How should analysts access this data?</label>
|
||||
<div class="bq-access-radio-group" style="display:flex; gap:12px; margin-top:6px;">
|
||||
<label style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="bqAccessMode" value="live" checked onchange="onBqAccessModeChange()">
|
||||
<strong>Live from BigQuery</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1031,7 +1018,7 @@
|
|||
freshness matters.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="bqAccessMode" value="synced" onchange="onBqAccessModeChange()">
|
||||
<strong>Synced locally</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1046,7 +1033,7 @@
|
|||
<div class="form-group bq-access-synced" style="display:none;">
|
||||
<label class="form-label">What to sync?</label>
|
||||
<div class="bq-sync-radio-group" style="display:flex; gap:12px; margin-top:6px;">
|
||||
<label style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="bqSyncMode" value="whole" checked onchange="onBqSyncModeChange()">
|
||||
<strong>Whole table</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1054,7 +1041,7 @@
|
|||
required. Disk + sync cost = full table size.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="bqSyncMode" value="custom" onchange="onBqSyncModeChange()">
|
||||
<strong>Custom query</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1200,14 +1187,14 @@
|
|||
<a href="docs/admin/query-modes.md" target="_blank" title="When to use which mode" style="margin-left: 6px; text-decoration: none; cursor: help;">?</a>
|
||||
</label>
|
||||
<div style="display:flex; gap:12px; margin-top:6px;">
|
||||
<label style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editBqAccessMode" value="live" onchange="onEditBqAccessModeChange()">
|
||||
<strong>Live from BigQuery</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
Each query goes to BQ. No local copy.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editBqAccessMode" value="synced" onchange="onEditBqAccessModeChange()">
|
||||
<strong>Synced locally</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1225,14 +1212,14 @@
|
|||
<div class="form-group bq-edit-access-synced" style="display:none;">
|
||||
<label class="form-label">What to sync?</label>
|
||||
<div style="display:flex; gap:12px; margin-top:6px;">
|
||||
<label style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editBqSyncMode" value="whole" onchange="onEditBqSyncModeChange()">
|
||||
<strong>Whole table</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
<code>SELECT *</code> on a schedule.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editBqSyncMode" value="custom" onchange="onEditBqSyncModeChange()">
|
||||
<strong>Custom query</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1356,7 +1343,7 @@
|
|||
<div class="form-group">
|
||||
<label class="form-label">What to sync?</label>
|
||||
<div class="bq-sync-radio-group" style="display:flex; gap:12px; margin-top:6px; flex-wrap:wrap;">
|
||||
<label style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="kbSyncMode" value="whole" checked onchange="onKbSyncModeChange()">
|
||||
<strong>Whole table (extension)</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1364,7 +1351,7 @@
|
|||
each tick. Fastest path; full overwrite each run.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="kbSyncMode" value="direct" onchange="onKbSyncModeChange()">
|
||||
<strong>Direct extract (Storage API)</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1373,7 +1360,7 @@
|
|||
and server-side <code>where_filters</code>.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:12px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="kbSyncMode" value="custom" onchange="onKbSyncModeChange()">
|
||||
<strong>Custom SQL</strong>
|
||||
<div style="font-size:12px; color:var(--text-secondary); margin-top:4px;">
|
||||
|
|
@ -1581,7 +1568,7 @@
|
|||
<div class="form-group">
|
||||
<label class="form-label">What to sync?</label>
|
||||
<div class="bq-sync-radio-group" style="display:flex; gap:12px; margin-top:6px; flex-wrap:wrap;">
|
||||
<label style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editKbSyncMode" value="whole"
|
||||
onchange="onEditKbSyncModeChange()">
|
||||
<strong>Whole table (extension)</strong>
|
||||
|
|
@ -1589,7 +1576,7 @@
|
|||
DuckDB Keboola extension; full overwrite each tick.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editKbSyncMode" value="direct"
|
||||
onchange="onEditKbSyncModeChange()">
|
||||
<strong>Direct extract (Storage API)</strong>
|
||||
|
|
@ -1598,7 +1585,7 @@
|
|||
<code>where_filters</code>.
|
||||
</div>
|
||||
</label>
|
||||
<label style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<label class="sync-option-card" style="flex:1; min-width:200px; padding:10px; border:1px solid var(--border); border-radius:8px; cursor:pointer;">
|
||||
<input type="radio" name="editKbSyncMode" value="custom"
|
||||
onchange="onEditKbSyncModeChange()">
|
||||
<strong>Custom SQL</strong>
|
||||
|
|
@ -1884,7 +1871,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Description <span class="optional">(optional)</span></label>
|
||||
<textarea id="cdp-desc" class="form-input" rows="2"></textarea>
|
||||
<textarea id="cdp-desc" class="form-textarea" rows="2"></textarea>
|
||||
</div>
|
||||
{# v51 lifecycle + classification — drive the hero filter
|
||||
checkboxes on /catalog and the eyebrow line above the
|
||||
|
|
@ -3176,7 +3163,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Description</label>
|
||||
<textarea id="edp-desc" class="form-input" rows="2"></textarea>
|
||||
<textarea id="edp-desc" class="form-textarea" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-group" style="display:flex; gap:12px;">
|
||||
<div style="flex:1;">
|
||||
|
|
@ -3901,7 +3888,6 @@
|
|||
if (mode === 'direct') onEditKbStrategyChange();
|
||||
}
|
||||
|
||||
{% if data_source_type == 'keboola' %}{# Phase F2 edit modal + prefill — keboola-only #}
|
||||
function _getEditKbStrategy() {
|
||||
var el = document.getElementById('editKbStrategy');
|
||||
return el ? el.value : 'full_refresh';
|
||||
|
|
@ -4153,7 +4139,6 @@
|
|||
}
|
||||
ta.value = 'SELECT *\nFROM kbc."' + bucket + '"."' + sourceTable + '"\nWHERE -- your filter here';
|
||||
}
|
||||
{% endif %}{# data_source_type == 'keboola' — Phase F2 edit modal + prefill #}
|
||||
|
||||
// C3: removed dead helper _buildKeboolaLegacyPayload — the Phase F
|
||||
// _buildKeboolaPayload (above) replaced it.
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@
|
|||
<div>
|
||||
{% set page_hero_eyebrow = "Agent Experience" %}
|
||||
{% set page_hero_title = "Init Prompt" %}
|
||||
{% set page_hero_subtitle = "Welcome shown to analysts at <code style="color:#fff;background:rgba(255,255,255,0.15);padding:1px 6px;border-radius:4px">agnes init</code>. Overrides the OSS default." %}
|
||||
{% set page_hero_subtitle = "Welcome shown to analysts at <code style="color:#fff;background:rgba(255,255,255,0.15);border:none;padding:1px 6px;border-radius:4px">agnes init</code>. Overrides the OSS default." %}
|
||||
{% include "_page_hero.html" %}
|
||||
</div>
|
||||
<div id="status-chip">
|
||||
|
|
|
|||
|
|
@ -1055,7 +1055,7 @@
|
|||
<div class="eyebrow">Welcome, {{ display_name }} — let's get you set up</div>
|
||||
<h1>Connect Claude Code on your machine to your team's data</h1>
|
||||
<p class="lead">
|
||||
{{ instance_brand }} gives <strong>Claude Code</strong> on your computer access to your team's <strong>curated data, plugins, third-party tools (Asana, Google Workspace, Atlassian), and shared knowledge</strong> — so you can ask questions and get answers in plain language, right from your terminal. This page walks you through the <strong>one-time setup (~10 minutes)</strong>; the install script also connects your tools for you, so there's no extra page to visit. Everything it installs lives in your home folder (<code style="background: rgba(255,255,255,0.12); padding: 1px 6px; border-radius: 4px; font-family: var(--hp-font-mono); font-size: 12.5px;">~/{{ workspace_dir }}</code>) and can be removed in one command.
|
||||
{{ instance_brand }} gives <strong>Claude Code</strong> on your computer access to your team's <strong>curated data, plugins, third-party tools (Asana, Google Workspace, Atlassian), and shared knowledge</strong> — so you can ask questions and get answers in plain language, right from your terminal. This page walks you through the <strong>one-time setup (~10 minutes)</strong>; the install script also connects your tools for you, so there's no extra page to visit. Everything it installs lives in your home folder (<code style="background: rgba(255,255,255,0.12); border: none; padding: 1px 6px; border-radius: 4px; font-family: var(--hp-font-mono); font-size: 12.5px;">~/{{ workspace_dir }}</code>) and can be removed in one command.
|
||||
</p>
|
||||
<p class="lead lead-privacy">
|
||||
<strong>What leaves your machine.</strong> Session telemetry — prompts, tool calls, and tool responses — flows back to the central catalog so the team can analyse failure patterns. Raw data rows you query locally stay on your machine; only the prompt/response transcript travels. Need a session off the record? Toggle Private in Claude Code (by typing <code style="background: rgba(255,255,255,0.12); padding: 1px 6px; border-radius: 4px; font-family: var(--hp-font-mono); font-size: 12.5px;">/agnes-private</code>) to disable telemetry for that chat — nothing from that session reaches the catalog.
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
<div class="eyebrow">Welcome back, {{ display_name }}</div>
|
||||
<h1>You're all set up</h1>
|
||||
<p>
|
||||
Open Claude Code in any project under <code style="background: rgba(255,255,255,0.12); padding: 1px 6px; border-radius: 4px; font-family: ui-monospace, 'SF Mono', Consolas, monospace; font-size: 12.5px;">~/{{ workspace_dir }}/Projects/</code>
|
||||
Open Claude Code in any project under <code style="background: rgba(255,255,255,0.12); border: none; padding: 1px 6px; border-radius: 4px; font-family: ui-monospace, 'SF Mono', Consolas, monospace; font-size: 12.5px;">~/{{ workspace_dir }}/Projects/</code>
|
||||
and start a session — your data and plugins are already synced. Use the cards below to jump into the parts of {{ instance_brand }} you need.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@
|
|||
overflow-x: auto; margin: 8px 0 14px;
|
||||
}
|
||||
.item-detail .lead-rendered pre code {
|
||||
background: transparent; padding: 0; color: inherit;
|
||||
background: transparent; border: none; border-radius: 0; padding: 0; color: inherit;
|
||||
}
|
||||
.item-detail .lead-rendered a { color: var(--primary); text-decoration: none; }
|
||||
.item-detail .lead-rendered a:hover { text-decoration: underline; }
|
||||
|
|
@ -526,6 +526,13 @@
|
|||
overflow-x: auto;
|
||||
white-space: pre-wrap; word-break: break-word;
|
||||
}
|
||||
.item-detail .use-case-prompt code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Sample interaction — Claude Code Catppuccin Mocha dark transcript.
|
||||
Identical visual treatment as plugin-detail's sample block: one dark
|
||||
|
|
@ -575,6 +582,7 @@
|
|||
.item-detail .sample-assistant-body em { color: #f9e2af; font-style: italic; }
|
||||
.item-detail .sample-assistant-body code {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: none;
|
||||
color: #f5c2e7;
|
||||
border-radius: 4px; padding: 1px 5px;
|
||||
font-size: 0.92em; font-family: var(--font-mono);
|
||||
|
|
@ -590,7 +598,7 @@
|
|||
margin: 8px 0;
|
||||
}
|
||||
.item-detail .sample-assistant-body pre code {
|
||||
background: transparent; padding: 0; color: inherit;
|
||||
background: transparent; border: none; border-radius: 0; padding: 0; color: inherit;
|
||||
}
|
||||
.item-detail .sample-assistant-body ul,
|
||||
.item-detail .sample-assistant-body ol { margin: 0 0 10px 22px; padding: 0; }
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@
|
|||
overflow-x: auto; margin: 8px 0 14px;
|
||||
}
|
||||
.plugin-detail .lead-rendered pre code {
|
||||
background: transparent; padding: 0; color: inherit;
|
||||
background: transparent; border: none; border-radius: 0; padding: 0; color: inherit;
|
||||
}
|
||||
.plugin-detail .lead-rendered a { color: var(--primary); text-decoration: none; }
|
||||
.plugin-detail .lead-rendered a:hover { text-decoration: underline; }
|
||||
|
|
@ -446,6 +446,13 @@
|
|||
overflow-x: auto;
|
||||
white-space: pre-wrap; word-break: break-word;
|
||||
}
|
||||
.plugin-detail .use-case-prompt code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Sample interaction — Claude Code transcript styling. Single dark
|
||||
Catppuccin Mocha panel splits the user prompt from Claude's response
|
||||
|
|
@ -510,6 +517,7 @@
|
|||
.plugin-detail .sample-assistant-body em { color: #f9e2af; font-style: italic; } /* mocha yellow */
|
||||
.plugin-detail .sample-assistant-body code {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: none;
|
||||
color: #f5c2e7; /* mocha pink */
|
||||
border-radius: 4px;
|
||||
padding: 1px 5px;
|
||||
|
|
@ -527,8 +535,7 @@
|
|||
margin: 8px 0;
|
||||
}
|
||||
.plugin-detail .sample-assistant-body pre code {
|
||||
background: transparent; padding: 0;
|
||||
color: inherit;
|
||||
background: transparent; border: none; border-radius: 0; padding: 0; color: inherit;
|
||||
}
|
||||
.plugin-detail .sample-assistant-body ul,
|
||||
.plugin-detail .sample-assistant-body ol {
|
||||
|
|
|
|||
|
|
@ -327,10 +327,17 @@ def test_keboola_discover_buttons_hidden_on_bigquery_instance(seeded_app, monkey
|
|||
# Inputs stay (manual entry works).
|
||||
assert 'id="kbBucket"' in html
|
||||
assert 'id="kbSourceTable"' in html
|
||||
# Buttons hidden.
|
||||
assert "discoverKeboolaBuckets" not in html
|
||||
assert "discoverKeboolaTables" not in html
|
||||
assert "prefillFromKeboolaTable" not in html
|
||||
# Buttons hidden — match the actual CALL SITES, not the
|
||||
# function definitions or JS comments that may reference the
|
||||
# names verbatim. #347 moved several Keboola edit-modal
|
||||
# helpers (incl. `prefillFromKeboolaTable`) out from under
|
||||
# the keboola Jinja guard so they're now defined as dead code
|
||||
# on every instance, but the `onclick="..."` call sites and
|
||||
# the Discover buttons themselves still respect the guard,
|
||||
# which is what actually matters for runtime behavior.
|
||||
assert 'onclick="discoverKeboolaBuckets(' not in html
|
||||
assert 'onclick="discoverKeboolaTables(' not in html
|
||||
assert 'onclick="prefillFromKeboolaTable(' not in html
|
||||
finally:
|
||||
reset_cache()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue