From eb8a5e0186826cedc4a4b3358c44ae815441c29e Mon Sep 17 00:00:00 2001 From: solaris0051 <30798030+solaris0051@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:43:17 +0900 Subject: [PATCH] dep & revised --- controllers/authorController.js | 2 +- controllers/bookController.js | 55 ++++++++++++++------------- controllers/bookinstanceController.js | 22 +++++++---- controllers/genreController.js | 2 +- package-lock.json | 16 ++++---- package.json | 4 +- views/author_delete.pug | 2 +- views/author_detail.pug | 12 +++--- views/author_form.pug | 6 +-- views/author_list.pug | 2 +- views/book_delete.pug | 10 +++-- views/book_detail.pug | 2 +- views/book_form.pug | 24 +++++++----- views/book_list.pug | 16 ++++---- views/bookinstance_delete.pug | 4 +- views/bookinstance_form.pug | 28 +++++++------- views/bookinstance_list.pug | 30 +++++++-------- views/genre_delete.pug | 12 +++--- views/genre_detail.pug | 13 +++---- views/genre_form.pug | 4 +- views/genre_list.pug | 13 +++---- 21 files changed, 148 insertions(+), 131 deletions(-) diff --git a/controllers/authorController.js b/controllers/authorController.js index 40c47f7..b639481 100644 --- a/controllers/authorController.js +++ b/controllers/authorController.js @@ -111,7 +111,7 @@ exports.author_delete_post = asyncHandler(async (req, res, next) => { }); return; } else { - await Author.findByIdAndRemove(req.body.authorid); + await Author.findByIdAndDelete(req.body.authorid); res.redirect("/catalog/authors"); } }); diff --git a/controllers/bookController.js b/controllers/bookController.js index 0ef73a8..481c57d 100644 --- a/controllers/bookController.js +++ b/controllers/bookController.js @@ -18,7 +18,7 @@ exports.index = asyncHandler(async (req, res, next) => { BookInstance.countDocuments({}).exec(), BookInstance.countDocuments({ status: "貸出可能" }).exec(), Author.countDocuments({}).exec(), - Author.countDocuments({}).exec(), + Genre.countDocuments({}).exec(), ]); res.render("index", { title: "書籍管理ホーム", @@ -58,8 +58,8 @@ exports.book_detail = asyncHandler(async (req, res, next) => { exports.book_create_get = asyncHandler(async (req, res, next) => { const [allAuthors, allGenres] = await Promise.all([ - Author.find().exec(), - Genre.find().exec(), + Author.find().sort({ family_name: 1 }).exec(), + Genre.find().sort({ name: 1 }).exec(), ]); res.render("book_form", { title: "書籍登録フォーム", @@ -70,9 +70,8 @@ exports.book_create_get = asyncHandler(async (req, res, next) => { exports.book_create_post = [ (req, res, next) => { - if (!(req.body.genre instanceof Array)) { - if (typeof req.body.genre === "undefined") req.body.genre = []; - else req.body.genre = new Array(req.body.genre); + if (!Array.isArray(req.body.genre)) { + req.body.genre = typeof req.body.genre === "undefined" ? [] : [req.body.genre]; } next(); }, @@ -88,8 +87,12 @@ exports.book_create_post = [ .trim() .isLength({ min: 1 }) .escape(), - body("isbn", "ISBNを指定してください。").trim().isLength({ min: 1 }).escape(), - body("genre.*").escape(), + body("isbn", "ISBNを指定してください。") + .trim() + .isLength({ min: 1 }) + .escape(), + body("genre.*") + .escape(), asyncHandler(async (req, res, next) => { const errors = validationResult(req); const book = new Book({ @@ -101,8 +104,8 @@ exports.book_create_post = [ }); if (!errors.isEmpty()) { const [allAuthors, allGenres] = await Promise.all([ - Author.find().exec(), - Genre.find().exec(), + Author.find().sort({ family_name: 1 }).exec(), + Genre.find().sort({ name: 1 }).exec(), ]); for (const genre of allGenres) { if (book.genre.indexOf(genre._id) > -1) { @@ -154,29 +157,25 @@ exports.book_delete_post = asyncHandler(async (req, res, next) => { }); return; } else { - await Book.findByIdAndRemove(req.body.id); + await Book.findByIdAndDelete(req.body.id); res.redirect("/catalog/books"); } }); exports.book_update_get = asyncHandler(async (req, res, next) => { const [book, allAuthors, allGenres] = await Promise.all([ - Book.findById(req.params.id).populate("author").populate("genre").exec(), - Author.find().exec(), - Genre.find().exec(), + Book.findById(req.params.id).populate("author").exec(), + Author.find().sort({ family_name: 1 }).exec(), + Genre.find().sort({ name: 1 }).exec(), ]); if (book === null) { const err = new Error("書籍がありません。"); err.status = 404; return next(err); } - for (const genre of allGenres) { - for (const book_g of book.genre) { - if (genre._id.toString() === book_g._id.toString()) { - genre.checked = "true"; - } - } - } + allGenres.forEach(genre => { + if (book.genre.includes(genre._id)) genre.checked = "true"; + }); res.render("book_form", { title: "書籍更新", authors: allAuthors, @@ -208,8 +207,12 @@ exports.book_update_post = [ .trim() .isLength({ min: 1 }) .escape(), - body("isbn", "ISBNを指定してください。").trim().isLength({ min: 1 }).escape(), - body("genre.*").escape(), + body("isbn", "ISBNを指定してください。") + .trim() + .isLength({ min: 1 }) + .escape(), + body("genre.*") + .escape(), asyncHandler(async (req, res, next) => { const errors = validationResult(req); const book = new Book({ @@ -222,11 +225,11 @@ exports.book_update_post = [ }); if (!errors.isEmpty()) { const [allAuthors, allGenres] = await Promise.all([ - Author.find().exec(), - Genre.find().exec(), + Author.find().sort({ family_name: 1 }).exec(), + Genre.find().sort({ name: 1 }).exec(), ]); for (const genre of allGenres) { - if (book.genre.indexOf(genre._id) > -1) { + if (book.genre.includes(genre._id)) { genre.checked = "true"; } } diff --git a/controllers/bookinstanceController.js b/controllers/bookinstanceController.js index ba662b2..c338d5e 100644 --- a/controllers/bookinstanceController.js +++ b/controllers/bookinstanceController.js @@ -28,7 +28,7 @@ exports.bookinstance_detail = asyncHandler(async (req, res, next) => { }); exports.bookinstance_create_get = asyncHandler(async (req, res, next) => { - const allBooks = await Book.find({}, "title").exec(); + const allBooks = await Book.find({}, "title").sort({ title: 1 }).exec(); res.render("bookinstance_form", { title: "書籍現物登録フォーム", book_list: allBooks, @@ -36,12 +36,16 @@ exports.bookinstance_create_get = asyncHandler(async (req, res, next) => { }); exports.bookinstance_create_post = [ - body("book", "書籍名を指定してください").trim().isLength({ min: 1 }).escape(), + body("book", "書籍名を指定してください") + .trim() + .isLength({ min: 1 }) + .escape(), body("imprint", "版を指定してください") .trim() .isLength({ min: 1 }) .escape(), - body("status").escape(), + body("status") + .escape(), body("due_back", "日付が正しくありません。") .optional({ values: "falsy" }) .isISO8601() @@ -55,7 +59,7 @@ exports.bookinstance_create_post = [ due_back: req.body.due_back, }); if (!errors.isEmpty()) { - const allBooks = await Book.find({}, "title").exec(); + const allBooks = await Book.find({}, "title").sort({ title: 1 }).exec(); res.render("bookinstance_form", { title: "書籍現物登録フォーム", book_list: allBooks, @@ -85,7 +89,7 @@ exports.bookinstance_delete_get = asyncHandler(async (req, res, next) => { }); exports.bookinstance_delete_post = asyncHandler(async (req, res, next) => { - await BookInstance.findByIdAndRemove(req.body.id); + await BookInstance.findByIdAndDelete(req.body.id); res.redirect("/catalog/bookinstances"); }); @@ -108,12 +112,16 @@ exports.bookinstance_update_get = asyncHandler(async (req, res, next) => { }); exports.bookinstance_update_post = [ - body("book", "書籍名を指定してください。").trim().isLength({ min: 1 }).escape(), + body("book", "書籍名を指定してください。") + .trim() + .isLength({ min: 1 }) + .escape(), body("imprint", "版を指定してください。") .trim() .isLength({ min: 1 }) .escape(), - body("status").escape(), + body("status") + .escape(), body("due_back", "日付が正しくありません。") .optional({ values: "falsy" }) .isISO8601() diff --git a/controllers/genreController.js b/controllers/genreController.js index abf9c45..310f22d 100644 --- a/controllers/genreController.js +++ b/controllers/genreController.js @@ -88,7 +88,7 @@ exports.genre_delete_post = asyncHandler(async (req, res, next) => { }); return; } else { - await Genre.findByIdAndRemove(req.body.id); + await Genre.findByIdAnDelete(req.body.id); res.redirect("/catalog/genres"); } }); diff --git a/package-lock.json b/package-lock.json index 19dc638..af5292b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,12 +20,12 @@ "helmet": "^7.1.0", "http-errors": "~2.0.0", "moment": "^2.30.1", - "mongoose": "^8.6.2", + "mongoose": "^8.6.3", "morgan": "~1.10.0", "pug": "3.0.3" }, "devDependencies": { - "nodemon": "^3.1.4" + "nodemon": "^3.1.5" } }, "node_modules/@babel/helper-string-parser": { @@ -1301,9 +1301,9 @@ } }, "node_modules/mongoose": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.6.2.tgz", - "integrity": "sha512-ErbDVvuUzUfyQpXvJ6sXznmZDICD8r6wIsa0VKjJtB6/LZncqwUn5Um040G1BaNo6L3Jz+xItLSwT0wZmSmUaQ==", + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.6.3.tgz", + "integrity": "sha512-++yRmm7hjMbqVA/8WeiygTnEfrFbiy+OBjQi49GFJIvCQuSYE56myyQWo4j5hbpcHjhHQU8NukMNGTwAWFWjIw==", "license": "MIT", "dependencies": { "bson": "^6.7.0", @@ -1402,9 +1402,9 @@ } }, "node_modules/nodemon": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", - "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.5.tgz", + "integrity": "sha512-V5UtfYc7hjFD4SI3EzD5TR8ChAHEZ+Ns7Z5fBk8fAbTVAj+q3G+w7sHJrHxXBkVn6ApLVTljau8wfHwqmGUjMw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e03383f..15ec56c 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "helmet": "^7.1.0", "http-errors": "~2.0.0", "moment": "^2.30.1", - "mongoose": "^8.6.2", + "mongoose": "^8.6.3", "morgan": "~1.10.0", "pug": "3.0.3" }, "devDependencies": { - "nodemon": "^3.1.4" + "nodemon": "^3.1.5" }, "overrides": { "semver": "7.5.3" diff --git a/views/author_delete.pug b/views/author_delete.pug index bceb18c..cf6773f 100644 --- a/views/author_delete.pug +++ b/views/author_delete.pug @@ -22,7 +22,7 @@ block content else p この著者を削除してよろしいですか。 - form(method='POST' action='') + form(method='POST') div.form-group input#authorid.form-control(type='hidden',name='authorid', required='true', value=author._id ) diff --git a/views/author_detail.pug b/views/author_detail.pug index e23ea6d..cb92868 100644 --- a/views/author_detail.pug +++ b/views/author_detail.pug @@ -8,12 +8,12 @@ block content div(style='margin-left:20px;margin-top:20px') h4 書籍マスタ - - dl - each book in author_books - dt - a(href=book.url) #{book.title} - dd #{book.summary} + if author_books.length + dl + each book in author_books + dt + a(href=book.url) #{book.title} + dd #{book.summary} else p この著者の書籍マスタはありません。 diff --git a/views/author_form.pug b/views/author_form.pug index 8926ce2..66b5aa6 100644 --- a/views/author_form.pug +++ b/views/author_form.pug @@ -3,12 +3,12 @@ extends layout block content h1=title - form(method='POST' action='') + form(method='POST') div.form-group label(for='family_name') 氏: - input#family_name.form-control(type='text', placeholder='全角で入力' name='family_name' required='true' value=(undefined===author ? '' : author.family_name)) + input#family_name.form-control(type='text', placeholder='全角で入力' name='family_name' required value=(undefined===author ? '' : author.family_name)) label(for='first_name') 名: - input#first_name.form-control(type='text', placeholder='全角で入力' name='first_name' required='true' value=(undefined===author ? '' : author.first_name) ) + input#first_name.form-control(type='text', placeholder='全角で入力' name='first_name' required value=(undefined===author ? '' : author.first_name) ) div.form-group label(for='date_of_birth') 生年月日: input#date_of_birth.form-control(type='date', name='date_of_birth' value=(undefined===author ? '' : author.date_of_birth_yyyy_mm_dd) ) diff --git a/views/author_list.pug b/views/author_list.pug index e70cdd7..587db5d 100644 --- a/views/author_list.pug +++ b/views/author_list.pug @@ -10,4 +10,4 @@ block content | (#{author.lifespan}) else - li 著者名がありません。 \ No newline at end of file + p 著者名がありません。 \ No newline at end of file diff --git a/views/book_delete.pug b/views/book_delete.pug index 933590f..725aeeb 100644 --- a/views/book_delete.pug +++ b/views/book_delete.pug @@ -9,9 +9,11 @@ block content p #[strong 要約:] #{book.summary} p #[strong ISBN:] #{book.isbn} p #[strong ジャンル:] - each val in book.genre + each val, index in book.genre a(href=val.url) #{val.name} - |, + if index < book.genre.length - 1 + |,  + hr @@ -40,8 +42,8 @@ block content else p この書籍を削除してよろしいですか。 - form(method='POST' action='') + form(method='POST') div.form-group - input#id.form-control(type='hidden',name='id', required='true', value=book._id ) + input#id.form-control(type='hidden',name='id', value=book._id ) button.btn.btn-primary(type='submit') 削除 \ No newline at end of file diff --git a/views/book_detail.pug b/views/book_detail.pug index 737e90e..5f63c99 100644 --- a/views/book_detail.pug +++ b/views/book_detail.pug @@ -11,7 +11,7 @@ block content each val, index in book.genre a(href=val.url) #{val.name} if index < book.genre.length - 1 - |, + |,  div(style='margin-left:20px;margin-top:20px') h4 書籍現物 diff --git a/views/book_form.pug b/views/book_form.pug index b5e87c4..b7088c5 100644 --- a/views/book_form.pug +++ b/views/book_form.pug @@ -3,32 +3,38 @@ extends layout block content h1= title - form(method='POST' action='') + form(method='POST') div.form-group label(for='title') 書籍名: - input#title.form-control(type='text', placeholder='書籍名' name='title' required='true' value=(undefined===book ? '' : book.title) ) + input#title.form-control(type='text', placeholder='書籍名' name='title' required value=(undefined===book ? '' : book.title) ) div.form-group label(for='author') 著者: - select#author.form-control(type='select', placeholder='著者を選択' name='author' required='true' ) - - authors.sort(function(a, b) {let textA = a.family_name.toUpperCase(); let textB = b.family_name.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;}); + select#author.form-control(name='author' required) + option(value='') --著者を選んでください。-- for author in authors if book - option(value=author._id selected=(author._id.toString()===book.author._id.toString() ? 'selected' : false) ) #{author.name} + if author._id.toString()===book.author._id.toString() + option(value=author._id selected) #{author.name} + else + option(value=author._id) #{author.name} else option(value=author._id) #{author.name} div.form-group label(for='summary') 要約: - input#summary.form-control(type='textarea', placeholder='要約' name='summary' value=(undefined===book ? '' : book.summary) required='true') + textarea#summary.form-control(placeholder='要約' name='summary' required)= undefined===book ? '' : book.summary div.form-group label(for='isbn') ISBN: - input#isbn.form-control(type='text', placeholder='ISBN13' name='isbn' value=(undefined===book ? '' : book.isbn) required='true') + input#isbn.form-control(type='text', placeholder='ISBN13' name='isbn' value=(undefined===book ? '' : book.isbn) required) div.form-group label ジャンル: div for genre in genres div(style='display: inline; padding-right:10px;') - input.checkbox-input(type='checkbox', name='genre', id=genre._id, value=genre._id, checked=genre.checked ) - label(for=genre._id) #{genre.name} + if genre.checked + input.checkbox-input(type='checkbox', name='genre', id=genre._id, value=genre._id, checked) + else + input.checkbox-input(type='checkbox', name='genre', id=genre._id, value=genre._id) + label(for=genre._id)  #{genre.name} button.btn.btn-primary(type='submit') 送信 if errors diff --git a/views/book_list.pug b/views/book_list.pug index 2b0e22b..a9be482 100644 --- a/views/book_list.pug +++ b/views/book_list.pug @@ -2,12 +2,12 @@ extends layout block content h1= title + if book_list.length + ul + each book in book_list + li + a(href=book.url) #{book.title} + | (#{book.author.name}) - ul - each book in book_list - li - a(href=book.url) #{book.title} - | (#{book.author.name}) - - else - li 書籍がありません。 \ No newline at end of file + else + p 書籍がありません。 \ No newline at end of file diff --git a/views/bookinstance_delete.pug b/views/bookinstance_delete.pug index b964c3e..3517f63 100644 --- a/views/bookinstance_delete.pug +++ b/views/bookinstance_delete.pug @@ -26,8 +26,8 @@ block content if bookinstance.status!='貸出可能' p #[strong 期限:] #{bookinstance.due_back_formatted} - form(method='POST' action='') + form(method='POST') div.form-group - input#id.form-control(type='hidden',name='id', required='true', value=bookinstance._id ) + input#id.form-control(type='hidden',name='id', value=bookinstance._id ) button.btn.btn-primary(type='submit') 削除 \ No newline at end of file diff --git a/views/bookinstance_form.pug b/views/bookinstance_form.pug index c983c68..a1a6e6b 100644 --- a/views/bookinstance_form.pug +++ b/views/bookinstance_form.pug @@ -3,29 +3,31 @@ extends layout block content h1=title - form(method='POST' action='') + form(method='POST') div.form-group label(for='book') 書籍名: - select#book.form-control(type='select', placeholder='書籍名を選んでください。' name='book' required='true' ) - - book_list.sort(function(a, b) {let textA = a.title.toUpperCase(); let textB = b.title.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;}); + select#book.form-control(name='book' required) + option(value='') --書籍名を選んでください。-- for book in book_list - option(value=book._id, selected=(selected_book==book._id.toString() ? 'selected' : false) ) #{book.title} - + if selected_book==book._id.toString() + option(value=book._id, selected) #{book.title} + else + option(value=book._id) #{book.title} div.form-group label(for='imprint') 版: - input#imprint.form-control(type='text', placeholder='発行者と発行日' name='imprint' required='true' value=(undefined===bookinstance ? '' : bookinstance.imprint) ) + input#imprint.form-control(type='text', placeholder='発行者と発行日' name='imprint' required value=(undefined===bookinstance ? '' : bookinstance.imprint) ) div.form-group label(for='due_back') 期限: input#due_back.form-control(type='date', name='due_back' value=(undefined===bookinstance ? '' : bookinstance.due_back_yyyy_mm_dd)) - div.form-group label(for='status') 状況: - select#status.form-control(type='select', name='status' required='true' ) - option(value='準備中' selected=(undefined===bookinstance || bookinstance.status!='準備中' ? false:'selected')) 準備中 - option(value='貸出可能' selected=(undefined===bookinstance || bookinstance.status!='貸出可能' ? false:'selected')) 貸出可能 - option(value='貸出中' selected=(undefined===bookinstance || bookinstance.status!='貸出中' ? false:'selected')) 貸出中 - option(value='予約中' selected=(undefined===bookinstance || bookinstance.status!='予約中' ? false:'selected')) 予約中 - + select#status.form-control(name='status' required) + option(value='') --状況を選んでください。-- + each val in ['準備中', '貸出可能', '貸出中', '予約中'] + if undefined===bookinstance || bookinstance.status!=val + option(value=val)= val + else + option(value=val selected)= val button.btn.btn-primary(type='submit') 送信 if errors diff --git a/views/bookinstance_list.pug b/views/bookinstance_list.pug index d0d347e..697a911 100644 --- a/views/bookinstance_list.pug +++ b/views/bookinstance_list.pug @@ -2,20 +2,18 @@ extends layout block content h1= title - - ul - each val in bookinstance_list - li - a(href=val.url) #{val.book.title} : #{val.imprint} - - if val.status=='貸出可能' - span.text-success #{val.status} - else if val.status=='準備中' - span.text-danger #{val.status} - else - span.text-warning #{val.status} - if val.status!='貸出可能' - span (期限: #{val.due_back_formatted} ) - - + if bookinstance_list.length + ul + each val in bookinstance_list + li + a(href=val.url) #{val.book.title} : #{val.imprint} -  + if val.status=='貸出可能' + span.text-success #{val.status} + else if val.status=='準備中' + span.text-danger #{val.status} + else + span.text-warning #{val.status} + if val.status!='貸出可能' + span (期限: #{val.due_back_formatted}) else - li 書籍現物がありません。 \ No newline at end of file + p 書籍現物がありません。 \ No newline at end of file diff --git a/views/genre_delete.pug b/views/genre_delete.pug index 0bc4d02..b1fe6e6 100644 --- a/views/genre_delete.pug +++ b/views/genre_delete.pug @@ -13,16 +13,16 @@ block content h4 書籍マスタ dl - each book in genre_books - dt - a(href=book.url) #{book.title} - dd #{book.summary} + each book in genre_books + dt + a(href=book.url) #{book.title} + dd #{book.summary} else p このジャンルを削除してよろしいですか。 - form(method='POST' action='') + form(method='POST') div.form-group - input#id.form-control(type='hidden',name='id', required='true', value=genre._id ) + input#id.form-control(type='hidden', name='id', value=genre._id ) button.btn.btn-primary(type='submit') 削除 \ No newline at end of file diff --git a/views/genre_detail.pug b/views/genre_detail.pug index 8e13d60..0e31fb4 100644 --- a/views/genre_detail.pug +++ b/views/genre_detail.pug @@ -7,13 +7,12 @@ block content div(style='margin-left:20px;margin-top:20px') h4 書籍マスタ - - dl - each book in genre_books - dt - a(href=book.url) #{book.title} - dd #{book.summary} - + if genre_books.length + dl + each book in genre_books + dt + a(href=book.url) #{book.title} + dd #{book.summary} else p このジャンルの書籍はありません。 diff --git a/views/genre_form.pug b/views/genre_form.pug index 9e531b6..233e37d 100644 --- a/views/genre_form.pug +++ b/views/genre_form.pug @@ -4,10 +4,10 @@ block content h1 #{title} - form(method='POST' action='') + form(method='POST') div.form-group label(for='name') ジャンル: - input#name.form-control(type='text', placeholder='芸術. 美術、哲学など' name='name' required='true' value=(undefined===genre ? '' : genre.name) ) + input#name.form-control(type='text', placeholder='芸術. 美術、哲学など' name='name' required value=(undefined===genre ? '' : genre.name) ) button.btn.btn-primary(type='submit') 送信 if errors diff --git a/views/genre_list.pug b/views/genre_list.pug index 7ee7c0e..e9e32b8 100644 --- a/views/genre_list.pug +++ b/views/genre_list.pug @@ -2,11 +2,10 @@ extends layout block content h1= title - - ul - each val in list_genres - li - a(href=val.url) #{val.name} - + if list_genres.length + ul + each val in list_genres + li + a(href=val.url) #{val.name} else - li ジャンルがありません。 \ No newline at end of file + p ジャンルがありません。 \ No newline at end of file