Skip to content

Commit e9b95ac

Browse files
committed
feat: implement svelte web UI for GraphQL inliner 🚀
This commit adds a complete Svelte web UI for the GraphQL inliner tool with the following features: - Added App component as the main container for the application - Implemented tabbed interface with TabBar component for managing multiple queries - Created EditorPanel with CodeMirror editors for input and output - Added Header and Footer components for consistent UI structure - Created tab store for state management and persistence - Implemented real-time compilation of GraphQL queries - Added error handling and status notifications - Support for copy to clipboard functionality
1 parent 1b1464e commit e9b95ac

File tree

11 files changed

+1348
-433
lines changed

11 files changed

+1348
-433
lines changed

‎src/lib/components/App.svelte

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
4+
import Header from '$lib/components/Header.svelte';
5+
import Footer from '$lib/components/Footer.svelte';
6+
import TabBar from '$lib/components/TabBar.svelte';
7+
import EditorPanel from '$lib/components/EditorPanel.svelte';
8+
9+
import { createTabStore } from '$lib/stores/tab-store.svelte.js';
10+
11+
let isLoading = $state(false);
12+
let error = $state<string>();
13+
let success = $state<string>();
14+
15+
const tabStore = createTabStore();
16+
const tabs = $derived(tabStore.tabs);
17+
const activeTabId = $derived(tabStore.activeTabId);
18+
const activeTab = $derived(tabStore.activeTab);
19+
20+
// Handle status updates from child components
21+
function updateStatus({
22+
loading,
23+
errorMessage,
24+
successMessage
25+
}: {
26+
loading?: boolean;
27+
errorMessage?: string;
28+
successMessage?: string;
29+
}) {
30+
if (loading !== undefined) {
31+
isLoading = loading;
32+
} else {
33+
isLoading = false;
34+
}
35+
if (errorMessage !== undefined) {
36+
error = errorMessage;
37+
} else {
38+
error = undefined;
39+
}
40+
if (successMessage !== undefined) {
41+
success = successMessage;
42+
} else {
43+
success = undefined;
44+
}
45+
46+
// Clear success messages after a delay
47+
if (successMessage) {
48+
setTimeout(() => {
49+
if (success === successMessage) {
50+
success = undefined;
51+
}
52+
}, 3000);
53+
}
54+
}
55+
56+
// Make sure we have at least one tab when the app loads
57+
onMount(() => {
58+
if (tabs.length === 0) {
59+
tabStore.addTab(true); // Add a default tab with example content
60+
}
61+
});
62+
</script>
63+
64+
<div class="app-container">
65+
<Header />
66+
67+
<div class="main-content">
68+
<div class="container full-height">
69+
<TabBar
70+
{tabs}
71+
{activeTabId}
72+
onAddTab={tabStore.addTab}
73+
onCloseTab={tabStore.closeTab}
74+
onSetActiveTab={tabStore.setActiveTab}
75+
onUpdateTabTitle={tabStore.updateTabTitle}
76+
/>
77+
78+
{#if activeTab}
79+
{#key activeTab.id}
80+
<EditorPanel
81+
tabId={activeTab.id}
82+
operationText={activeTab.operationText}
83+
optimizedOperationText={activeTab.optimizedOperationText}
84+
onUpdate={tabStore.updateTabContent}
85+
onStatus={updateStatus}
86+
/>
87+
{/key}
88+
{/if}
89+
</div>
90+
</div>
91+
92+
<Footer {isLoading} {error} {success} />
93+
</div>
94+
95+
<style>
96+
:global(html, body) {
97+
margin: 0;
98+
padding: 0;
99+
height: 100%;
100+
overflow: hidden;
101+
}
102+
103+
:global(body) {
104+
font-family:
105+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell,
106+
'Helvetica Neue', sans-serif;
107+
background-color: #f9fafb;
108+
color: #1f2937;
109+
}
110+
111+
.app-container {
112+
display: flex;
113+
flex-direction: column;
114+
height: 100vh;
115+
overflow: hidden;
116+
}
117+
118+
.main-content {
119+
flex: 1;
120+
overflow: hidden;
121+
display: flex;
122+
flex-direction: column;
123+
}
124+
125+
.container {
126+
width: 100%;
127+
max-width: 1800px;
128+
margin: 0 auto;
129+
padding: 0 1rem;
130+
}
131+
132+
.full-height {
133+
height: 100%;
134+
display: flex;
135+
flex-direction: column;
136+
}
137+
</style>

0 commit comments

Comments
 (0)