add /inventory page

This commit is contained in:
j3d1 2024-04-11 21:21:14 +02:00
parent 9770ca861a
commit 8716d3f692
8 changed files with 329 additions and 5 deletions

View file

@ -9,6 +9,12 @@
<li class="sidebar-header">
Tools & Components
</li>
<li class="sidebar-item">
<router-link to="/inventory" class="sidebar-link">
<b-icon-archive class="bi-valign-middle"></b-icon-archive>
<span class="align-middle">Inventory</span>
</router-link>
</li>
<li class="sidebar-item">
<router-link to="/friends" class="sidebar-link">
<b-icon-people class="bi-valign-middle"></b-icon-people>

View file

@ -13,9 +13,13 @@ function get_prefered_server() {
request.open('GET', '/local/dns', false);
request.send(null);
if (request.status === 200) {
const servers = JSON.parse(request.responseText);
if (servers && servers.length > 0) {
return servers;
try {
const servers = JSON.parse(request.responseText);
if (servers && servers.length > 0) {
return servers;
}
} catch (e) {
console.error(e);
}
}
return ['1.1.1.1', '8.8.8.8'];

View file

@ -4,10 +4,12 @@ import Login from '@/views/Login.vue';
import Register from '@/views/Register.vue';
import store from '@/store';
import Friends from "@/views/Friends.vue";
import Inventory from '@/views/Inventory.vue';
const routes = [
{path: '/', component: Dashboard, meta: {requiresAuth: true}},
{path: '/inventory', component: Inventory, meta: {requiresAuth: true}},
{path: '/friends', component: Friends, meta: {requiresAuth: true}},
{path: '/login', component: Login, meta: {requiresAuth: false}},
{path: '/register', component: Register, meta: {requiresAuth: false}},

View file

@ -13,10 +13,13 @@ export default createStore({
token: null,
keypair: null,
remember: false,
friends: [],
item_map: {},
home_servers: null,
all_friends_servers: null,
resolver: new FallBackResolver(),
unreachable_neighbors: new NeighborsCache(),
availability_policies: [],
},
mutations: {
setUser(state, user) {
@ -43,6 +46,9 @@ export default createStore({
}
localStorage.setItem('remember', remember);
},
setInventoryItems(state, {url, items}) {
state.item_map[url] = items;
},
setFriends(state, friends) {
state.friends = friends;
},
@ -52,6 +58,9 @@ export default createStore({
setAllFriendsServers(state, servers) {
state.all_friends_servers = servers;
},
setAvailabilityPolicies(state, availability_policies) {
state.availability_policies = availability_policies;
},
logout(state) {
state.user = null;
state.token = null;
@ -128,6 +137,13 @@ export default createStore({
async getFriendServers({state, dispatch, commit}, {username}) {
return dispatch('lookupServer', {username}).then(servers => new ServerSet(servers, state.unreachable_neighbors))
},
async fetchInventoryItems({commit, dispatch, getters}) {
const servers = await dispatch('getHomeServers')
const items = await servers.get(getters.signAuth, '/api/inventory_items/')
items.map(item => item.files.map(file => file.owner = item.owner))
commit('setInventoryItems', {url: '/', items})
return items
},
async fetchFriends({commit, dispatch, getters, state}) {
const servers = await dispatch('getHomeServers')
const data = await servers.get(getters.signAuth, '/api/friends/')
@ -205,5 +221,13 @@ export default createStore({
nullAuth(state) {
return createNullAuth({})
},
inventory_items(state) {
return state.item_map['/'] || []
},
loaded_items(state) {
return Object.entries(state.item_map).reduce((acc, [url, items]) => {
return acc.concat(items)
}, [])
},
}
})

View file

@ -0,0 +1,70 @@
<template>
<BaseLayout>
<main class="content">
<div class="container-fluid p-0">
<div class="row">
<div class="col-12 col-xl-6">
<div class="card">
<div class="card-header">
<h5 class="card-title">{{ user }}'s Inventory</h5>
</div>
<table class="table table-striped">
<thead>
<tr>
<th style="width:40%;">Name</th>
<th style="width:25%">Availability Policy</th>
<th class="d-none d-md-table-cell" style="width:25%">Amount</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in inventory_items" :key="item.id">
<td>
{{ item.name }}
</td>
<td class="d-none d-md-table-cell">{{ item.availability_policy }}</td>
<td class="d-none d-md-table-cell">{{ item.owned_quantity }}</td>
<td class="table-action">
</td>
</tr>
</tbody>
</table>
</div>
<div class="card">
<button class="btn" @click="fetchInventoryItems">Refresh</button>
<router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
</div>
</div>
</div>
</div>
</main>
</BaseLayout>
</template>
<script>
import {mapActions, mapGetters, mapMutations, mapState} from "vuex";
import * as BIcons from "bootstrap-icons-vue";
import BaseLayout from "@/components/BaseLayout.vue";
export default {
name: "Inventory",
components: {
BaseLayout,
...BIcons
},
computed: {
...mapGetters(["inventory_items", "loaded_items"]),
...mapState(["user"]),
},
methods: {
...mapActions(["fetchInventoryItems", "deleteInventoryItem"]),
},
async mounted() {
await this.fetchInventoryItems()
}
}
</script>
<style scoped>
</style>