mirror of
https://github.com/perstarkse/minne.git
synced 2026-01-11 20:50:24 +01:00
design: additional design improvements
chore: remove stale comment
This commit is contained in:
@@ -8,7 +8,6 @@ use std::{
|
||||
};
|
||||
use tempfile::NamedTempFile;
|
||||
use thiserror::Error;
|
||||
// futures imports no longer needed here after abstraction
|
||||
use tracing::info;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
@@ -440,14 +440,63 @@
|
||||
}
|
||||
|
||||
.kg-overlay {
|
||||
@apply absolute top-4 left-4 z-10 flex items-center gap-2;
|
||||
@apply absolute top-4 left-4 right-4 z-10 flex flex-col items-stretch gap-2;
|
||||
max-width: min(420px, calc(100% - 2rem));
|
||||
}
|
||||
|
||||
.kg-control-row {
|
||||
@apply flex flex-wrap items-center gap-2;
|
||||
}
|
||||
|
||||
.kg-control-row-primary {
|
||||
@apply justify-start;
|
||||
}
|
||||
|
||||
.kg-control-row-secondary {
|
||||
@apply justify-center;
|
||||
}
|
||||
|
||||
.kg-search-input {
|
||||
@apply pl-2;
|
||||
height: 2rem;
|
||||
min-width: 220px;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.kg-control-row-primary .kg-search-input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.kg-search-btn {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.kg-toggle {
|
||||
@apply transition-colors;
|
||||
}
|
||||
|
||||
.kg-toggle-active {
|
||||
--btn-color: var(--color-accent);
|
||||
--btn-fg: var(--color-accent-content);
|
||||
--btn-noise: none;
|
||||
background-image: none;
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent-content);
|
||||
}
|
||||
|
||||
.kg-toggle-active:hover {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent-content);
|
||||
filter: saturate(1.1) brightness(1.05);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.kg-overlay {
|
||||
right: auto;
|
||||
max-width: none;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.kg-legend {
|
||||
|
||||
@@ -71,10 +71,16 @@
|
||||
return { idToNode, neighbors };
|
||||
}
|
||||
|
||||
function attachOverlay(container, { onSearch, onToggleLabels, onCenter }) {
|
||||
function attachOverlay(container, { onSearch, onToggleNames, onToggleEdgeLabels, onCenter }) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'kg-overlay';
|
||||
|
||||
const primaryRow = document.createElement('div');
|
||||
primaryRow.className = 'kg-control-row kg-control-row-primary';
|
||||
|
||||
const secondaryRow = document.createElement('div');
|
||||
secondaryRow.className = 'kg-control-row kg-control-row-secondary';
|
||||
|
||||
// search box
|
||||
const input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
@@ -85,29 +91,41 @@
|
||||
});
|
||||
|
||||
const searchBtn = document.createElement('button');
|
||||
searchBtn.className = 'nb-btn btn-xs nb-cta';
|
||||
searchBtn.className = 'nb-btn btn-xs nb-cta kg-search-btn';
|
||||
searchBtn.textContent = 'Go';
|
||||
searchBtn.addEventListener('click', () => onSearch && onSearch(input.value.trim()));
|
||||
|
||||
const namesToggle = document.createElement('button');
|
||||
namesToggle.className = 'nb-btn btn-xs kg-toggle';
|
||||
namesToggle.type = 'button';
|
||||
namesToggle.textContent = 'Names';
|
||||
namesToggle.addEventListener('click', () => onToggleNames && onToggleNames());
|
||||
|
||||
const labelToggle = document.createElement('button');
|
||||
labelToggle.className = 'nb-btn btn-xs';
|
||||
labelToggle.className = 'nb-btn btn-xs kg-toggle';
|
||||
labelToggle.type = 'button';
|
||||
labelToggle.textContent = 'Labels';
|
||||
labelToggle.addEventListener('click', () => onToggleLabels && onToggleLabels());
|
||||
labelToggle.addEventListener('click', () => onToggleEdgeLabels && onToggleEdgeLabels());
|
||||
|
||||
const centerBtn = document.createElement('button');
|
||||
centerBtn.className = 'nb-btn btn-xs';
|
||||
centerBtn.textContent = 'Center';
|
||||
centerBtn.addEventListener('click', () => onCenter && onCenter());
|
||||
|
||||
overlay.appendChild(input);
|
||||
overlay.appendChild(searchBtn);
|
||||
overlay.appendChild(labelToggle);
|
||||
overlay.appendChild(centerBtn);
|
||||
primaryRow.appendChild(input);
|
||||
primaryRow.appendChild(searchBtn);
|
||||
|
||||
secondaryRow.appendChild(namesToggle);
|
||||
secondaryRow.appendChild(labelToggle);
|
||||
secondaryRow.appendChild(centerBtn);
|
||||
|
||||
overlay.appendChild(primaryRow);
|
||||
overlay.appendChild(secondaryRow);
|
||||
|
||||
container.style.position = 'relative';
|
||||
container.appendChild(overlay);
|
||||
|
||||
return { input, overlay };
|
||||
return { input, overlay, namesToggle, labelToggle };
|
||||
}
|
||||
|
||||
function attachLegends(container, typeColor, relColor) {
|
||||
@@ -180,13 +198,33 @@
|
||||
const { neighbors } = buildAdjacency(data.nodes, data.links);
|
||||
|
||||
// Build overlay controls
|
||||
let labelsVisible = true;
|
||||
const { input } = attachOverlay(container, {
|
||||
let namesVisible = true;
|
||||
let edgeLabelsVisible = true;
|
||||
|
||||
const togglePressedState = (button, state) => {
|
||||
if (!button) return;
|
||||
button.setAttribute('aria-pressed', state ? 'true' : 'false');
|
||||
button.classList.toggle('kg-toggle-active', !!state);
|
||||
};
|
||||
|
||||
const { input, namesToggle, labelToggle } = attachOverlay(container, {
|
||||
onSearch: (q) => focusSearch(q),
|
||||
onToggleLabels: () => { labelsVisible = !labelsVisible; label.style('display', labelsVisible ? null : 'none'); },
|
||||
onToggleNames: () => {
|
||||
namesVisible = !namesVisible;
|
||||
label.style('display', namesVisible ? null : 'none');
|
||||
togglePressedState(namesToggle, namesVisible);
|
||||
},
|
||||
onToggleEdgeLabels: () => {
|
||||
edgeLabelsVisible = !edgeLabelsVisible;
|
||||
linkLabel.style('display', edgeLabelsVisible ? null : 'none');
|
||||
togglePressedState(labelToggle, edgeLabelsVisible);
|
||||
},
|
||||
onCenter: () => zoomTo(1, [width / 2, height / 2])
|
||||
});
|
||||
|
||||
togglePressedState(namesToggle, namesVisible);
|
||||
togglePressedState(labelToggle, edgeLabelsVisible);
|
||||
|
||||
// SVG + zoom
|
||||
const svg = d3.select(container)
|
||||
.append('svg')
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -17,7 +17,7 @@ hx-swap="outerHTML"
|
||||
{% endblock %}
|
||||
|
||||
{% block primary_actions %}
|
||||
<button type="button" class="nb-btn mr-2" id="reset_prompt_button">
|
||||
<button type="button" class="nb-btn w-full sm:w-auto sm:mr-2" id="reset_prompt_button">
|
||||
Reset to Default
|
||||
</button>
|
||||
|
||||
@@ -29,7 +29,7 @@ hx-swap="outerHTML"
|
||||
});
|
||||
</script>
|
||||
|
||||
<button type="submit" class="nb-btn nb-cta">
|
||||
<button type="submit" class="nb-btn nb-cta w-full sm:w-auto">
|
||||
<span class="htmx-indicator hidden">
|
||||
<span class="loading loading-spinner loading-xs mr-2"></span>
|
||||
</span>
|
||||
|
||||
@@ -17,7 +17,7 @@ hx-swap="outerHTML"
|
||||
{% endblock %}
|
||||
|
||||
{% block primary_actions %}
|
||||
<button type="button" class="nb-btn mr-2" id="reset_prompt_button">
|
||||
<button type="button" class="nb-btn w-full sm:w-auto sm:mr-2" id="reset_prompt_button">
|
||||
Reset to Default
|
||||
</button>
|
||||
|
||||
@@ -29,7 +29,7 @@ hx-swap="outerHTML"
|
||||
});
|
||||
</script>
|
||||
|
||||
<button type="submit" class="nb-btn nb-cta">
|
||||
<button type="submit" class="nb-btn nb-cta w-full sm:w-auto">
|
||||
<span class="htmx-indicator hidden">
|
||||
<span class="loading loading-spinner loading-xs mr-2"></span>
|
||||
</span>
|
||||
|
||||
@@ -17,7 +17,7 @@ hx-swap="outerHTML"
|
||||
{% endblock %}
|
||||
|
||||
{% block primary_actions %}
|
||||
<button type="button" class="nb-btn mr-2" id="reset_prompt_button">
|
||||
<button type="button" class="nb-btn w-full sm:w-auto sm:mr-2" id="reset_prompt_button">
|
||||
Reset to Default
|
||||
</button>
|
||||
|
||||
@@ -29,7 +29,7 @@ hx-swap="outerHTML"
|
||||
});
|
||||
</script>
|
||||
|
||||
<button type="submit" class="nb-btn nb-cta">
|
||||
<button type="submit" class="nb-btn nb-cta w-full sm:w-auto">
|
||||
<span class="htmx-indicator hidden">
|
||||
<span class="loading loading-spinner loading-xs mr-2"></span>
|
||||
</span>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
{% block modal_content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class="u-hairline mt-4 pt-3 flex justify-end gap-2">
|
||||
<div class="u-hairline mt-4 pt-3 flex flex-col gap-2 sm:flex-row sm:justify-end sm:items-center">
|
||||
<!-- Close button (always visible) -->
|
||||
<button type="button" class="nb-btn" onclick="document.getElementById('body_modal').close()">
|
||||
<button type="button" class="nb-btn w-full sm:w-auto" onclick="document.getElementById('body_modal').close()">
|
||||
Close
|
||||
</button>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user