Skip to content

Commit 0e8972c

Browse files
committed
user can edit budget categories
1 parent f7bd25d commit 0e8972c

7 files changed

Lines changed: 117 additions & 15 deletions

File tree

src/app/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default {
5454
background-color: #02212B;
5555
5656
.brand {
57-
font-size: 36px;
57+
font-size: 24px;
5858
color: #ffffff;
5959
margin: 40px 0 20px 20px;
6060
vertical-align: top;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<template>
2+
<tr class="budget-item">
3+
<td><span class="subtitle is-5">{{ getCategoryById(value.category).name }}</span></td>
4+
<td><span class="subtitle is-5">${{ value.budgeted }}</span></td>
5+
<td><span class="subtitle is-5">${{ value.spent }}</span></td>
6+
<td><span class="subtitle is-5">${{ value.budgeted - value.spent }}</span></td>
7+
<td><a class='button' @click="$emit('edit-budget-category')">Edit</a></td>
8+
</tr>
9+
</template>
10+
11+
<script>
12+
import { mapGetters } from 'vuex';
13+
14+
export default {
15+
name: 'budget-item',
16+
17+
props: ['value'],
18+
19+
computed: {
20+
...mapGetters(['getCategoryById'])
21+
}
22+
};
23+
</script>

src/app/budgets/components/CreateUpdateBudget.vue

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,20 @@
5858
<th>Budgeted</th>
5959
<th>Spent</th>
6060
<th>Remaining</th>
61+
<th></th>
6162
</tr>
6263
</thead>
6364
<tbody>
64-
<tr v-for="bc in selectedBudget.budgetCategories">
65-
<td><span class="subtitle is-5">{{ getCategoryById(bc.category).name }}</span></td>
66-
<td><span class="subtitle is-5">${{ bc.budgeted }}</span></td>
67-
<td><span class="subtitle is-5">${{ bc.spent }}</span></td>
68-
<td><span class="subtitle is-5">${{ bc.budgeted - bc.spent }}</span></td>
69-
</tr>
65+
<template
66+
v-for="value, key in selectedBudget.budgetCategories"
67+
>
68+
<component
69+
:is="budgetCategoryComponent(value)"
70+
v-model="value"
71+
v-on:update-budget-category="saveBudgetCategory"
72+
v-on:edit-budget-category="activeBudgetCategory = value"
73+
></component>
74+
</template>
7075
<CreateUpdateBudgetCategory v-on:add-budget-category="addBudgetCategory"></CreateUpdateBudgetCategory>
7176
</tbody>
7277
<tfoot>
@@ -75,6 +80,7 @@
7580
<td>${{ selectedBudget.budgeted }}</td>
7681
<td>${{ selectedBudget.spent }}</td>
7782
<td>${{ selectedBudget.budgeted - selectedBudget.spent }}</td>
83+
<td></td>
7884
</tr>
7985
</tfoot>
8086
</table>
@@ -90,19 +96,22 @@ import { mapActions, mapGetters } from 'vuex';
9096
import Datepicker from 'vuejs-datepicker';
9197
9298
import CreateUpdateBudgetCategory from './CreateUpdateBudgetCategory';
99+
import BudgetCategory from './BudgetCategory';
93100
94101
export default {
95102
name: 'budget-create-edit-view',
96103
97104
components: {
98105
Datepicker,
99-
CreateUpdateBudgetCategory
106+
CreateUpdateBudgetCategory,
107+
BudgetCategory
100108
},
101109
102110
data: () => {
103111
return {
104112
selectedBudget: {},
105-
editing: false
113+
editing: false,
114+
activeBudgetCategory: null
106115
};
107116
},
108117
@@ -123,7 +132,8 @@ export default {
123132
'createBudget',
124133
'updateBudget',
125134
'loadBudgets',
126-
'createBudgetCategory'
135+
'createBudgetCategory',
136+
'updateBudgetCategory'
127137
]),
128138
129139
resetAndGo () {
@@ -164,6 +174,21 @@ export default {
164174
}).then(() => {
165175
this.selectedBudget = Object.assign({}, this.getBudgetById(this.$route.params.budgetId));
166176
});
177+
},
178+
179+
saveBudgetCategory (budgetCategory) {
180+
// format it how our action expects
181+
budgetCategory.category = budgetCategory.category.id;
182+
this.updateBudgetCategory({
183+
budget: this.selectedBudget,
184+
budgetCategory: budgetCategory
185+
}).then(() => {
186+
this.selectedBudget = Object.assign({}, this.getBudgetById(this.$route.params.budgetId));
187+
});
188+
},
189+
190+
budgetCategoryComponent (budgetCategory) {
191+
return this.activeBudgetCategory && this.activeBudgetCategory === budgetCategory ? 'create-update-budget-category' : 'budget-category';
167192
}
168193
},
169194

src/app/budgets/components/CreateUpdateBudgetCategory.vue

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
<span class="subtitle is-5">${{ budgetCategory.spent }}</span>
2828
</td>
2929

30+
<td></td>
31+
3032
<td>
31-
<a class="button is-primary" @click.prevent="processSave">Add</a>
33+
<a class="button is-primary" @click.prevent="processSave">
34+
{{ editing ? 'Save' : 'Add' }}
35+
</a>
3236
</td>
3337

3438
</tr>
@@ -46,14 +50,27 @@ export default {
4650
Multiselect
4751
},
4852
53+
props: [
54+
'value'
55+
],
56+
4957
data: () => {
5058
return {
51-
budgetCategory: {}
59+
budgetCategory: {},
60+
editing: false
5261
};
5362
},
5463
5564
mounted () {
5665
this.loadCategories();
66+
if (this.value) {
67+
this.budgetCategory = Object.assign({}, this.value);
68+
69+
// we need the selected category name and ID, but the budgetCategory object only holds the ID by default
70+
this.budgetCategory.category = this.getCategoryById(this.budgetCategory.category);
71+
72+
this.editing = true;
73+
}
5774
},
5875
5976
methods: {
@@ -63,8 +80,14 @@ export default {
6380
]),
6481
6582
processSave () {
66-
this.$emit('add-budget-category', this.budgetCategory);
67-
this.budgetCategory = {};
83+
// we are passing the saves up to the budget because this budget
84+
// category view isn't aware of its parent budget object
85+
if (this.editing) {
86+
this.$emit('update-budget-category', this.budgetCategory);
87+
} else {
88+
this.$emit('add-budget-category', this.budgetCategory);
89+
this.budgetCategory = {};
90+
}
6891
},
6992
7093
handleCreateCategory (category) {
@@ -84,7 +107,8 @@ export default {
84107
85108
computed: {
86109
...mapGetters([
87-
'getCategorySelectList'
110+
'getCategorySelectList',
111+
'getCategoryById'
88112
])
89113
}
90114
};

src/app/budgets/vuex/actions.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,21 @@ export const createBudgetCategory = ({ commit, dispatch, getters }, data) => {
9696
value: budgetCategory.budgeted
9797
});
9898
};
99+
100+
export const updateBudgetCategory = ({ commit, dispatch, getters }, data) => {
101+
let newBudget = data.budgetCategory.budgeted;
102+
let oldBudget = getters.getBudgetCategoryById(data.budget.id, data.budgetCategory.id).budgeted;
103+
104+
if (newBudget !== oldBudget) {
105+
dispatch('updateBudgetBalance', {
106+
budget: data.budget,
107+
param: 'budgeted',
108+
value: newBudget - oldBudget
109+
});
110+
}
111+
112+
commit('UPDATE_BUDGET_CATEGORY', data);
113+
114+
// save using the budget in our store
115+
saveBudget(getters.getBudgetById(data.budget.id));
116+
};

src/app/budgets/vuex/getters.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,13 @@ export default {
99

1010
getCategorySelectList: (state, getters) => {
1111
return state.categories && Object.keys(state.categories).length > 0 ? Object.values(state.categories) : [];
12+
},
13+
14+
getBudgetCategoryById: (state, getters) => (budgetId, budgetCategoryId) => {
15+
return state.budgets && budgetId in state.budgets
16+
? state.budgets[budgetId].budgetCategories && budgetCategoryId in state.budgets[budgetId].budgetCategories
17+
? state.budgets[budgetId].budgetCategories[budgetCategoryId]
18+
: false
19+
: false;
1220
}
1321
};

src/app/budgets/vuex/mutations.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,9 @@ export default {
3939

4040
CREATE_BUDGET_CATEGORY (state, payload) {
4141
Vue.set(state.budgets[payload.budget.id].budgetCategories, payload.budgetCategory.id, payload.budgetCategory);
42+
},
43+
44+
UPDATE_BUDGET_CATEGORY (state, payload) {
45+
state.budgets[payload.budget.id].budgetCategories[payload.budgetCategory.id] = payload.budgetCategory;
4246
}
4347
};

0 commit comments

Comments
 (0)