logs
This commit is contained in:
parent
2da16e334e
commit
46072422d4
@ -2,12 +2,11 @@ class LogsController < ApplicationController
|
|||||||
|
|
||||||
before_action :ensure_valid_user
|
before_action :ensure_valid_user
|
||||||
|
|
||||||
before_action :set_log, only: [:show, :edit, :update, :destroy]
|
before_action :set_log, only: [:show, :update, :destroy]
|
||||||
before_action :set_recipe, only: [:new, :create]
|
|
||||||
before_action :require_recipe, only: [:new, :create]
|
before_action :require_recipe, only: [:new, :create]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@logs = Log.for_user(current_user).order(:date)
|
@logs = Log.for_user(current_user).order(:date).page(params[:page]).per(params[:per])
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@ -45,9 +44,9 @@ class LogsController < ApplicationController
|
|||||||
@log.source_recipe = @recipe
|
@log.source_recipe = @recipe
|
||||||
|
|
||||||
if @log.save
|
if @log.save
|
||||||
redirect_to logs_path, notice: 'Log Entry was successfully created.'
|
render json: { success: true }
|
||||||
else
|
else
|
||||||
render :new
|
render json: @log.errors, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
h = h.toString().padStart(2, "0");
|
h = h.toString().padStart(2, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
return h + ":" + m + " " + meridiem;
|
return h + ":" + m + meridiem;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
<router-link to="/" class="navbar-item">Recipes</router-link>
|
<router-link to="/" class="navbar-item">Recipes</router-link>
|
||||||
<router-link to="/ingredients" class="navbar-item">Ingredients</router-link>
|
<router-link to="/ingredients" class="navbar-item">Ingredients</router-link>
|
||||||
<router-link to="/calculator" class="navbar-item">Calculator</router-link>
|
<router-link to="/calculator" class="navbar-item">Calculator</router-link>
|
||||||
<router-link to="/about" class="navbar-item">About</router-link>
|
<router-link v-if="isLoggedIn" to="/logs" class="navbar-item">Log</router-link>
|
||||||
<router-link v-if="isLoggedIn" to="/notes" class="navbar-item">Notes</router-link>
|
<router-link v-if="isLoggedIn" to="/notes" class="navbar-item">Notes</router-link>
|
||||||
|
<router-link to="/about" class="navbar-item">About</router-link>
|
||||||
<a v-if="isAdmin" class="navbar-item" href="/admin/users">Admin</a>
|
<a v-if="isAdmin" class="navbar-item" href="/admin/users">Admin</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
48
app/javascript/components/AppTextField.vue
Normal file
48
app/javascript/components/AppTextField.vue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div class="field">
|
||||||
|
<label v-if="label.length" class="label is-small-mobile">{{ label }}</label>
|
||||||
|
<div class="control">
|
||||||
|
<textarea v-if="isTextarea" class="textarea is-small-mobile" :value="value" @input="input"></textarea>
|
||||||
|
<input v-else :type="type" class="input is-small-mobile" :value="value" @input="input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
label: {
|
||||||
|
required: false,
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
required: false,
|
||||||
|
type: [String, Number],
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
required: false,
|
||||||
|
type: String,
|
||||||
|
default: "text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isTextarea() {
|
||||||
|
return this.type === "textarea";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
input(evt) {
|
||||||
|
this.$emit("input", evt.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
39
app/javascript/components/LogEdit.vue
Normal file
39
app/javascript/components/LogEdit.vue
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<h1 class="title">Creating Log for {{ log.recipe.name }}</h1>
|
||||||
|
|
||||||
|
<p>Edit Rating</p>
|
||||||
|
|
||||||
|
<p>Edit Date</p>
|
||||||
|
|
||||||
|
<app-text-field label="Notes" :value="log.notes" type="textarea"></app-text-field>
|
||||||
|
|
||||||
|
<recipe-edit :recipe="log.recipe" :for-logging="true"></recipe-edit>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import RecipeEdit from "./RecipeEdit";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
log: {
|
||||||
|
required: true,
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
RecipeEdit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
14
app/javascript/components/LogShow.vue
Normal file
14
app/javascript/components/LogShow.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
@ -1,65 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="title">{{ action }} {{ recipe.name || "[Unamed Recipe]" }}</h1>
|
<template v-if="!forLogging">
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<app-text-field label="Name" v-model="recipe.name"></app-text-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
|
<app-text-field label="Source" v-model="recipe.source"></app-text-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-text-field label="Description" type="textarea" v-model="recipe.description"></app-text-field>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label is-small-mobile">Tags</label>
|
||||||
|
<app-tag-editor v-model="recipe.tags"></app-tag-editor>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="field">
|
<app-text-field label="Yields" v-model="recipe.yields"></app-text-field>
|
||||||
<label class="label is-small-mobile">Name</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input is-small-mobile" type="text" placeholder="name" v-model="recipe.name">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="field">
|
<app-text-field label="Total Time" type="number" v-model="recipe.total_time"></app-text-field>
|
||||||
<label class="label is-small-mobile">Source</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input is-small-mobile" type="text" placeholder="source" v-model="recipe.source">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<label class="label is-small-mobile">Description</label>
|
|
||||||
<div class="control">
|
|
||||||
<textarea class="textarea is-small-mobile" placeholder="description" v-model="recipe.description"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<label class="label is-small-mobile">Tags</label>
|
|
||||||
<app-tag-editor v-model="recipe.tags"></app-tag-editor>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label is-small-mobile">Yields</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input is-small-mobile" type="text" placeholder="servings" v-model="recipe.yields">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="field">
|
<app-text-field label="Active Time" v-model="recipe.active_time"></app-text-field>
|
||||||
<label class="label is-small-mobile">Total Time</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input is-small-mobile" type="number" placeholder="minutes" v-model="recipe.total_time">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label is-small-mobile">Active Time</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input is-small-mobile" type="number" placeholder="minutes" v-model="recipe.active_time">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -98,10 +70,10 @@
|
|||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
},
|
},
|
||||||
action: {
|
forLogging: {
|
||||||
required: false,
|
required: false,
|
||||||
type: String,
|
type: Boolean,
|
||||||
default: "Editing"
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
14
app/javascript/components/TheLog.vue
Normal file
14
app/javascript/components/TheLog.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
63
app/javascript/components/TheLogCreator.vue
Normal file
63
app/javascript/components/TheLogCreator.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<log-edit v-if="log.recipe !== null" :log="log"></log-edit>
|
||||||
|
|
||||||
|
<button type="button" class="button is-primary" @click="save">Save</button>
|
||||||
|
<router-link class="button is-secondary" to="/">Cancel</router-link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import LogEdit from "./LogEdit";
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import api from "../lib/Api";
|
||||||
|
import * as Errors from '../lib/Errors';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
validationErrors: [],
|
||||||
|
log: {
|
||||||
|
date: null,
|
||||||
|
rating: null,
|
||||||
|
notes: null,
|
||||||
|
recipe: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
recipeId: state => state.route.params.recipeId,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
save() {
|
||||||
|
this.loadResource(
|
||||||
|
api.postLog(this.log)
|
||||||
|
.then(() => this.$router.push('/'))
|
||||||
|
.catch(Errors.onlyFor(Errors.ApiValidationError, err => this.validationErrors = err.validationErrors()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.loadResource(
|
||||||
|
api.getRecipe(this.recipeId)
|
||||||
|
.then(data => { this.log.recipe = data; return data; })
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
LogEdit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
14
app/javascript/components/TheLogEditor.vue
Normal file
14
app/javascript/components/TheLogEditor.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
93
app/javascript/components/TheLogList.vue
Normal file
93
app/javascript/components/TheLogList.vue
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="title">
|
||||||
|
Log Entries
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Recipe</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Rating</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr v-for="l in logs" :key="l.id">
|
||||||
|
<td>{{l.recipe.name}}</td>
|
||||||
|
<td>l.date</td>
|
||||||
|
<td>l.rating</td>
|
||||||
|
<td>l.notes</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import api from "../lib/Api";
|
||||||
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
logData: null,
|
||||||
|
search: {
|
||||||
|
page: 1,
|
||||||
|
per: 25
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
logs() {
|
||||||
|
if (this.logData) {
|
||||||
|
return this.logData.logs;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
totalPages() {
|
||||||
|
if (this.logData) {
|
||||||
|
return this.logData.total_pages
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
currentPage() {
|
||||||
|
if (this.logData) {
|
||||||
|
return this.logData.current_page
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
changePage(idx) {
|
||||||
|
this.search.page = idx;
|
||||||
|
},
|
||||||
|
|
||||||
|
getList: debounce(function() {
|
||||||
|
this.loadResource(
|
||||||
|
api.getLogList(this.search.page, this.search.per)
|
||||||
|
.then(data => this.logData = data)
|
||||||
|
);
|
||||||
|
}, 500, {leading: true, trailing: true})
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.$watch("search",
|
||||||
|
() => this.getList(),
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
<h1 class="title">Creating {{ recipe.name || "[Unamed Recipe]" }}</h1>
|
||||||
|
|
||||||
<recipe-edit :recipe="recipe" action="Creating"></recipe-edit>
|
<recipe-edit :recipe="recipe" action="Creating"></recipe-edit>
|
||||||
|
|
||||||
<button type="button" class="button is-primary" @click="save">Save</button>
|
<button type="button" class="button is-primary" @click="save">Save</button>
|
||||||
@ -12,13 +14,13 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import RecipeEdit from "./RecipeEdit";
|
import RecipeEdit from "./RecipeEdit";
|
||||||
import { mapState } from "vuex";
|
|
||||||
import api from "../lib/Api";
|
import api from "../lib/Api";
|
||||||
import * as Errors from '../lib/Errors';
|
import * as Errors from '../lib/Errors';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
validationErrors: [],
|
||||||
recipe: {
|
recipe: {
|
||||||
name: null,
|
name: null,
|
||||||
source: null,
|
source: null,
|
||||||
@ -33,12 +35,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
recipeId: state => state.route.params.id,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
save() {
|
save() {
|
||||||
this.loadResource(
|
this.loadResource(
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
<h1 class="title">Editing {{ recipe.name || "[Unamed Recipe]" }}</h1>
|
||||||
<recipe-edit :recipe="recipe"></recipe-edit>
|
<recipe-edit :recipe="recipe"></recipe-edit>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -52,6 +52,9 @@
|
|||||||
<td>{{ formatRecipeTime(r.total_time, r.active_time) }}</td>
|
<td>{{ formatRecipeTime(r.total_time, r.active_time) }}</td>
|
||||||
<td><app-date-time :date-time="r.created_at" :show-time="false"></app-date-time></td>
|
<td><app-date-time :date-time="r.created_at" :show-time="false"></app-date-time></td>
|
||||||
<td>
|
<td>
|
||||||
|
<router-link v-if="isLoggedIn" :to="{name: 'new_log', params: { recipeId: r.id } }" class="button is-primary">
|
||||||
|
<app-icon icon="star" size="md"></app-icon>
|
||||||
|
</router-link>
|
||||||
<router-link v-if="isLoggedIn" :to="{name: 'edit_recipe', params: { id: r.id } }" class="button is-primary">
|
<router-link v-if="isLoggedIn" :to="{name: 'edit_recipe', params: { id: r.id } }" class="button is-primary">
|
||||||
<app-icon icon="pencil" size="md"></app-icon>
|
<app-icon icon="pencil" size="md"></app-icon>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -273,6 +273,35 @@ class Api {
|
|||||||
return this.del("/notes/" + note.id);
|
return this.del("/notes/" + note.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLogList(page, per) {
|
||||||
|
const params = {
|
||||||
|
page,
|
||||||
|
per
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.get("/logs", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildLogParams(log) {
|
||||||
|
return {
|
||||||
|
log: {
|
||||||
|
date: log.date,
|
||||||
|
rating: log.rating,
|
||||||
|
notes: log.notes,
|
||||||
|
source_recipe_id: log.source_recipe_id,
|
||||||
|
recipe_attributes: this.buildRecipeParams(log.recipe)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
postLog(log) {
|
||||||
|
return this.post("/logs/", this.buildLogParams(log));
|
||||||
|
}
|
||||||
|
|
||||||
|
patchLog(log) {
|
||||||
|
return this.patch("/logs/" + log.id, this.buildLogParams(log));
|
||||||
|
}
|
||||||
|
|
||||||
postLogin(username, password) {
|
postLogin(username, password) {
|
||||||
const params = {
|
const params = {
|
||||||
username: username,
|
username: username,
|
||||||
|
@ -17,6 +17,7 @@ import AppNavbar from "../components/AppNavbar";
|
|||||||
import AppPager from "../components/AppPager";
|
import AppPager from "../components/AppPager";
|
||||||
import AppRating from "../components/AppRating";
|
import AppRating from "../components/AppRating";
|
||||||
import AppTagEditor from "../components/AppTagEditor";
|
import AppTagEditor from "../components/AppTagEditor";
|
||||||
|
import AppTextField from "../components/AppTextField";
|
||||||
|
|
||||||
Vue.component("AppAutocomplete", AppAutocomplete);
|
Vue.component("AppAutocomplete", AppAutocomplete);
|
||||||
Vue.component("AppDateTime", AppDateTime);
|
Vue.component("AppDateTime", AppDateTime);
|
||||||
@ -26,6 +27,7 @@ Vue.component("AppNavbar", AppNavbar);
|
|||||||
Vue.component("AppPager", AppPager);
|
Vue.component("AppPager", AppPager);
|
||||||
Vue.component("AppRating", AppRating);
|
Vue.component("AppRating", AppRating);
|
||||||
Vue.component("AppTagEditor", AppTagEditor);
|
Vue.component("AppTagEditor", AppTagEditor);
|
||||||
|
Vue.component("AppTextField", AppTextField);
|
||||||
|
|
||||||
|
|
||||||
Vue.use(VueProgressBar, {
|
Vue.use(VueProgressBar, {
|
||||||
|
@ -4,6 +4,12 @@ import Router from 'vue-router';
|
|||||||
import The404Page from './components/The404Page';
|
import The404Page from './components/The404Page';
|
||||||
import TheAboutPage from './components/TheAboutPage';
|
import TheAboutPage from './components/TheAboutPage';
|
||||||
import TheCalculator from './components/TheCalculator';
|
import TheCalculator from './components/TheCalculator';
|
||||||
|
|
||||||
|
import TheLog from './components/TheLog';
|
||||||
|
import TheLogList from './components/TheLogList';
|
||||||
|
import TheLogCreator from './components/TheLogCreator';
|
||||||
|
import TheLogEditor from './components/TheLogEditor';
|
||||||
|
|
||||||
import TheIngredientList from './components/TheIngredientList';
|
import TheIngredientList from './components/TheIngredientList';
|
||||||
import TheIngredient from "./components/TheIngredient";
|
import TheIngredient from "./components/TheIngredient";
|
||||||
import TheIngredientEditor from "./components/TheIngredientEditor";
|
import TheIngredientEditor from "./components/TheIngredientEditor";
|
||||||
@ -76,6 +82,26 @@ router.addRoutes(
|
|||||||
name: "ingredient",
|
name: "ingredient",
|
||||||
component: TheIngredient
|
component: TheIngredient
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/logs",
|
||||||
|
name: "logs",
|
||||||
|
component: TheLogList
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/recipes/:recipeId/logs/new",
|
||||||
|
name: "new_log",
|
||||||
|
component: TheLogCreator
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/logs/:id/edit",
|
||||||
|
name: "edit_log",
|
||||||
|
component: TheLogEditor
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/logs/:id",
|
||||||
|
name: "log",
|
||||||
|
component: TheLog
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/notes",
|
path: "/notes",
|
||||||
name: "notes",
|
name: "notes",
|
||||||
|
16
app/views/logs/index.json.jbuilder
Normal file
16
app/views/logs/index.json.jbuilder
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
json.cache_root! [Log.all, @logs] do
|
||||||
|
|
||||||
|
json.extract! @logs, :total_count, :total_pages, :current_page
|
||||||
|
json.page_size @logs.limit_value
|
||||||
|
|
||||||
|
json.logs @logs do |l|
|
||||||
|
json.extract! l, :id, :date, :rating, :notes
|
||||||
|
|
||||||
|
json.recipe do
|
||||||
|
json.id l.recipe.id
|
||||||
|
json.name l.recipe.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user