feat: list saved queries

This commit is contained in:
Yann Amsellem
2025-01-07 21:54:04 +01:00
parent 84051c6cb0
commit d39cfe03e0
4 changed files with 117 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
<script lang="ts">
import SQLFile from '$lib/icons/SQLFile.svelte';
import type { Query } from '$lib/repositories/queries';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
interface Props {
queries?: Query[];
}
let { queries = [] }: Props = $props();
</script>
<ol role="menu">
{#each queries as query (query.id)}
<li
tabindex="-1"
oncontextmenu={(e) => {
e.preventDefault();
}}
role="menuitem"
onkeydown={(e) => {
if (e.key === 'Enter') {
e.currentTarget.blur();
}
}}
onclick={(e) => {
if (e.detail >= 2) {
e.currentTarget.blur();
}
}}
>
<SQLFile size="18" />
<div>
<span>{query.name}</span>
<span>{dayjs(query.createdAt).fromNow()}</span>
</div>
</li>
{/each}
</ol>
<style>
ol {
list-style: none;
margin: 0;
padding: 0;
flex: 1;
overflow-y: auto;
}
li {
padding: 3px 5px;
border-radius: 3px;
cursor: default;
user-select: none;
-webkit-user-select: none;
display: flex;
align-items: center;
gap: 5px;
& > :global(svg) {
fill: hsl(0deg 0% 96%);
flex-shrink: 0;
}
& > div {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
overflow: hidden;
& > span:first-of-type {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
& > span:last-of-type {
font-size: 10px;
color: hsl(0deg 0% 96%);
}
}
&:focus {
outline: none;
background-color: hsl(210deg 100% 52%);
}
}
</style>

View File

@@ -0,0 +1 @@
export { default as Queries } from './Queries.svelte';

View File

@@ -4,6 +4,7 @@
import type { Query } from '$lib/repositories/queries';
import Datasets from './Datasets/Datasets.svelte';
import History from './History.svelte';
import Queries from './Queries/Queries.svelte';
type Tab = 'sources' | 'queries' | 'history';
@@ -31,6 +32,9 @@
{#if tab === 'sources'}
<Datasets {tables} />
{/if}
{#if tab === 'queries'}
<Queries {queries} />
{/if}
{#if tab === 'history'}
<History {history} {onHistoryClick} />
{/if}

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
interface Props extends Omit<SvelteHTMLElements['svg'], 'width' | 'height'> {
size?: string | number | null;
}
let { size = 24, ...rest }: Props = $props();
</script>
<svg width={size} height={size} viewBox="0 0 16 16" {...rest}>
<path
fill="currentColor"
fill-rule="evenodd"
d="M14 4.5V14a2 2 0 0 1-2 2v-1a1 1 0 0 0 1-1V4.5h-2A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v9H2V2a2 2 0 0 1 2-2h5.5zM0 14.841a1.13 1.13 0 0 0 .401.823q.194.162.478.252c.284.09.411.091.665.091q.507 0 .858-.158q.355-.159.54-.44a1.17 1.17 0 0 0 .187-.656q0-.336-.135-.56a1 1 0 0 0-.375-.357a2 2 0 0 0-.565-.21l-.621-.144a1 1 0 0 1-.405-.176a.37.37 0 0 1-.143-.299q0-.234.184-.384q.187-.152.513-.152q.214 0 .37.068a.6.6 0 0 1 .245.181a.56.56 0 0 1 .12.258h.75a1.1 1.1 0 0 0-.199-.566a1.2 1.2 0 0 0-.5-.41a1.8 1.8 0 0 0-.78-.152q-.44 0-.776.15q-.337.149-.528.421q-.19.273-.19.639q0 .302.123.524t.351.367q.229.143.54.213l.618.144q.31.073.462.193a.39.39 0 0 1 .153.325q0 .165-.085.29A.56.56 0 0 1 2 15.31q-.167.07-.413.07q-.176 0-.32-.04a.8.8 0 0 1-.248-.115a.58.58 0 0 1-.255-.384zm6.878 1.489l-.507-.739q.264-.243.401-.6q.138-.358.138-.806v-.501q0-.556-.208-.967a1.5 1.5 0 0 0-.589-.636q-.383-.225-.917-.225q-.527 0-.914.225q-.384.223-.592.636a2.14 2.14 0 0 0-.205.967v.5q0 .554.205.965q.208.41.592.636a1.8 1.8 0 0 0 .914.222a1.8 1.8 0 0 0 .6-.1l.294.422h.788ZM4.262 14.2v-.522q0-.369.114-.63a.9.9 0 0 1 .325-.398a.9.9 0 0 1 .495-.138q.288 0 .495.138a.9.9 0 0 1 .325.398q.115.261.115.63v.522q0 .246-.053.445q-.053.196-.155.34l-.106-.14l-.105-.147h-.733l.451.65a.6.6 0 0 1-.251.047a.87.87 0 0 1-.487-.147a.9.9 0 0 1-.32-.404a1.7 1.7 0 0 1-.11-.644m3.986 1.057h1.696v.674H7.457v-3.999h.79z"
/>
</svg>