notes work
This commit is contained in:
parent
63a566d697
commit
2da16e334e
@ -77,6 +77,6 @@ class NotesController < ApplicationController
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
def note_params
|
||||
params.require(:note).permit(:user_id, :content)
|
||||
params.require(:note).permit(:content)
|
||||
end
|
||||
end
|
||||
|
57
app/javascript/components/NoteEdit.vue
Normal file
57
app/javascript/components/NoteEdit.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="field">
|
||||
<label class="label">Note</label>
|
||||
<div class="control">
|
||||
<textarea class="textarea" v-model="note.content"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<button type="button" class="button is-primary" :disabled="!canSave" @click="save">
|
||||
Save
|
||||
</button>
|
||||
|
||||
<button type="button" class="button is-secondary" @click="cancel">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
note: {
|
||||
required: true,
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
canSave() {
|
||||
return this.note && this.note.content && this.note.content.length;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
save() {
|
||||
this.$emit("save", this.note);
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.$emit("cancel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
@ -2,11 +2,13 @@
|
||||
<div>
|
||||
<h1 class="title">Ingredients</h1>
|
||||
|
||||
<router-link v-if="isLoggedIn" :to="{name: 'new_ingredient'}" class="button is-primary">Create Ingredient</router-link>
|
||||
<div class="buttons">
|
||||
<router-link v-if="isLoggedIn" :to="{name: 'new_ingredient'}" class="button is-primary">Create Ingredient</router-link>
|
||||
</div>
|
||||
|
||||
<app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="ingredient" @changePage="changePage"></app-pager>
|
||||
|
||||
<table class="table">
|
||||
<table class="table is-fullwidth is-narrow">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
@ -46,6 +48,10 @@
|
||||
|
||||
<app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="ingredient" @changePage="changePage"></app-pager>
|
||||
|
||||
<div class="buttons">
|
||||
<router-link v-if="isLoggedIn" :to="{name: 'new_ingredient'}" class="button is-primary">Create Ingredient</router-link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,11 +1,95 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="buttons">
|
||||
<button type="button" class="button is-primary" @click="addNote">Add Note</button>
|
||||
</div>
|
||||
|
||||
<app-modal title="Add Note" :open="editNote !== null" @dismiss="cancelNote">
|
||||
<note-edit v-if="editNote !== null" :note="editNote" @save="saveNote" @cancel="cancelNote"></note-edit>
|
||||
</app-modal>
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Note</th>
|
||||
<th>Date</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<tr v-for="n in notes" :key="n.id">
|
||||
<td>
|
||||
{{ n.content }}
|
||||
</td>
|
||||
<td>
|
||||
<app-date-time :date-time="n.created_at"></app-date-time>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="button is-danger" @click="deleteNote(n)">
|
||||
<app-icon icon="x"></app-icon>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
import api from "../lib/Api";
|
||||
import NoteEdit from "./NoteEdit";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
notes: [],
|
||||
editNote: null
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
refreshList() {
|
||||
this.loadResource(
|
||||
api.getNoteList()
|
||||
.then(data => this.notes = data)
|
||||
);
|
||||
},
|
||||
|
||||
addNote() {
|
||||
this.editNote = { id: null, content: "" };
|
||||
},
|
||||
|
||||
saveNote() {
|
||||
this.loadResource(
|
||||
api.postNote(this.editNote)
|
||||
.then(() => {
|
||||
this.editNote = null;
|
||||
return this.refreshList();
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
cancelNote() {
|
||||
this.editNote = null;
|
||||
},
|
||||
|
||||
deleteNote(n) {
|
||||
this.loadResource(
|
||||
api.deleteNote(n)
|
||||
.then(() => {
|
||||
return this.refreshList();
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.refreshList();
|
||||
},
|
||||
|
||||
components: {
|
||||
NoteEdit
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -12,8 +12,10 @@ class Api {
|
||||
}
|
||||
|
||||
checkStatus(response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return response;
|
||||
if (response.status == 204) {
|
||||
return null;
|
||||
} else if (response.ok) {
|
||||
return response.json();
|
||||
} else if (response.status === 404) {
|
||||
throw new Errors.ApiNotFoundError(response.statusText, response);
|
||||
} else if (response.status === 422) {
|
||||
@ -32,6 +34,7 @@ class Api {
|
||||
|
||||
const headers = new Headers();
|
||||
headers.append('Accept', 'application/json');
|
||||
headers.append('Content-Type', 'application/json');
|
||||
|
||||
const opts = {
|
||||
headers,
|
||||
@ -40,11 +43,10 @@ class Api {
|
||||
};
|
||||
|
||||
if (hasBody) {
|
||||
headers.append('Content-Type', 'application/json');
|
||||
opts.body = JSON.stringify(params);
|
||||
}
|
||||
|
||||
return fetch(url, opts).then(this.checkStatus).then(this.parseJSON);
|
||||
return fetch(url, opts).then(this.checkStatus);
|
||||
}
|
||||
|
||||
objectToUrlParams(obj, queryParams = [], prefixes = []) {
|
||||
@ -84,6 +86,10 @@ class Api {
|
||||
return this.performRequest(url, "PATCH", params);
|
||||
}
|
||||
|
||||
del(url, params = {}) {
|
||||
return this.performRequest(url, "DELETE", params);
|
||||
}
|
||||
|
||||
getRecipeList(page, per, sortColumn, sortDirection, name, tags) {
|
||||
const params = {
|
||||
criteria: {
|
||||
@ -251,6 +257,22 @@ class Api {
|
||||
return this.get("/ingredients/usda_food_search", {query: query});
|
||||
}
|
||||
|
||||
getNoteList() {
|
||||
return this.get("/notes/");
|
||||
}
|
||||
|
||||
postNote(note) {
|
||||
const params = {
|
||||
content: note.content
|
||||
};
|
||||
|
||||
return this.post("/notes/", params);
|
||||
}
|
||||
|
||||
deleteNote(note) {
|
||||
return this.del("/notes/" + note.id);
|
||||
}
|
||||
|
||||
postLogin(username, password) {
|
||||
const params = {
|
||||
username: username,
|
||||
|
@ -43,6 +43,7 @@ export default new Vuex.Store({
|
||||
},
|
||||
|
||||
setError(state, value) {
|
||||
console.log(value);
|
||||
state.error = value;
|
||||
},
|
||||
|
||||
|
@ -7,6 +7,8 @@ $coolors-green: rgba(121, 167, 54, 1);
|
||||
$coolors-red: #ab4c34;
|
||||
$coolors-yellow: rgba(240, 162, 2, 1);
|
||||
|
||||
$family-serif: Georgia, "Times New Roman", Times, serif;
|
||||
|
||||
// Bluma default overrides
|
||||
//$green: #79A736;
|
||||
//$red: #d4424e;
|
||||
@ -19,6 +21,7 @@ $yellow: $coolors-yellow;
|
||||
$dark: $coolors-dark;
|
||||
|
||||
$primary: $green;
|
||||
$family-primary: $family-serif;
|
||||
|
||||
$modal-content-width: 750px;
|
||||
|
||||
|
@ -34,3 +34,11 @@ body {
|
||||
background-color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.title, .subtitle, .navbar, .button, .pagination, .modal-card-title, th {
|
||||
font-family: $family-sans-serif;
|
||||
}
|
||||
|
||||
.pagination:not(:last-child) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user