-
-
Save andyleach/3525c9bbbd0d732a1f1caed9bcc6b6e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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">–</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