Skip to content

Instantly share code, notes, and snippets.

@andyleach
Last active June 12, 2018 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyleach/3525c9bbbd0d732a1f1caed9bcc6b6e6 to your computer and use it in GitHub Desktop.
Save andyleach/3525c9bbbd0d732a1f1caed9bcc6b6e6 to your computer and use it in GitHub Desktop.
<template>
<div class="tab-content" id="myTabContent">
<div class="tab-pane show active fade" id="overview" role="tabpanel" aria-labelledby="overview-tab">
<stock-shares v-model="allocations" :portfolio="portfolio" :balance="balance"/>
</div>
<div class="tab-pane show fade" id="allocations" role="tabpanel" aria-labelledby="allocations-tab">
<portfolio-balance-form v-model.number="balance" :portfolio="portfolio" />
<stock-allocations-form v-model="allocations" :portfolio="portfolio" />
</div>
<div class="tab-pane show fade" id="history" role="tabpanel" aria-labelledby="history-tab">
</div>
</div>
</template>
<script>
export default {
props: ['portfolio'],
data: () => ({
allocations: [],
balance: 10000
}),
mounted() {
this.getAllocations();
this.$on('remove:allocations', this.remove)
this.$on('add:allocations', this.add)
},
methods: {
getAllocations() {
axios.get('/api/portfolios/'+this.portfolio+'/allocations').then(response=> {
this.allocations = response.data;
})
},
getBalance() {
axios.get('/api/portfolios/'+this.portfolio+'/balance').then(response=> {
this.balance = response.data;
})
},
refreshPrices() {
var allocations = this.allocations;
axios.get('/api/batch/stock/prices', {
params: {
symbols: this.getSymbols()
}
}).then(response => {
allocations.map(allocation => {
allocation.price = response.data[allocation.stock.id]
return allocation;
})
this.$emit('update:prices', allocations)
this.$forceUpdate();
})
},
getSymbols() {
var symbols = [];
this.allocations.map(allocation => {
return symbols.push(allocation.stock.id);
})
return symbols;
},
remove(index) {
this.allocations.splice(index, 1)
},
add(item) {
this.allocations.push(item)
}
}
}
</script>
<template>
<div class="card card-default">
<div class="card-header">Allocations</div>
<div class="card-body mt-3 mb-3" v-show="noSlices">
You have not setup your portfolio yet, please begin by adding a slice to your pie.
</div>
<table class="table table-striped" v-show="hasAtLeastOneSlice">
<thead>
<tr>
<th>Ticker</th>
<th>Percent Allocated</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(allocation, index) in allocations">
<td>
<stock-search v-model="allocation.stock" />
</td>
<td>
<input class="form-control" type="text" v-model.number="allocation.allocation">
</td>
<td>
<button class="btn btn-default" @click="remove(index)" v-show="hasAtLeastOneItem">&ndash;</button>
</td>
</tr>
</tbody>
</table>
<div class="card-body text-center pb-0 pt-0" v-show="allocationsOverMax">
<div class="alert alert-danger">
You've allocated over the max of 100%. Your current total allocation is {{ totalAllocated }}%
</div>
</div>
<div class="card-footer text-right">
<button class="btn btn-outline-secondary mr-2" @click="add">Add Slice +</button>
<button class="btn btn-primary" @click="update" :disabled="allocationsOverMax">Update Pie</button>
</div>
</div>
</template>
<script>
export default {
model: {
prop: "allocations",
},
props: ['portfolio', 'allocations'],
computed: {
/**
* There is at least one item in our stock allocations list
*/
hasAtLeastOneItem() {
return this.allocations.length > 1;
},
/**
* Calculate how much of our pie has been allocated
*/
totalAllocated() {
var total = 0;
this.allocations.map(allocation=>{
total+=allocation['allocation']
})
return total
},
/**
* Is the total allocated over 100%
*/
allocationsOverMax() {
return this.totalAllocated > 100;
},
/**
* Do we have any slices
*/
noSlices() {
return this.allocations.length == 0
},
/**
* Is there at least one slice
*/
hasAtLeastOneSlice() {
return this.allocations.length > 0
}
},
methods: {
/**
* Removes an item from the stockAllocations list of selected stocks
* @param item
*/
remove: function (index) {
this.$parent.$emit('remove:allocations', index)
},
/**
* Adds a blank item to the stockAllocations list of selected stocks
* @param event
*/
add() {
this.$parent.$emit('add:allocations', {
allocation: 0,
stock: {
id: '0',
label: 'Select a stock',
},
price: 0
})
},
/**
* Sends a patch request to the server so we can let them know we've changed our allocations
*/
update() {
axios.patch('/api/portfolios/'+this.portfolio+'/allocations', {
});
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment