Skip to content

Commit

Permalink
feat: update spa app
Browse files Browse the repository at this point in the history
  • Loading branch information
tanakaworld committed Jun 23, 2019
1 parent 050c68a commit 09fe247
Show file tree
Hide file tree
Showing 23 changed files with 468 additions and 132 deletions.
46 changes: 0 additions & 46 deletions app/javascript/src/spa-app/components/BookList.vue

This file was deleted.

32 changes: 0 additions & 32 deletions app/javascript/src/spa-app/components/BookListItem.vue

This file was deleted.

14 changes: 14 additions & 0 deletions app/javascript/src/spa-app/components/CHeader.vue
@@ -0,0 +1,14 @@
<template>
<header class="CHeader">
<ul>
<li><a href="/books">Books</a></li>
<li><a href="/app/books">Books (SPA)</a></li>
</ul>
</header>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
export default Vue.extend({});
</script>
45 changes: 45 additions & 0 deletions app/javascript/src/spa-app/components/books/BookList.vue
@@ -0,0 +1,45 @@
<template>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Image</th>
<th colspan="3"></th>
</tr>
</thead>

<tbody>
<BookListItem
v-for="book in books"
:key="book.id"
:book="book"
@delete="onDelete"
/>
</tbody>
</table>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import BookListItem from '@spa-app/components/books/BookListItem.vue';
import { Book } from '@gen';
export default Vue.extend({
components: {
BookListItem
},
props: {
books: {
type: Array as () => Book[],
required: true
}
},
methods: {
onDelete(id: number) {
this.$emit('delete', id);
}
}
});
</script>
47 changes: 47 additions & 0 deletions app/javascript/src/spa-app/components/books/BookListItem.vue
@@ -0,0 +1,47 @@
<template>
<tr>
<td>{{ book.title }}</td>
<td>{{ book.description }}</td>
<td>
<img width="50" height="50" :src="book.image_url" />
</td>
<td>
<router-link
:to="{ name: 'book_show_path', params: { book_id: book.id } }"
>Show</router-link
>
</td>
<td>
<router-link
:to="{ name: 'book_edit_path', params: { book_id: book.id } }"
>Edit</router-link
>
</td>
<td>
<a rel="nofollow" @click.prevent="onDelete" href="javascript: void 0;"
>Destroy</a
>
</td>
</tr>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import { Book } from '@gen';
export default Vue.extend({
props: {
book: {
type: Object as () => Book,
required: true
}
},
methods: {
onDelete() {
if (confirm('Are you sure?')) {
this.$emit('delete', this.book.id);
}
}
}
});
</script>
75 changes: 75 additions & 0 deletions app/javascript/src/spa-app/components/books/Form.vue
@@ -0,0 +1,75 @@
<template>
<form @submit="onSubmit">
<div class="field">
<label for="book_title">Title</label>
<input
required="required"
type="text"
name="book[title]"
id="book_title"
v-model="formData.title"
/>
</div>

<div class="field">
<label for="book_description">Description</label>
<textarea
required="required"
name="book[description]"
id="book_description"
v-model="formData.description"
/>
</div>

<div class="field">
<label for="book_image">Image</label>
<input
type="file"
name="book[image]"
id="book_image"
@change="onChangeImage"
/>
</div>

<div class="actions">
<input type="submit" name="commit" value="Save" />
</div>
</form>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import { Book } from '@gen';
export default Vue.extend({
props: {
book: {
type: Object as () => Book,
default: null
}
},
data() {
const { title, description } = this.book
? this.book
: { title: null, description: null };
return {
formData: {
title,
description,
image: void 0
}
};
},
methods: {
onSubmit(e) {
e.preventDefault();
this.$emit('submit', this.formData);
},
onChangeImage(e: any) {
e.preventDefault();
const file = e.target.files[0];
this.formData.image = file ? file : void 0;
}
}
});
</script>
50 changes: 50 additions & 0 deletions app/javascript/src/spa-app/pages/books/Edit.vue
@@ -0,0 +1,50 @@
<template>
<div>
<h1>Editing Book (SPA)</h1>

<book-form :book="book" @submit="onSubmit" />

<router-link :to="{ name: 'book_show_path', params: { book_id: book.id } }"
>Show</router-link
>
|
<router-link :to="{ name: 'books_path' }">Back</router-link>
</div>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import PageFetchHook from '@spa-app/mixins/PageFetchHook';
import BookForm from '@spa-app/components/books/Form.vue';
import store from '@spa-app/store';
import * as BooksModule from '@spa-app/store/modules/books';
const fetch = async params => {
await store.dispatch(BooksModule.GetBook.namespaced({ id: params.book_id }));
};
export default Vue.extend({
mixins: [PageFetchHook(fetch)],
components: {
BookForm
},
computed: {
book() {
return this.$store.getters['books/book'];
}
},
methods: {
async onSubmit(body) {
const bookId = this.$route.params.book_id;
await this.$store.dispatch(
BooksModule.UpdateBook.namespaced({
params: { id: bookId },
body
})
);
this.$router.push({ name: 'books_path' });
}
}
});
</script>
20 changes: 15 additions & 5 deletions app/javascript/src/spa-app/pages/books/Index.vue
@@ -1,18 +1,22 @@
<template>
<div>
<h1>Books</h1>
<h1>Books (SPA)</h1>

<book-list />
<book-list :books="$store.getters['books/books']" @delete="onDelete" />

<br />

<router-link :to="{ name: 'book_new_path' }">New Book</router-link>
</div>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import PageFetchHook from '../../mixins/PageFetchHook';
import BookList from '@spa-app/components/BookList.vue';
import PageFetchHook from '@spa-app/mixins/PageFetchHook';
import BookList from '@spa-app/components/books/BookList.vue';
import store from '@spa-app/store';
import * as BooksModule from '@spa-app/store/modules/books/store';
import * as BooksModule from '@spa-app/store/modules/books';
const fetch = async _params => {
await store.dispatch(BooksModule.GetBooks.namespaced(null));
Expand All @@ -22,6 +26,12 @@ export default Vue.extend({
mixins: [PageFetchHook(fetch)],
components: {
BookList
},
methods: {
async onDelete(id: number) {
await this.$store.dispatch(BooksModule.DeleteBook.namespaced({ id }));
await this.$store.dispatch(BooksModule.GetBooks.namespaced(null));
}
}
});
</script>
32 changes: 32 additions & 0 deletions app/javascript/src/spa-app/pages/books/New.vue
@@ -0,0 +1,32 @@
<template>
<div>
<h1>New Book (SPA)</h1>

<book-form @submit="onSubmit" />

<router-link :to="{ name: 'books_path' }">Back</router-link>
</div>
</template>

<script lang="ts">
import Vue from 'vue/dist/vue.esm';
import BookForm from '@spa-app/components/books/Form.vue';
import * as BooksModule from '@spa-app/store/modules/books';
export default Vue.extend({
components: {
BookForm
},
methods: {
async onSubmit(body) {
await this.$store.dispatch(
BooksModule.CreateBook.namespaced({
body
})
);
this.$router.push({ name: 'books_path' });
}
}
});
</script>

0 comments on commit 09fe247

Please sign in to comment.