Skip to content

Commit 906d6ed

Browse files
authored
Merge pull request #5 from dev-Ninjaa/ui-ux
UI ux
2 parents a210709 + c7d1381 commit 906d6ed

File tree

11 files changed

+423
-48
lines changed

11 files changed

+423
-48
lines changed

src-tauri/src/env/models.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use serde::{Deserialize, Serialize};
22

3+
fn default_enabled() -> bool { true }
4+
35
#[derive(Debug, Clone, Serialize, Deserialize)]
46
pub struct EnvVar {
57
pub key: String,
68
pub value: String,
7-
}
9+
#[serde(default = "default_enabled")]
10+
pub enabled: bool,
11+
}

src-tauri/src/env/store.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,47 @@ impl EnvStore {
1010
pub fn new(db_path: &str) -> SqlResult<Self> {
1111
let conn = Connection::open(db_path)?;
1212

13-
// Create env_vars table if not exists
13+
// Create env_vars table if not exists (includes enabled flag)
1414
conn.execute(
1515
"CREATE TABLE IF NOT EXISTS env_vars (
1616
key TEXT PRIMARY KEY,
17-
value TEXT NOT NULL
17+
value TEXT NOT NULL,
18+
enabled INTEGER DEFAULT 1
1819
)",
1920
[],
2021
)?;
2122

23+
// Ensure backward compatibility: add 'enabled' column if missing
24+
{
25+
let mut stmt = conn.prepare("PRAGMA table_info(env_vars)")?;
26+
let mut rows = stmt.query([])?;
27+
let mut has_enabled = false;
28+
while let Some(row) = rows.next()? {
29+
let col_name: String = row.get(1)?;
30+
if col_name == "enabled" {
31+
has_enabled = true;
32+
break;
33+
}
34+
}
35+
if !has_enabled {
36+
conn.execute("ALTER TABLE env_vars ADD COLUMN enabled INTEGER DEFAULT 1", [])?;
37+
}
38+
}
39+
2240
Ok(EnvStore {
2341
conn: Mutex::new(conn),
2442
})
2543
}
2644

2745
pub fn get_all(&self) -> SqlResult<Vec<EnvVar>> {
2846
let conn = self.conn.lock().unwrap();
29-
let mut stmt = conn.prepare("SELECT key, value FROM env_vars ORDER BY key")?;
47+
let mut stmt = conn.prepare("SELECT key, value, COALESCE(enabled,1) FROM env_vars ORDER BY key")?;
3048

3149
let vars = stmt.query_map([], |row| {
3250
Ok(EnvVar {
3351
key: row.get(0)?,
3452
value: row.get(1)?,
53+
enabled: row.get(2)?,
3554
})
3655
})?;
3756

@@ -42,11 +61,11 @@ impl EnvStore {
4261
Ok(result)
4362
}
4463

45-
pub fn set(&self, key: &str, value: &str) -> SqlResult<()> {
64+
pub fn set(&self, key: &str, value: &str, enabled: bool) -> SqlResult<()> {
4665
let conn = self.conn.lock().unwrap();
4766
conn.execute(
48-
"INSERT OR REPLACE INTO env_vars (key, value) VALUES (?1, ?2)",
49-
(key, value),
67+
"INSERT OR REPLACE INTO env_vars (key, value, enabled) VALUES (?1, ?2, ?3)",
68+
(key, value, enabled as i32),
5069
)?;
5170
Ok(())
5271
}

src-tauri/src/main.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,42 @@ fn get_env_vars(state: State<'_, AppState>) -> Result<Vec<EnvVar>, String> {
6969
}
7070

7171
#[tauri::command]
72-
fn set_env_var(key: String, value: String, state: State<'_, AppState>) -> Result<(), String> {
73-
state.env_store.set(&key, &value)
72+
fn set_env_var(key: String, value: String, enabled: Option<bool>, state: State<'_, AppState>) -> Result<(), String> {
73+
let en = enabled.unwrap_or(true);
74+
state.env_store.set(&key, &value, en)
7475
.map_err(|e| format!("Failed to set env var: {}", e))
7576
}
7677

78+
#[tauri::command]
79+
async fn export_env_vars(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
80+
use tauri_plugin_dialog::{DialogExt, FilePath};
81+
use std::fs;
82+
83+
let vars = state.env_store.get_all().map_err(|e| format!("Failed to fetch env vars: {}", e))?;
84+
let export = serde_json::json!({
85+
"version": "1.0",
86+
"exportedAt": chrono::Utc::now().to_rfc3339(),
87+
"env": vars,
88+
});
89+
90+
let file_path = app.dialog()
91+
.file()
92+
.set_title("Export Environment Variables")
93+
.add_filter("JSON Files", &["json"])
94+
.set_file_name("env-vars.json")
95+
.blocking_save_file();
96+
97+
if let Some(path) = file_path {
98+
let path_str = match path {
99+
FilePath::Path(p) => p.to_str().ok_or_else(|| "Invalid file path".to_string())?.to_string(),
100+
FilePath::Url(_u) => return Err("URL paths not supported".to_string()),
101+
};
102+
fs::write(path_str, serde_json::to_string_pretty(&export).map_err(|e| e.to_string())?).map_err(|e| format!("Failed to write file: {}", e))?;
103+
}
104+
105+
Ok(())
106+
}
107+
77108
#[tauri::command]
78109
fn delete_env_var(key: String, state: State<'_, AppState>) -> Result<(), String> {
79110
state.env_store.delete(&key)
@@ -257,7 +288,8 @@ fn main() {
257288
delete_env_var,
258289
save_request,
259290
load_request,
260-
save_collections
291+
save_collections,
292+
export_env_vars
261293
])
262294
.run(tauri::generate_context!())
263295
.expect("error while running tauri application");

src/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,12 @@ <h3>History</h3>
277277
<div class="key-value-editor" id="envVarsList">
278278
<!-- Env vars will be rendered here -->
279279
</div>
280-
<button class="btn-secondary btn-add" id="addEnvVarBtn">+ Add Variable</button>
280+
<div class="env-actions">
281+
<button class="btn-secondary btn-add" id="addEnvVarBtn">+ Add Variable</button>
282+
<button class="btn-secondary" id="exportEnvBtn">Export Variables</button>
283+
<button class="btn-secondary" id="importEnvBtn">Import Variables</button>
284+
<input type="file" id="importEnvInput" accept=".json" style="display:none">
285+
</div>
281286
</div>
282287
</div>
283288
</section>

src/scripts/state.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ const state = {
2222
collections: []
2323
};
2424

25-
const getInvoke = () => window.__TAURI__?.core?.invoke || window.__TAURI__?.invoke;
25+
if (typeof window.getInvoke === 'undefined') {
26+
window.getInvoke = () => window.__TAURI__?.core?.invoke || window.__TAURI__?.invoke;
27+
}
28+
if (typeof window.getDialog === 'undefined') {
29+
window.getDialog = () => window.__TAURI__?.dialog || window.__TAURI__?.core?.dialog;
30+
}
2631

2732
// State management functions
2833
function updateRequest(updates) {
@@ -39,7 +44,7 @@ function setResponse(response) {
3944

4045
async function clearHistory() {
4146
try {
42-
const invoke = getInvoke();
47+
const invoke = window.getInvoke ? window.getInvoke() : null;
4348
if (!invoke) return;
4449
await invoke('clear_history');
4550
state.history = [];
@@ -51,7 +56,7 @@ async function clearHistory() {
5156

5257
async function loadHistory() {
5358
try {
54-
const invoke = getInvoke();
59+
const invoke = window.getInvoke ? window.getInvoke() : null;
5560
if (!invoke) return;
5661
const history = await invoke('get_history');
5762
state.history = history;
@@ -64,7 +69,7 @@ async function loadHistory() {
6469
// Environment variables management
6570
async function loadEnvVars() {
6671
try {
67-
const invoke = getInvoke();
72+
const invoke = window.getInvoke ? window.getInvoke() : null;
6873
if (!invoke) return;
6974
const envVars = await invoke('get_env_vars');
7075
state.envVars = envVars;
@@ -74,21 +79,21 @@ async function loadEnvVars() {
7479
}
7580
}
7681

77-
async function setEnvVar(key, value) {
82+
async function setEnvVar(key, value, enabled = true) {
7883
try {
79-
const invoke = getInvoke();
84+
const invoke = window.getInvoke ? window.getInvoke() : null;
8085
if (!invoke) return;
81-
await invoke('set_env_var', { key, value });
86+
await invoke('set_env_var', { key, value, enabled });
8287
await loadEnvVars();
8388
} catch (e) {
8489
console.error('Failed to set env var:', e);
8590
throw e;
8691
}
87-
}
92+
}
8893

8994
async function deleteEnvVar(key) {
9095
try {
91-
const invoke = getInvoke();
96+
const invoke = window.getInvoke ? window.getInvoke() : null;
9297
if (!invoke) return;
9398
await invoke('delete_env_var', { key });
9499
await loadEnvVars();

0 commit comments

Comments
 (0)