create-tauri-vue-app 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +8 -0
- package/package.json +1 -1
- package/template/package.json +1 -0
- package/template/src/components/TaskList.vue +132 -0
- package/template/src/router/index.js +6 -0
- package/template/src/utils/db.js +45 -0
- package/template/src/views/Home.vue +2 -0
- package/template/src-tauri/Cargo.toml +1 -0
- package/template/src-tauri/capabilities/default.json +5 -0
- package/template/src-tauri/src/lib.rs +45 -0
package/package.json
CHANGED
package/template/package.json
CHANGED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="task-list">
|
|
3
|
+
<h2>Task List</h2>
|
|
4
|
+
|
|
5
|
+
<div class="add-task">
|
|
6
|
+
<el-input
|
|
7
|
+
v-model="newTask"
|
|
8
|
+
placeholder="Enter task title..."
|
|
9
|
+
@keyup.enter="handleAddTask"
|
|
10
|
+
/>
|
|
11
|
+
<el-button type="primary" @click="handleAddTask">Add</el-button>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<el-spinner v-if="loading" />
|
|
15
|
+
|
|
16
|
+
<div v-else class="tasks">
|
|
17
|
+
<div v-for="task in tasks" :key="task.id" class="task-item">
|
|
18
|
+
<el-checkbox
|
|
19
|
+
:model-value="task.completed === 1"
|
|
20
|
+
@change="handleToggle(task)"
|
|
21
|
+
>
|
|
22
|
+
<span :class="{ completed: task.completed }">{{ task.title }}</span>
|
|
23
|
+
</el-checkbox>
|
|
24
|
+
<el-button text type="danger" @click="handleDelete(task.id)">
|
|
25
|
+
Delete
|
|
26
|
+
</el-button>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div v-if="tasks.length === 0" class="empty">No tasks yet</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup>
|
|
35
|
+
import { ref, onMounted } from 'vue'
|
|
36
|
+
import { getTasks, addTask, deleteTask, toggleTask } from '../utils/db'
|
|
37
|
+
import { ElMessage } from 'element-plus'
|
|
38
|
+
|
|
39
|
+
const tasks = ref([])
|
|
40
|
+
const newTask = ref('')
|
|
41
|
+
const loading = ref(true)
|
|
42
|
+
|
|
43
|
+
async function loadTasks() {
|
|
44
|
+
loading.value = true
|
|
45
|
+
try {
|
|
46
|
+
tasks.value = await getTasks()
|
|
47
|
+
} catch (e) {
|
|
48
|
+
ElMessage.error('Failed to load tasks')
|
|
49
|
+
console.error(e)
|
|
50
|
+
} finally {
|
|
51
|
+
loading.value = false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function handleAddTask() {
|
|
56
|
+
if (!newTask.value.trim()) return
|
|
57
|
+
try {
|
|
58
|
+
await addTask(newTask.value.trim())
|
|
59
|
+
newTask.value = ''
|
|
60
|
+
await loadTasks()
|
|
61
|
+
ElMessage.success('Task added')
|
|
62
|
+
} catch (e) {
|
|
63
|
+
ElMessage.error('Failed to add task')
|
|
64
|
+
console.error(e)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function handleToggle(task) {
|
|
69
|
+
try {
|
|
70
|
+
await toggleTask(task.id, task.completed !== 1)
|
|
71
|
+
await loadTasks()
|
|
72
|
+
} catch (e) {
|
|
73
|
+
ElMessage.error('Failed to update task')
|
|
74
|
+
console.error(e)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function handleDelete(id) {
|
|
79
|
+
try {
|
|
80
|
+
await deleteTask(id)
|
|
81
|
+
await loadTasks()
|
|
82
|
+
ElMessage.success('Task deleted')
|
|
83
|
+
} catch (e) {
|
|
84
|
+
ElMessage.error('Failed to delete task')
|
|
85
|
+
console.error(e)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
onMounted(loadTasks)
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style scoped>
|
|
93
|
+
.task-list {
|
|
94
|
+
padding: 20px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.add-task {
|
|
98
|
+
display: flex;
|
|
99
|
+
gap: 10px;
|
|
100
|
+
margin-bottom: 20px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.add-task .el-input {
|
|
104
|
+
flex: 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.tasks {
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
gap: 10px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.task-item {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: space-between;
|
|
117
|
+
padding: 10px;
|
|
118
|
+
border: 1px solid #eee;
|
|
119
|
+
border-radius: 4px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.task-item .completed {
|
|
123
|
+
text-decoration: line-through;
|
|
124
|
+
color: #999;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.empty {
|
|
128
|
+
text-align: center;
|
|
129
|
+
color: #999;
|
|
130
|
+
padding: 20px;
|
|
131
|
+
}
|
|
132
|
+
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
2
2
|
import Home from '../views/Home.vue'
|
|
3
|
+
import TaskList from '../components/TaskList.vue'
|
|
3
4
|
|
|
4
5
|
const routes = [
|
|
5
6
|
{
|
|
@@ -7,6 +8,11 @@ const routes = [
|
|
|
7
8
|
name: 'Home',
|
|
8
9
|
component: Home
|
|
9
10
|
},
|
|
11
|
+
{
|
|
12
|
+
path: '/tasks',
|
|
13
|
+
name: 'Tasks',
|
|
14
|
+
component: TaskList
|
|
15
|
+
},
|
|
10
16
|
{
|
|
11
17
|
path: '/admin',
|
|
12
18
|
name: 'Admin',
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Database from '@tauri-apps/plugin-sql'
|
|
2
|
+
|
|
3
|
+
let db = null
|
|
4
|
+
|
|
5
|
+
export async function getDb() {
|
|
6
|
+
if (!db) {
|
|
7
|
+
db = await Database.load('sqlite:app.db')
|
|
8
|
+
}
|
|
9
|
+
return db
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// CRUD operations for tasks
|
|
13
|
+
export async function getTasks() {
|
|
14
|
+
const database = await getDb()
|
|
15
|
+
return await database.select('SELECT * FROM tasks ORDER BY created_at DESC')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function addTask(title, description = '') {
|
|
19
|
+
const database = await getDb()
|
|
20
|
+
await database.execute(
|
|
21
|
+
'INSERT INTO tasks (title, description, completed) VALUES (?, ?, ?)',
|
|
22
|
+
[title, description, 0]
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function updateTask(id, title, description, completed) {
|
|
27
|
+
const database = await getDb()
|
|
28
|
+
await database.execute(
|
|
29
|
+
'UPDATE tasks SET title = ?, description = ?, completed = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
|
30
|
+
[title, description, completed ? 1 : 0, id]
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function deleteTask(id) {
|
|
35
|
+
const database = await getDb()
|
|
36
|
+
await database.execute('DELETE FROM tasks WHERE id = ?', [id])
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function toggleTask(id, completed) {
|
|
40
|
+
const database = await getDb()
|
|
41
|
+
await database.execute(
|
|
42
|
+
'UPDATE tasks SET completed = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
|
43
|
+
[completed ? 1 : 0, id]
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
2
|
+
use tauri_plugin_sql::{Migration, MigrationKind};
|
|
3
|
+
|
|
2
4
|
pub fn run() {
|
|
3
5
|
tauri::Builder::default()
|
|
4
6
|
.plugin(
|
|
@@ -7,6 +9,49 @@ pub fn run() {
|
|
|
7
9
|
.build(),
|
|
8
10
|
)
|
|
9
11
|
.plugin(tauri_plugin_shell::init())
|
|
12
|
+
.plugin(
|
|
13
|
+
tauri_plugin_sql::Builder::default()
|
|
14
|
+
.add_migrations(
|
|
15
|
+
"sqlite:app.db",
|
|
16
|
+
vec![
|
|
17
|
+
Migration {
|
|
18
|
+
version: 1,
|
|
19
|
+
description: "create_tasks_table",
|
|
20
|
+
sql: r#"
|
|
21
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
22
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
23
|
+
title TEXT NOT NULL,
|
|
24
|
+
description TEXT,
|
|
25
|
+
completed INTEGER DEFAULT 0,
|
|
26
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
27
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
28
|
+
)
|
|
29
|
+
"#,
|
|
30
|
+
kind: MigrationKind::Up,
|
|
31
|
+
},
|
|
32
|
+
Migration {
|
|
33
|
+
version: 2,
|
|
34
|
+
description: "create_downloads_table",
|
|
35
|
+
sql: r#"
|
|
36
|
+
CREATE TABLE IF NOT EXISTS downloads (
|
|
37
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
|
+
filename TEXT NOT NULL,
|
|
39
|
+
url TEXT,
|
|
40
|
+
save_path TEXT,
|
|
41
|
+
file_size TEXT,
|
|
42
|
+
status TEXT DEFAULT 'downloading',
|
|
43
|
+
progress INTEGER DEFAULT 0,
|
|
44
|
+
gid TEXT,
|
|
45
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
47
|
+
)
|
|
48
|
+
"#,
|
|
49
|
+
kind: MigrationKind::Up,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
)
|
|
53
|
+
.build(),
|
|
54
|
+
)
|
|
10
55
|
.run(tauri::generate_context!())
|
|
11
56
|
.expect("error while running tauri application");
|
|
12
57
|
}
|