fileupload and sync with backend
This commit is contained in:
parent
1e01ba7439
commit
01ae5558cc
12
README.md
12
README.md
|
@ -1,5 +1,17 @@
|
|||
# billibox-vue
|
||||
|
||||
Datenbank zur Verwaltung alter Kameras und Zubehör.
|
||||
|
||||
Authentifizierung erfolgt über Keycloak open-id-connect
|
||||
|
||||
Backend ist eine in node-js geschriebene Komponente, die JSON-Collections entgegen nimmt.
|
||||
Die Daten werden zunächst lokal in einer IndexedDB vorgehalten und mit dem Backend asynchron gesichert.
|
||||
|
||||
|
||||
Das Backend ist im Projekt billibox-fpg zu finden.
|
||||
|
||||
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"@fortawesome/vue-fontawesome": "^3.0.0-4",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^0.26.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"core-js": "^3.8.3",
|
||||
"fs": "^0.0.1-security",
|
||||
"keycloak-js": "^17.0.1",
|
||||
|
@ -1991,9 +1991,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz",
|
||||
"integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==",
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
@ -4015,15 +4015,21 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
|
||||
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
},
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.10.2"
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
|
@ -4179,9 +4185,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001322",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz",
|
||||
"integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==",
|
||||
"version": "1.0.30001524",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
|
||||
"integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -4191,6 +4197,10 @@
|
|||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -13785,9 +13795,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz",
|
||||
"integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==",
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"peer": true
|
||||
},
|
||||
"@sideway/address": {
|
||||
|
@ -15377,9 +15387,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
|
||||
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||
"requires": {}
|
||||
},
|
||||
"brace-expansion": {
|
||||
|
@ -15487,9 +15497,9 @@
|
|||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001322",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz",
|
||||
"integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==",
|
||||
"version": "1.0.30001524",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
|
||||
"integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
|
||||
"dev": true
|
||||
},
|
||||
"case-sensitive-paths-webpack-plugin": {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"@fortawesome/vue-fontawesome": "^3.0.0-4",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^0.26.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"core-js": "^3.8.3",
|
||||
"fs": "^0.0.1-security",
|
||||
"keycloak-js": "^17.0.1",
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<template>
|
||||
|
||||
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<router-link to="/list" class="nav-link">Startseite</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link to="/shop/item/create" class="nav-link">Neue Kamera</router-link>
|
||||
<router-link to="/admin/camera/create" class="nav-link">Neue Kamera</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link to="/auth" class="nav-link">Auth</router-link>
|
||||
|
|
|
@ -1,14 +1,31 @@
|
|||
<template>
|
||||
|
||||
<div>
|
||||
|
||||
<label for="fileUpload">Datei</label>
|
||||
<input id="fileUpload" type="file"
|
||||
@change="handleFileUpload( $event) "
|
||||
/><br>
|
||||
<button v-on:click="submitFile()">Upload</button>
|
||||
</div>
|
||||
|
||||
<form @submit="submitFile">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="fileDescription">Beschreibung</label>
|
||||
<input id="fileDescription" name="description" type="text"
|
||||
/><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label class="form-label" for="fileUpload">Datei</label>
|
||||
<input class="form-control" id="fileUpload" name="file" type="file"
|
||||
@change="handleFileUpload( $event) "
|
||||
/><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mt-3">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<div class="d-grid">
|
||||
<button class="btn bg-vue">
|
||||
<span v-if="!isLoading">Hochladen</span>
|
||||
<span v-else class="spinner-border spinner-border-sm"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -17,7 +34,16 @@ import axios from 'axios';
|
|||
export default {
|
||||
name: "FileUpload",
|
||||
|
||||
|
||||
props: {
|
||||
store: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
activeStore: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
@ -28,9 +54,10 @@ export default {
|
|||
handleFileUpload(event) {
|
||||
this.file = event.target.files[0];
|
||||
},
|
||||
submitFile() {
|
||||
let formData = new FormData();
|
||||
formData.append('file',this.file);
|
||||
submitFile(event) {
|
||||
event.preventDefault();
|
||||
const form = event.target;
|
||||
let formData = new FormData(form);
|
||||
localStorage.debug = "axios";
|
||||
const api = axios.create({baseURL: 'http://127.0.0.1:4000'})
|
||||
const apiLogger = require('debug')('api');
|
||||
|
@ -48,6 +75,13 @@ export default {
|
|||
|
||||
).then((res) => {
|
||||
console.log("FileUpload Success", res.data);
|
||||
console.log("StoreID Success", this.store.id)
|
||||
|
||||
const uploadItem = {key: res.data.rows[0].key, value: res.data.rows[0].value};
|
||||
this.$store.dispatch("insertNameKeyObject", {
|
||||
storeType: this.store.id,
|
||||
item: uploadItem
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
|
|
|
@ -11,14 +11,13 @@
|
|||
@click="toggleNew"
|
||||
class="billi-store-add billi-close billi-secondary" icon="xmark"/>
|
||||
|
||||
|
||||
<transition
|
||||
enter-active-class="animate__animated animate__fadeInDown"
|
||||
leave-active-class="animate__animated animate__fadeOutUp"
|
||||
mode="out-in"
|
||||
appear
|
||||
>
|
||||
<section class="billi-store-edit" v-if="add && isActive">
|
||||
<section class="billi-store-edit" v-if="add && isActive && this.store.type !== 'filestore'">
|
||||
<Form @submit="submitData" :validation-schema="schema" v-slot="{ errors }">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
|
@ -84,7 +83,7 @@
|
|||
</transition>
|
||||
|
||||
<section class="billi-store-edit" v-if="add && isActive && this.store.type === 'filestore'">
|
||||
<FileUpload></FileUpload>
|
||||
<FileUpload :active-store="activeStore" :store="store" ></FileUpload>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import {urlComponents} from "@/types";
|
||||
|
||||
|
||||
export const backendAPI:urlComponents = {
|
||||
host : 'localhost',
|
||||
port : 4000,
|
||||
protocol : 'http'
|
||||
}
|
||||
|
||||
export const port = process.env.PORT || 3000;
|
||||
|
||||
export const indexDB = {
|
||||
id: 'billibox',
|
||||
version: 3
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
import axios from "axios";
|
||||
import {collectionExists, createCollection, putItem} from "@/store/backend";
|
||||
import {DatabaseItem, NameKeyStore} from "@/store/interfaces/NameKeyStore";
|
||||
|
||||
|
||||
export default class BilliDB {
|
||||
DB_VERSION: number;
|
||||
DB_NAME: string;
|
||||
constructor(dbName:string, dbVersion:number) {
|
||||
BACKEND_URL: string;
|
||||
constructor(dbName:string, dbVersion:number, backendUrl:string) {
|
||||
this.DB_NAME = dbName;
|
||||
this.DB_VERSION = dbVersion;
|
||||
this.BACKEND_URL = backendUrl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,8 +62,33 @@ export default class BilliDB {
|
|||
|
||||
|
||||
async saveItem(item, storeId:string) {
|
||||
const db = await this.getDb();
|
||||
console.log("-->saveItem", storeId, item);
|
||||
const itemClean = {...item}
|
||||
console.log("-->saveItem clean", storeId, itemClean);
|
||||
|
||||
const request = window.indexedDB.open(this.DB_NAME, this.DB_VERSION);
|
||||
request.onsuccess = (event) => {
|
||||
console.log("DB Request done");
|
||||
const transaction = request.result
|
||||
.transaction([storeId], 'readwrite');
|
||||
const objectStore = transaction.objectStore(storeId);
|
||||
|
||||
const requestUpdate = objectStore.put(itemClean);
|
||||
requestUpdate.onsuccess = (event) => {
|
||||
console.log("Data update complete")
|
||||
}
|
||||
|
||||
transaction.oncomplete = (event) => {
|
||||
console.log("Transaction complete")
|
||||
}
|
||||
}
|
||||
|
||||
request.onerror = (err) => {
|
||||
console.log("DB Error" , err)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("Starting Add Transaction");
|
||||
|
||||
|
@ -87,6 +117,7 @@ export default class BilliDB {
|
|||
console.log("onsuccess on Store", e)
|
||||
}
|
||||
})
|
||||
*/
|
||||
}
|
||||
async saveItems(items, storeId:string) {
|
||||
const db = await this.getDb();
|
||||
|
@ -159,6 +190,70 @@ export default class BilliDB {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
async syncDatabase(storeId:string) {
|
||||
console.log("-->syncDatabase");
|
||||
let db;
|
||||
const request = window.indexedDB.open(this.DB_NAME, this.DB_VERSION);
|
||||
request.onsuccess = (event) => {
|
||||
if (navigator.onLine) {
|
||||
db = request.result;
|
||||
console.log("..onsuccess", db)
|
||||
|
||||
for(const collection of db.objectStoreNames) {
|
||||
console.log("working on: ", collection);
|
||||
|
||||
createCollection(collection).then( exist => {
|
||||
console.log(exist);
|
||||
const transaction = db.transaction(collection,'readwrite');
|
||||
const objectStore = transaction.objectStore(collection);
|
||||
console.log("working on objectstore: ", objectStore);
|
||||
const cursorRequest = objectStore.openCursor();
|
||||
cursorRequest.onsuccess = (e) => {
|
||||
const cursor = e.target.result;
|
||||
if(cursor) {
|
||||
const value = cursor.value;
|
||||
console.log(cursor.key, cursor.value, value);
|
||||
|
||||
putItem(collection, value);
|
||||
cursor.continue();
|
||||
} else {
|
||||
console.log("no cursor");
|
||||
}
|
||||
}
|
||||
cursorRequest.onerror = (err) => {
|
||||
console.log("cursor error", err);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
const objectStore = transaction.objectStore('brand111s');
|
||||
const cursorRequest = objectStore.openCursor();
|
||||
|
||||
cursorRequest.onsuccess = (e) => {
|
||||
const cursor = e.target.result;
|
||||
if (cursor) {
|
||||
|
||||
console.log("Cursor: ", cursor.value());
|
||||
|
||||
// axios.put('', cursor.value())
|
||||
// Perform synchronization logic here
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
// Test if we have connection to the Internet
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
56
src/main.ts
56
src/main.ts
|
@ -3,6 +3,7 @@ import App from './App.vue'
|
|||
import store from './store';
|
||||
import router from './router'
|
||||
import VueKeyCloak from '@dsb-norge/vue-keycloak-js'
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
|
||||
import { KeycloakInstance } from "keycloak-js";
|
||||
import { VueKeycloakInstance } from "@dsb-norge/vue-keycloak-js/dist/types";
|
||||
|
@ -23,6 +24,8 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
|||
|
||||
library.add(faUserSecret);
|
||||
|
||||
const SKIP_KEYCLOAK = false;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -46,12 +49,12 @@ createApp(App);
|
|||
app.use(store)
|
||||
app.use(router)
|
||||
app.component("font-awesome-icon", FontAwesomeIcon);
|
||||
app.use(VueKeyCloak, {
|
||||
if (!SKIP_KEYCLOAK) app.use(VueKeyCloak, {
|
||||
config: {
|
||||
url: 'https://auth.toking.de/',
|
||||
realm: 'toking',
|
||||
clientId: 'billibox',
|
||||
redirectUri: 'http://127.0.0.1:8080/',
|
||||
redirectUri: 'http://127.0.0.1:8081/',
|
||||
onLoad: 'login-required',
|
||||
enableLogging: true,
|
||||
scope: 'open-id'
|
||||
|
@ -82,52 +85,3 @@ declare module '@vue/runtime-core' {
|
|||
$keycloak: VueKeycloakInstance
|
||||
}
|
||||
}
|
||||
|
||||
// import Vue from 'vue';
|
||||
// import App from './App.vue';
|
||||
// import Keycloak from "keycloak-js";
|
||||
// const initOptions = {
|
||||
// url: 'https://auth.toking.de/', realm: 'toking', clientId: 'billibox', onLoad: 'login-required',
|
||||
// redirectUri: 'http://127.0.0.1:8080/'
|
||||
// };
|
||||
// //const app = createApp(App);
|
||||
// const keycloak = Keycloak(initOptions);
|
||||
// keycloak.init({ onLoad: 'login-required', redirectUri: 'http://127.0.0.1:8080/' }).then((auth) => {
|
||||
// if (!auth) {
|
||||
// window.location.reload();
|
||||
// }
|
||||
// else {
|
||||
// // @ts-ignore
|
||||
// console.info("Authenticated", auth);
|
||||
// // @ts-ignore
|
||||
//
|
||||
// new Vue({
|
||||
// el: '#app',
|
||||
// render: h => h(App, { props: { keycloak: keycloak } })
|
||||
// });
|
||||
// }
|
||||
// //Token Refresh
|
||||
// // setInterval(() => {
|
||||
// // keycloak.updateToken(70).then((refreshed) => {
|
||||
// // if (refreshed) {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.info('Token refreshed' + refreshed);
|
||||
// // }
|
||||
// // else {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.warn('Token not refreshed, valid for '
|
||||
// // + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
|
||||
// // }
|
||||
// // }).catch(() => {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.error('Failed to refresh token');
|
||||
// // });
|
||||
// // }, 6000);
|
||||
// }).catch(() => {
|
||||
// // @ts-ignore
|
||||
//
|
||||
// console.error("Authenticated Failed");
|
||||
// });
|
||||
|
|
|
@ -62,6 +62,7 @@ export default {
|
|||
else return ['alert-secondary'];
|
||||
},
|
||||
setActiveStore(key) {
|
||||
console.log("setting Active store to: ", key);
|
||||
this.activeStore = key
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import CreateCameraPage from "@/pages/CreateCameraPage.vue";
|
||||
import ReadNameKeyPage from "@/pages/ReadNameKeyPage.vue";
|
||||
const shopRoutes = [
|
||||
{
|
||||
path: "/admin/camera/create",
|
||||
component: CreateCameraPage,
|
||||
meta: {
|
||||
requiresAuth: true
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/admin/namekey",
|
||||
component: ReadNameKeyPage,
|
||||
props: true,
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
// enterTransition: "rubberBand"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/admin/camera/create",
|
||||
// component: CreateCameraPage,
|
||||
// meta: {
|
||||
// requiresAuth: true
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: "/admin/namekey",
|
||||
// component: ReadNameKeyPage,
|
||||
// props: true,
|
||||
// meta: {
|
||||
// requiresAuth: false,
|
||||
// // enterTransition: "rubberBand"
|
||||
// }
|
||||
// },
|
||||
];
|
||||
export default shopRoutes;
|
||||
//# sourceMappingURL=admin-routes.js.map
|
|
@ -142,7 +142,7 @@ export const brands = [
|
|||
description: 'APS-Kameras, Digitalkameras, Kleinbildkameras, Mittelformatkameras.'
|
||||
},
|
||||
{key: 'fandolfi', name: 'Gandolfi', description: 'Großformatkameras.'},
|
||||
{key: 'fottschalt', name: 'Gottschalt', description: 'Fachkameras.'},
|
||||
{key: 'gottschalt', name: 'Gottschalt', description: 'Fachkameras.'},
|
||||
{key: 'hasselblad', name: 'Hasselblad', description: 'Kleinbildkameras, Mittelformatkameras.'},
|
||||
{key: 'hitachi', name: 'Hitachi', description: 'Digitalkameras.'},
|
||||
{key: 'hewlett-Packard (HP)', name: 'Hewlett-Packard (HP)', description: 'Digitalkameras.'},
|
||||
|
@ -300,7 +300,7 @@ export const manufacturers = [
|
|||
description: 'APS-Kameras, Digitalkameras, Kleinbildkameras, Mittelformatkameras.'
|
||||
},
|
||||
{key: 'fandolfi', name: 'Gandolfi', description: 'Großformatkameras.'},
|
||||
{key: 'fottschalt', name: 'Gottschalt', description: 'Fachkameras.'},
|
||||
{key: 'gottschalt', name: 'Gottschalt', description: 'Fachkameras.'},
|
||||
{key: 'hasselblad', name: 'Hasselblad', description: 'Kleinbildkameras, Mittelformatkameras.'},
|
||||
{key: 'hitachi', name: 'Hitachi', description: 'Digitalkameras.'},
|
||||
{key: 'hewlett-Packard (HP)', name: 'Hewlett-Packard (HP)', description: 'Digitalkameras.'},
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import axios from "axios";
|
||||
import {backendAPI, indexDB} from "@/config";
|
||||
import Util from "@/util";
|
||||
import {DatabaseItem} from "@/store/interfaces/NameKeyStore";
|
||||
|
||||
|
||||
export async function collectionExists(collectionName: string) {
|
||||
const apiBase = Util.getURL(backendAPI);
|
||||
const endpoint = `${apiBase}/pgadmin/${indexDB.id}/${collectionName}`;
|
||||
try {
|
||||
const rawResult = await axios.get(endpoint);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function createCollection(collectionName: string) {
|
||||
const apiBase = Util.getURL(backendAPI);
|
||||
const endpoint = `${apiBase}/pgadmin/${indexDB.id}/${collectionName}`;
|
||||
try {
|
||||
const rawResult = await axios.post(endpoint);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function putItem(collectionName: string, item:DatabaseItem) {
|
||||
console.log("-->putItem", item);
|
||||
const apiBase = Util.getURL(backendAPI);
|
||||
const endpoint = `${apiBase}/pg/${indexDB.id}/${collectionName}/${item.key}`;
|
||||
try {
|
||||
const rawResult = await axios.put(endpoint,item);
|
||||
return rawResult.data;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,11 @@
|
|||
interface NameKeyStore {
|
||||
export interface NameKeyStore {
|
||||
name:string;
|
||||
id:string;
|
||||
identifier:string;
|
||||
type:( "nameKey" | "filestore" | "object")
|
||||
}
|
||||
export interface DatabaseItem {
|
||||
key:string,
|
||||
value:object,
|
||||
lastchanged?:Date
|
||||
}
|
|
@ -203,10 +203,11 @@ const mutations = {
|
|||
const actions = {
|
||||
storeNameKeyObject(context, payload) {
|
||||
console.log("actions.storeNameKeyObject", payload);
|
||||
db.saveItem(payload.item, payload.storeType).then((res) => {
|
||||
|
||||
db.saveItem(payload, payload.storeType).then((res) => {
|
||||
console.log("Item stored in Database");
|
||||
});
|
||||
context.commit("storeNameKey", payload.item);
|
||||
context.commit("storeNameKey", {...payload});
|
||||
},
|
||||
insertNameKeyObject(context, payload) {
|
||||
console.log("actions.insertNameKeyObject", payload);
|
||||
|
@ -289,6 +290,7 @@ const actions = {
|
|||
}
|
||||
else {
|
||||
console.log("SEEDING skipped");
|
||||
db.syncDatabase();
|
||||
context.dispatch("loadDataFromLocalDB")
|
||||
.then(() => console.log("Store Data loaded"))
|
||||
.catch((e) => console.log("Error loading StoreData", e));
|
||||
|
|
|
@ -8,9 +8,12 @@ import InventoryItem from "@/store/classes/InventoryItem";
|
|||
import Camera from "@/store/classes/Camera";
|
||||
import Lens from "@/store/classes/Lens";
|
||||
import InventorySet from "@/store/classes/InventorySet";
|
||||
import {backendAPI, indexDB} from "@/config";
|
||||
import Util from "@/util";
|
||||
import {NameKeyStore} from "@/store/interfaces/NameKeyStore";
|
||||
|
||||
|
||||
const db = new BilliDB("billibox", 3);
|
||||
const db = new BilliDB(indexDB.id, 3, Util.getURL(backendAPI));
|
||||
|
||||
|
||||
const stores:NameKeyStore[] = [
|
||||
|
@ -147,7 +150,8 @@ const mutations = {
|
|||
},
|
||||
|
||||
storeNameKey(state:any, payload:any) {
|
||||
const objNK:NameKey = state[payload.storeType].find( (item) => item.key === payload.itemOld.key);
|
||||
console.log("mutation.storeNameKey", state, payload.storeType);
|
||||
const objNK:NameKey = state[payload.storeType].find( (item) => item.key === payload.item.key);
|
||||
if(objNK.key) objNK.key = payload.item.key;
|
||||
objNK.name = payload.item.name;
|
||||
objNK.description = payload.item.description;
|
||||
|
@ -160,7 +164,7 @@ const mutations = {
|
|||
},
|
||||
|
||||
|
||||
setItemActiveState(state:any, payload:any) {
|
||||
setItemActiveState(state:any, payload:any) {
|
||||
console.log("mutation.setItemActiveState");
|
||||
state.inventory.map((item:InventoryItem) => item.active= false);
|
||||
const objItem = state.inventory.find((itemId:InventoryItem) => itemId.key === payload.key);
|
||||
|
@ -257,7 +261,7 @@ const actions = {
|
|||
console.log("Item stored in Database")
|
||||
})
|
||||
|
||||
context.commit("storeNameKey", payload.item);
|
||||
context.commit("storeNameKey", {...payload});
|
||||
|
||||
},
|
||||
|
||||
|
@ -367,6 +371,7 @@ const actions = {
|
|||
localStorage.setItem("SEED_VERSION", seed.SEED_VERSION.toString())
|
||||
} else {
|
||||
console.log("SEEDING skipped");
|
||||
db.syncDatabase("test");
|
||||
context.dispatch("loadDataFromLocalDB")
|
||||
.then(() => console.log("Store Data loaded"))
|
||||
.catch((e) => console.log("Error loading StoreData", e));
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export interface urlComponents {
|
||||
host: string,
|
||||
port: number,
|
||||
protocol: 'http'|'https'
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import {urlComponents} from "@/types";
|
||||
|
||||
export default class Util {
|
||||
|
||||
public static getURL(components:urlComponents) {
|
||||
|
||||
return `${components.protocol}://${components.host}${(components.port)?':'+components.port:''}`;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue