Convert recipe to task list

This commit is contained in:
Dan Elbert 2021-05-09 23:31:44 -05:00
parent e15bd576e6
commit 64735b5ee5
7 changed files with 83 additions and 2 deletions

View File

@ -1,7 +1,7 @@
class TaskListsController < ApplicationController class TaskListsController < ApplicationController
before_action :ensure_valid_user before_action :ensure_valid_user
before_action :set_task_list, only: [:show, :update, :destroy] before_action :set_task_list, only: [:show, :update, :destroy, :add_recipe]
def index def index
@task_lists = TaskList.for_user(current_user).includes(:task_items).order(created_at: :desc) @task_lists = TaskList.for_user(current_user).includes(:task_items).order(created_at: :desc)
@ -40,6 +40,16 @@ class TaskListsController < ApplicationController
head :no_content head :no_content
end end
end end
def add_recipe
ensure_owner(@task_list) do
recipe = Recipe.find(params[:recipe_id])
@task_list.add_recipe_ingredients(recipe)
head :no_content
end
end
private private

View File

@ -37,6 +37,11 @@
<div class="message-header"> <div class="message-header">
Ingredients Ingredients
<button class="button is-small is-primary" type="button" @click="showConvertDialog = true">Convert</button> <button class="button is-small is-primary" type="button" @click="showConvertDialog = true">Convert</button>
<app-dropdown :open="addToTasksMenuOpen" label="Add to list" button-class="is-small is-primary" @open="addToTasksMenuOpen = true" @close="addToTasksMenuOpen = false">
<button class="button primary" v-for="tl in taskLists" :key="tl.id" @click="addRecipeToList(tl)">
{{tl.name}}
</button>
</app-dropdown>
</div> </div>
<div class="message-body content"> <div class="message-body content">
<ul v-if="recipe.ingredients.length > 0" v-click-strike> <ul v-if="recipe.ingredients.length > 0" v-click-strike>
@ -143,6 +148,9 @@
<script> <script>
import api from "../lib/Api";
import { mapActions, mapMutations, mapState } from "vuex";
export default { export default {
props: { props: {
recipe: { recipe: {
@ -155,6 +163,7 @@
return { return {
showNutrition: false, showNutrition: false,
showConvertDialog: false, showConvertDialog: false,
addToTasksMenuOpen: false,
scaleValue: '1', scaleValue: '1',
systemConvertValue: "", systemConvertValue: "",
@ -176,6 +185,10 @@
}, },
computed: { computed: {
...mapState([
'taskLists'
]),
timeDisplay() { timeDisplay() {
let a = this.formatMinutes(this.recipe.active_time); let a = this.formatMinutes(this.recipe.active_time);
const t = this.formatMinutes(this.recipe.total_time); const t = this.formatMinutes(this.recipe.total_time);
@ -222,6 +235,23 @@
}, },
methods: { methods: {
...mapActions([
'ensureTaskLists'
]),
...mapMutations([
'setCurrentTaskList'
]),
addRecipeToList(list) {
console.log(list);
api.addRecipeToTaskList(list.id, this.recipe.id)
.then(() => {
this.setCurrentTaskList(list);
this.$router.push({name: 'task_lists'})
});
},
convert() { convert() {
this.showConvertDialog = false; this.showConvertDialog = false;
this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }}); this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }});
@ -256,6 +286,10 @@
return ""; return "";
} }
} }
},
mounted() {
this.ensureTaskLists();
} }
} }

View File

@ -423,6 +423,10 @@ class Api {
return this.patch(`/task_lists/${listId}/task_items/complete`, params); return this.patch(`/task_lists/${listId}/task_items/complete`, params);
} }
addRecipeToTaskList(listId, recipeId) {
return this.patch(`/task_lists/${listId}/add_recipe/${recipeId}`);
}
getAdminUserList() { getAdminUserList() {
return this.get("/admin/users"); return this.get("/admin/users");

View File

@ -186,6 +186,14 @@ export default new Vuex.Store({
return api.getTaskLists(cb) return api.getTaskLists(cb)
}, },
ensureTaskLists({dispatch, state}) {
if (state.user && state.taskLists.length === 0) {
return dispatch("refreshTaskLists");
} else {
return Promise.resolve();
}
},
createTaskList({commit, dispatch}, newList) { createTaskList({commit, dispatch}, newList) {
return api.postTaskList(newList) return api.postTaskList(newList)

View File

@ -9,4 +9,26 @@ class TaskList < ApplicationRecord
scope :for_user, -> (user) { where(user_id: user) } scope :for_user, -> (user) { where(user_id: user) }
def add_recipe_ingredients(recipe, recurse_depth = 0)
if recurse_depth > 10
raise "This shouldn't be. Did you make a recipe loop?"
end
recipe.recipe_ingredients.each do |ri|
if ri.ingredient.is_a?(Recipe)
add_recipe_ingredients(ri.ingredient, recurse_depth + 1)
else
item = self.task_items.detect { |i| i.name.downcase == ri.name.downcase } || TaskItem.new(name: ri.name, task_list: self)
quantity_str = [ri.quantity, ri.units].delete_if { |i| i.blank? }.join(' ')
if item.quantity.blank?
item.quantity = quantity_str
else
item.quantity += (', ' + quantity_str)
end
item.save
end
end
end
end end

View File

@ -41,7 +41,7 @@
} }
#app { #app {
transition: opacity 0.25s ease-in; transition: opacity 0.1s ease-in;
} }
body.loading #app { body.loading #app {

View File

@ -33,6 +33,9 @@ Rails.application.routes.draw do
end end
resources :task_lists, only: [:index, :show, :create, :update, :destroy] do resources :task_lists, only: [:index, :show, :create, :update, :destroy] do
member do
patch 'add_recipe/:recipe_id', action: :add_recipe
end
resources :task_items, only: [:create, :update] do resources :task_items, only: [:create, :update] do
collection do collection do
delete '/', action: :destroy, as: :destroy delete '/', action: :destroy, as: :destroy