Proof of concept (#6)

* Sample template created

* added findByName functionality for item

* Solve Cors errors and inhibit DefaultExposure

* changed project structure

* Added frontend

* Creation of base template (#1)

* changed base path of REST api and updated frontend api quering
This commit is contained in:
cato
2022-06-02 19:11:46 +02:00
committed by GitHub
parent edaf3c557e
commit f6385b40f6
32 changed files with 7031 additions and 0 deletions

20
frontend/src/Api.js Normal file
View File

@@ -0,0 +1,20 @@
import axios from 'axios'
const SERVER_URL = 'http://localhost:9000'
const instance = axios.create({
baseURL : SERVER_URL,
timeout: 1000
})
export default {
createNew: (name, quantity, unit) => instance.post("/api/v1/items", {name: name, quantity : quantity, unit : unit}),
getAll: () => instance.get('/api/v1/items', {
transformResponse: [function (data) {
return data? JSON.parse(data)._embedded.items : data;
}]
}),
removeForId: (id) => instance.delete('/api/v1/items/'+ id)
}

19
frontend/src/App.vue Normal file
View File

@@ -0,0 +1,19 @@
<template>
<div id="app">
<ItemModel />
</div>
</template>
<script>
import ItemModel from "./components/ItemModel.vue";
export default {
components: {
ItemModel
}
};
</script>
<style>
[v-cloak] {
display: none;
}
</style>

View File

@@ -0,0 +1,125 @@
<template>
<div>
<h1 class="title">Items</h1>
<h1 class="email">{{userEmail}}</h1>
<section class="itemapp">
<div v-if="loading">
<h1 class="loading">Loading...</h1>
</div>
<div v-else>
<header class="header">
<input class="newItemName"
autofocus autocomplete="off"
:placeholder="this.inputPlaceholder"
v-model="newItem"
@keyup.enter="addItem"/>
</header>
<section class="main" v-show="items.length" v-cloak>
<ul class="item-list">
<li v-for="item in items"
class="item"
:key="item.id">
<div class="view">
<label @dblclick="editItem(item)">{{ item.name }} {{ item.quantity }}{{ item.unit }}</label>
<button class="destroy" @click="removeItem(item)"></button>
</div>
</li>
</ul>
</section>
</div>
</section>
</div>
</template>
<script>
import api from '../Api';
const Items = {
name: 'Items',
props: {
activeUser: Object
},
// app initial state
data: function() {
return {
items: [],
newItem: '',
editedItem: null,
loading: true,
error: null,
id: 0
}
},
mounted() {
api.getAll()
.then(response => {
this.$log.debug("Data loaded: ", response.data)
this.items = response.data
})
.catch(error => {
this.$log.debug(error)
this.error = "Failed to load items"
})
.finally(() => this.loading = false)
},
computed: {
userEmail: function () {
return this.activeUser ? this.activeUser.email : ''
},
inputPlaceholder: function () {
return this.activeUser ? this.activeUser.given_name + ', what do you want to add?' : 'What needs to be added'
}
},
methods: {
addItem: function () {
var value = this.newItem && this.newItem.trim()
if (!value) {
return
}
var components = value.split(' ')
api.createNew(components[0],
parseInt(components[1].replace ( /[^\d.]/g, '' )),
components[1].replace(/[0-9]/g, '') === 'ml' ? 'MILLILETERS' : "GRAMMS"
).then( (response) => {
this.$log.debug("New item created:", response);
this.items.push({
id: response.data.id,
name: components[0],
quantity: parseInt(components[1].replace ( /[^\d.]/g, '' )),
unit: components[1].replace(/[0-9]/g, '') === 'MILLILETERS' ? 'ml' : 'g'
})
}).catch((error) => {
this.$log.debug(error);
this.error = "Failed to add item"
});
this.newItem = ''
},
removeItem: function (item) { // notice NOT using "=>" syntax
api.removeForId(item.id).then(() => {
this.$log.debug("Item removed:", item);
this.items.splice(this.items.indexOf(item), 1)
}).catch((error) => {
this.$log.debug(error);
this.error = "Failed to remove item"
})
}
},
directives: {
'item-focus': function (el, binding) {
if (binding.value) {
el.focus()
}
}
}
}
export default Items
</script>

25
frontend/src/main.js Normal file
View File

@@ -0,0 +1,25 @@
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
import VueLogger from 'vuejs-logger';
const options = {
isEnabled: true,
logLevel : 'debug',
stringifyArguments : false,
showLogLevel : true,
showMethodName : false,
separator: '|',
showConsoleColors: true
};
Vue.use(VueLogger, options);
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<App/>',
components: { App }
});