diff --git a/mocks/sample-data.json b/mocks/sample-data.json new file mode 100644 index 0000000..cd27af8 --- /dev/null +++ b/mocks/sample-data.json @@ -0,0 +1,33 @@ +{ + "columns": [ + { "name": "name", "type": "text" }, + { "name": "category", "type": "text" }, + { "name": "quantity", "type": "text" }, + { "name": "location", "type": "text" }, + { "name": "image", "type": "image" } + ], + "rows": [ + { + "id": "abc123", + "name": "test a", + "category": "type a", + "quantity": "5" + }, + { + "id": "def456", + "name": "test b", + "category": "type a", + "quantity": "10" + }, + { + "id": "ghi789", + "name": "test c", + "category": "type b", + "quantity": "2", + "image": { + "src": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Loup_du_Canada_%28Canis_lupus_mackenzii%29.JPG/1280px-Loup_du_Canada_%28Canis_lupus_mackenzii%29.JPG", + "alt": "Loup du Canada" + } + } + ] +} diff --git a/package-lock.json b/package-lock.json index c8a1385..2eab453 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@primeuix/themes": "1.0.0", "@tauri-apps/api": "2.3.0", "@tauri-apps/plugin-dialog": "^2.2.0", + "@tauri-apps/plugin-fs": "^2.2.0", "@tauri-apps/plugin-opener": "2.2.6", "pinia": "3.0.1", "primeicons": "7.0.0", @@ -1368,6 +1369,15 @@ "@tauri-apps/api": "^2.0.0" } }, + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.2.0.tgz", + "integrity": "sha512-+08mApuONKI8/sCNEZ6AR8vf5vI9DXD4YfrQ9NQmhRxYKMLVhRW164vdW5BSLmMpuevftpQ2FVoL9EFkfG9Z+g==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, "node_modules/@tauri-apps/plugin-opener": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.2.6.tgz", diff --git a/package.json b/package.json index 3e0deb6..befec82 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@primeuix/themes": "1.0.0", "@tauri-apps/api": "2.3.0", "@tauri-apps/plugin-dialog": "^2.2.0", + "@tauri-apps/plugin-fs": "^2.2.0", "@tauri-apps/plugin-opener": "2.2.6", "pinia": "3.0.1", "primeicons": "7.0.0", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 03e0e59..9ec200e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3493,6 +3493,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-dialog", + "tauri-plugin-fs", "tauri-plugin-opener", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 8d4d46e..80e729a 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -23,4 +23,5 @@ tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" tauri-plugin-dialog = "2" +tauri-plugin-fs = "2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 3c1ad59..4f7c3b1 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -8,6 +8,7 @@ "permissions": [ "core:default", "opener:default", - "dialog:default" + "dialog:default", + "fs:default" ] } \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b878ebb..aa18a96 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -7,6 +7,7 @@ fn greet(name: &str) -> String { #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_opener::init()) .invoke_handler(tauri::generate_handler![greet]) diff --git a/src/App.vue b/src/App.vue index 1657b56..9de7773 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,8 +1,9 @@ <script setup lang="ts"> - +import Toast from 'primevue/toast' </script> <template lang="pug"> +Toast main router-view( v-slot='{ Component }' diff --git a/src/main.ts b/src/main.ts index fd77094..3a39623 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { createApp } from 'vue' import { createPinia } from 'pinia' import Aura from '@primeuix/themes/aura' import PrimeVue from 'primevue/config' +import ToastService from 'primevue/toastservice' import 'primeicons/primeicons.css' import { router } from './router' @@ -22,4 +23,5 @@ app }, }, }) + .use(ToastService) .mount('#app') diff --git a/src/store.ts b/src/store.ts new file mode 100644 index 0000000..19056a9 --- /dev/null +++ b/src/store.ts @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia' + +import { type Inventory } from './types/data' + +export const useAppStore = defineStore('appStore', { + state: () => ({ + currentInventory: { + filePath: '', + data: null as Inventory | null, + }, + }), +}) + +export type AppStoreDefinition = Omit< + ReturnType<typeof useAppStore>, + keyof ReturnType<typeof defineStore> +> diff --git a/src/views/Editor.vue b/src/views/Editor.vue index 52fc189..54e01b3 100644 --- a/src/views/Editor.vue +++ b/src/views/Editor.vue @@ -12,39 +12,14 @@ import Select from 'primevue/select' import { FieldTypes, } from '../types/data' +import { useAppStore } from '../store' -const sampleData = ref([ - { - id: 'abc123', - name: 'test a', - category: 'type a', - quantity: 5, - }, - { - id: 'def456', - name: 'test b', - category: 'type a', - quantity: 10, - }, - { - id: 'ghi789', - name: 'test c', - category: 'type b', - quantity: 2, - image: { - src: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Loup_du_Canada_%28Canis_lupus_mackenzii%29.JPG/1280px-Loup_du_Canada_%28Canis_lupus_mackenzii%29.JPG', - alt: 'Loup du Canada', - }, - }, -]) +const appStore = useAppStore() + +const sampleData = ref([...appStore.currentInventory.data?.rows || []]) const editingRows = ref([]) -const sampleFields = ref([ - { name: 'name', type: 'text' }, - { name: 'category', type: 'text' }, - { name: 'quantity', type: 'text' }, - { name: 'image', type: 'image' }, -]) +const sampleFields = ref([...appStore.currentInventory.data?.columns || []]) const editingFields = ref([]) const onRowEditSave = (event: { newData: any, index: number }) => { diff --git a/src/views/Home.vue b/src/views/Home.vue index d983b63..f13fcee 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -4,14 +4,20 @@ import { ref, } from 'vue' import { open } from '@tauri-apps/plugin-dialog' +import { readTextFile } from '@tauri-apps/plugin-fs' import { useRouter } from 'vue-router' +import { useToast } from 'primevue/usetoast' import Button from 'primevue/button' import InputText from 'primevue/inputtext' import InputGroup from 'primevue/inputgroup' import InputGroupAddon from 'primevue/inputgroupaddon' import Panel from 'primevue/panel' +import { useAppStore } from '../store' + const router = useRouter() +const toast = useToast() +const appStore = useAppStore() const filePath = ref('') const fileName = ref('') @@ -32,8 +38,65 @@ const onBrowse = async (e: Event) => { const onCreate = async (e: Event) => { e.preventDefault() + appStore.currentInventory.filePath = `${filePath}/${fileName}.json` + appStore.currentInventory.data = { + columns: [ + { name: 'name', type: 'text' }, + { name: 'location', type: 'text' }, + { name: 'image', type: 'image' }, + ], + rows: [], + } router.push('/editor') } + +const onFind = async (e: Event) => { + e.preventDefault() + + const val = await open({ + multiple: false, + directory: false, + }) + + if (!!val && !Array.isArray(val)) { + let contents: string + try { + contents = await readTextFile(val) + } catch (err) { + toast.add({ + severity: 'error', + summary: 'The file could not be read (permission issue?)', + detail: err, + }) + + return + } + + let json: any + try { + json = JSON.parse(contents) + } catch (err) { + toast.add({ + severity: 'error', + summary: 'The file could not be parsed (invalid json)', + detail: err, + }) + + return + } + + if (!!json.columns && !!json.rows) { + appStore.currentInventory.data = json + appStore.currentInventory.filePath = val + router.push('/editor') + } else { + toast.add({ + severity: 'error', + summary: 'The file is not a valid database for simple-inventory-editor', + }) + } + } +} </script> <template lang="pug"> @@ -42,7 +105,11 @@ section.home-page template(#header) h2 Open Recent File .content - p Not Yet Implemented + InputGroup + Button.submit( + label='Browse...' + @click='onFind' + ) p or... Panel template(#header) diff --git a/tsconfig.json b/tsconfig.json index f82888f..f4b1232 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,8 +16,8 @@ /* Linting */ "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, + "noUnusedLocals": false, + "noUnusedParameters": false, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],