Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
WIP 書籍のメタデータを記入できるようにする ku-suke#1
Browse files Browse the repository at this point in the history
  • Loading branch information
mogya committed Nov 15, 2018
1 parent 338ead2 commit 1ba4adb
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 4 deletions.
12 changes: 9 additions & 3 deletions src/containers/Book/Detail/Nav/index.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<template>
<div class="BookNavi">
<div class="BookNavi__Navi">
<div class="BookNavi__Navi" v-if="presenter.projectTree">
<router-link :to="{ name: 'buildSetting', params: { id: presenter.projectTree.props.identifier }}">
<NavItem label="書籍をビルド">
<i class="el-icon-printer" slot="icon" />
</NavItem>
</router-link>
<Nav label="設定">
<Nav label="設定" v-if="presenter.book">
<NavItem label="プロジェクト設定" />
<NavItem label="出版設定" />
<router-link :to="{ name: 'bookSetting', params: { id: presenter.book.identifier }}">
<NavItem label="書籍設定" />
</router-link>
</Nav>
<Nav label="チャプター管理">
<Nav label="チャプター管理" v-if="presenter.projectTree">
<div slot="menu">
<ProjectTreeMenu v-if="presenter.projectTree.props.identifier" @addChapter="registerChapter" @registerPage="registerPage" :identifier="presenter.projectTree.props.identifier" />
</div>
Expand Down Expand Up @@ -46,6 +50,7 @@ import NavItem from "@/components/Base/NavItem.vue";
import ProjectTreeMenu from "@/components/Modules/ProjectTreeMenu.vue";
import ChapterTree from "@/components/Modules/Tree/ChapterTree.vue";
import PageTree from "@/components/Modules/Tree/PageTree.vue";
import BookRepository from "@/repositories/BookRepository";
export default Vue.extend({
components: {
Expand All @@ -64,6 +69,7 @@ export default Vue.extend({
presenter(): IPresenter {
return Presenter({
userRepository: new UserRepository(),
bookRepository: new BookRepository(),
projectTreeRepository: new ProjectTreeRepository(),
pageContentRepository: new PageContentRepository()
});
Expand Down
8 changes: 8 additions & 0 deletions src/containers/Book/Detail/Nav/presenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,36 @@ import UserRepository from "@/repositories/UserRepository";
import ProjectTreeRepository from "@/repositories/ProjectTreeRepository";
import PageContentRepository from "@/repositories/PageContentRepository";
import ProjectTreeEntity from "@/entities/ProjectTree";
import BookRepository from "@/repositories/BookRepository";
import BookEntity from "@/entities/Book";
import { IBook } from "@/entities/Book";

export interface PresenterParams {
userRepository: UserRepository;
bookRepository: BookRepository;
projectTreeRepository: ProjectTreeRepository;
pageContentRepository: PageContentRepository;
}

export interface IPresenter {
userId: string;
book: IBook;
projectTree: ProjectTreeEntity;
currentPage: string | null;
}

export default ({
userRepository,
bookRepository,
projectTreeRepository,
pageContentRepository
}: PresenterParams): IPresenter => {
const currentUser = userRepository.getCurrentUser();
const pageContent = pageContentRepository.getItem();
const item = bookRepository.getItem();
return {
userId: currentUser ? currentUser.uid : "",
book: item ? new BookEntity(item).props : null,
projectTree: projectTreeRepository.getData(),
currentPage: pageContent ? pageContent.props.identifier : null
};
Expand Down
129 changes: 129 additions & 0 deletions src/containers/BookSetting/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>
<div class="wrapper">
<div class="header">
<div class="title">書籍設定</div>
</div>
<div class="content" v-if="presenter.book">
<FormBlock label="書籍名">
<Input v-model="presenter.book.name" placeholder="猫でもわかるflightbooks" :disabled="isLoading"/>
</FormBlock>
<FormBlock label="コピーライト">
<Input v-model="presenter.book.copyright" placeholder="(c)2015 neko" :disabled="isLoading"/>
</FormBlock>
<FormBlock>
<Button text="保存" @click="save" :loading="isLoading" :disabled="isLoading"/>
</FormBlock>
</div>
</div>
</template>

<script lang="ts">
import Vue from "vue";
import moment from "moment";
import Presenter, { IPresenter } from "./presenter";
import FetchBookUseCase from "@/usecases/Book/FetchBookUseCase";
import SaveBookUseCase from "@/usecases/Book/SaveBookUseCase";
import BookEntity from "@/entities/Book";
import BookRepository from "@/repositories/BookRepository";
import ErrorService from "@/services/ErrorService";
import Input from "@/components/Base/Input.vue";
import Select from "@/components/Base/Select.vue";
import FormBlock from "@/components/Base/FormBlock.vue";
import Button, {
Type as ButtonType,
Size as ButtonSize
} from "@/components/Base/Button.vue";
interface IData {
isLoading: boolean;
}
export default Vue.extend({
components: {
FormBlock,
Input,
Button
},
props: {
id: {
type: String,
required: true
}
},
data(): IData {
return {
isLoading: false
};
},
computed: {
presenter(): IPresenter {
let p = Presenter({
bookRepository: new BookRepository()
});
return p;
}
},
methods: {
async fetchBook() {
const usecase = new FetchBookUseCase({
bookRepository: new BookRepository(),
errorService: new ErrorService({ context: "LoadContainer UseCase" })
});
await usecase.execute(this.id);
},
async save() {
this.isLoading = true;
// Bookを保存する
const saveBookUseCase = new SaveBookUseCase({
BookRepository: new BookRepository(),
errorService: new ErrorService({ context: "saveBookJob UseCase" })
});
const item = new BookEntity({
...this.presenter.Book,
identifier: this.id
});
await saveBookUseCase.execute(item);
this.isLoading = false;
alert("Bookを保存しました");
}
},
async mounted() {
await this.fetchBook();
}
});
</script>

<style scoped>
.title {
padding: 24px;
font-size: 24px;
}
.content {
width: 640px;
margin: 0 auto;
}
.select {
box-sizing: border-box;
font-size: 14px;
min-height: 50px;
padding: 10px 18px;
line-height: 30px;
color: #070707;
background-color: #f6f6f6;
outline: none;
border: 1px solid #dadbe3;
border-radius: 4px;
transition: 0.3s;
appearance: none;
}
</style>
19 changes: 19 additions & 0 deletions src/containers/BookSetting/presenter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import UserRepository from "@/repositories/UserRepository";
import BookRepository from "@/repositories/BookRepository";
import BookEntity from "@/entities/Book";
import { IBook } from "@/entities/Book";

export interface PresenterParams {
bookRepository: BookRepository;
}

export interface IPresenter {
book: IBook;
}

export default ({ bookRepository }: PresenterParams): IPresenter => {
const item = bookRepository.getItem();
return {
book: item ? new BookEntity(item).props : null
};
};
46 changes: 46 additions & 0 deletions src/entities/Author.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import firebase from "firebase";
import uuid from "uuid/v4";

export interface IAuthor {
identifier: string;
name: string;
role?: string;
profile?: string;
link?: string;
createdAt: firebase.firestore.Timestamp;
updatedAt: firebase.firestore.Timestamp;
}

export default class AuthorEntity {
private _props: IAuthor;

constructor(params: IAuthor) {
this._props = { ...params };
}

static newAuthor({
name,
role,
profile,
link
}: {
name: string;
role: string;
profile: string;
link: string;
}): AuthorEntity {
return new AuthorEntity({
identifier: uuid(),
name,
role,
profile,
link,
createdAt: firebase.firestore.FieldValue.serverTimestamp() as firebase.firestore.Timestamp,
updatedAt: firebase.firestore.FieldValue.serverTimestamp() as firebase.firestore.Timestamp
});
}

get props(): IAuthor {
return this._props;
}
}
2 changes: 2 additions & 0 deletions src/entities/Book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface IBook {
name: string;
owner: string;
genre?: number;
copyright: string;
createdAt: firebase.firestore.Timestamp;
updatedAt: firebase.firestore.Timestamp;
thumbanilUrl?: string;
Expand Down Expand Up @@ -36,6 +37,7 @@ export default class BookEntity {
identifier: uuid(),
name,
owner,
copyright: "",
projectTreeRef,
createdAt: firebase.firestore.FieldValue.serverTimestamp() as firebase.firestore.Timestamp,
updatedAt: firebase.firestore.FieldValue.serverTimestamp() as firebase.firestore.Timestamp
Expand Down
23 changes: 23 additions & 0 deletions src/pages/BookSetting.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<main class="BookSetting">
<BookSettingContainer :id="$route.params.id" />
</main>
</template>

<script lang="ts">
import Vue from "vue";
import BookSettingContainer from "@/containers/BookSetting/index.vue";
export default Vue.extend({
name: "build",
components: {
BookSettingContainer
}
});
</script>

<style scoped>
.BookSetting {
padding: 0;
}
</style>
20 changes: 19 additions & 1 deletion src/repositories/BookRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "@/store/modules/book/types";
import BookEntity, { IBook } from "@/entities/Book";

const collection = "test-projects";
const collection = "books";

export default class BookRepository {
constructor() {}
Expand Down Expand Up @@ -117,4 +117,22 @@ export default class BookRepository {
.doc(identifier);
await ref.set(itemProps);
}

async save(item: BookEntity) {
const itemProps = item.props;
const identifier = itemProps.identifier;
const serialized = {
...itemProps
};

const ref = firebase
.firestore()
.collection(collection)
.doc(identifier);
await ref.update(serialized);

// fetch item again then update local store
const latestItem = await this.fetchItem(identifier);
this.storeItem(latestItem);
}
}
9 changes: 9 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Router from "vue-router";
import Home from "./pages/Home.vue";
import About from "./pages/About.vue";
import BuildSetting from "./pages/BuildSetting.vue";
import BookSetting from "./pages/BookSetting.vue";
import Project from "./pages/Project.vue";
import Signin from "./pages/Signin.vue";
import Signup from "./pages/Signup.vue";
Expand Down Expand Up @@ -45,6 +46,14 @@ let router = new Router({
requireAuth: true
}
},
{
path: "/projects/:id/bookSetting",
name: "bookSetting",
component: BookSetting,
meta: {
requireAuth: true
}
},
{
path: "/about",
name: "about",
Expand Down
Loading

0 comments on commit 1ba4adb

Please sign in to comment.