Skip to content

Commit

Permalink
Merge pull request #7166 from fjordllc/main
Browse files Browse the repository at this point in the history
Release 2024-01-11 08:59:25
  • Loading branch information
komagata authored Jan 11, 2024
2 parents 17a72a0 + 26e6332 commit 8e11f39
Show file tree
Hide file tree
Showing 65 changed files with 756 additions and 83 deletions.
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ jobs:
- run:
name: Assets precompile
command: 'bundle exec rails assets:clean assets:precompile NODE_OPTIONS=--openssl-legacy-provider'
- run:
command: 'gem install stringio -v 3.1.0'
- run:
name: Test
command: |
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ruby '3.1.4'
gem 'bootsnap', '>= 1.4.4', require: false
gem 'image_processing', '~> 1.12'
gem 'jbuilder', '~> 2.7'
gem 'puma', '~> 6.3'
gem 'puma', '~> 6.4'
gem 'rails', '~> 6.1.4.4'
gem 'webpacker', '~> 5.0'

Expand Down Expand Up @@ -64,7 +64,7 @@ gem 'rubyzip'
gem 'slim-rails'
gem 'sorcery', '~> 0.16.2'
gem 'sorcery-jwt'
gem 'stringio', '3.0.1'
gem 'stringio', '3.1.0'
gem 'stripe'
gem 'stripe-i18n', git: 'https://github.com/komagata/stripe-i18n', branch: 'update-depencency'
gem 'tzinfo', '~> 2.0', '>= 2.0.6'
Expand Down
10 changes: 5 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ GEM
net-protocol
netrc (0.11.0)
newspaper (0.2.0)
nio4r (2.5.9)
nio4r (2.7.0)
nokogiri (1.15.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-darwin)
Expand Down Expand Up @@ -362,7 +362,7 @@ GEM
psych (5.1.1.1)
stringio
public_suffix (5.0.3)
puma (6.4.0)
puma (6.4.2)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.7.3)
Expand Down Expand Up @@ -523,7 +523,7 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
stringio (3.0.1)
stringio (3.1.0)
strings (0.2.1)
strings-ansi (~> 0.2)
unicode-display_width (>= 1.5, < 3.0)
Expand Down Expand Up @@ -641,7 +641,7 @@ DEPENDENCIES
pg (~> 1.4.6)
postmark-rails
pry-byebug
puma (~> 6.3)
puma (~> 6.4)
rack-cors
rack-dev-mark
rack-mini-profiler (~> 2.0)
Expand All @@ -668,7 +668,7 @@ DEPENDENCIES
sorcery-jwt
spring
spring-watcher-listen (~> 2.0.0)
stringio (= 3.0.1)
stringio (= 3.1.0)
stripe
stripe-i18n!
syntax_suggest
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ rack-mini-profilerによりプロファイリングはデフォルトではOFF
$ PROFILE=1 rails server
```

## その他
## 環境構築

- [Develop環境でログインする方法](https://github.com/fjordllc/bootcamp/wiki/Develop%E7%92%B0%E5%A2%83%E3%81%A7%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
- [Develop環境でのメールの確認方法](https://github.com/fjordllc/bootcamp/wiki/Develop%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95)
- [nodeのバージョン切り替え](https://github.com/fjordllc/bootcamp/wiki/node%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88)
- [Rake Taskの実装方法](https://github.com/fjordllc/bootcamp/wiki/Rake-Task%E3%81%AE%E5%AE%9F%E8%A3%85%E6%96%B9%E6%B3%95)
- [Develop環境をDockerで動かす方法](doc/development_on_docker.md)
- [通知機能](https://github.com/fjordllc/bootcamp/wiki/%E9%80%9A%E7%9F%A5%E6%A9%9F%E8%83%BD)
- [gemを使った通知機能 · fjordllc/bootcamp Wiki](https://github.com/fjordllc/bootcamp/wiki/gem%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E9%80%9A%E7%9F%A5%E6%A9%9F%E8%83%BD)

## その他

- [Bootcamp Wiki](https://github.com/fjordllc/bootcamp/wiki)
7 changes: 4 additions & 3 deletions app/controllers/api/products/unchecked_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ def index
checker_id = params[:checker_id]
@products = case @target
when 'unchecked_all'
Product.unchecked
Product.unhibernated_user_products
.unchecked
.not_wip
.list
.ascending_by_date_of_publishing_and_id
.page(params[:page])
when 'unchecked_no_replied'
Product.unchecked_no_replied_products
.unchecked
Product.unhibernated_user_products
.unchecked_no_replied_products
.not_wip
.list
.page(params[:page])
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def target_users
if @target == 'followings'
current_user.followees_list(watch: @watch)
elsif @tag
User.tagged_with(@tag)
User.tagged_with(@tag).unhibernated.unretired
else
users_scope =
if @company
Expand Down
7 changes: 7 additions & 0 deletions app/controllers/courses/books_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class Courses::BooksController < ApplicationController
def index
@course = Course.find(params[:course_id])
end
end
1 change: 1 addition & 0 deletions app/controllers/hibernation_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def create
destroy_subscription!
notify_to_chat
notify_to_mentors_and_admins
current_user.delete_and_assign_new_organizer
logout
redirect_to hibernation_path
else
Expand Down
1 change: 1 addition & 0 deletions app/controllers/retirement_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def create
current_user.retired_on = Date.current
if current_user.save(context: :retirement)
user = current_user
current_user.delete_and_assign_new_organizer
Newspaper.publish(:retirement_create, user)
begin
UserMailer.retire(user).deliver_now
Expand Down
8 changes: 7 additions & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

class UsersController < ApplicationController
skip_before_action :require_active_user_login, raise: false, only: %i[new create]
skip_before_action :require_active_user_login, raise: false, only: %i[new create show]
before_action :require_token, only: %i[new] if Rails.env.production?
before_action :set_user, only: %w[show]

Expand Down Expand Up @@ -40,6 +40,12 @@ def show
.includes(:practice)
.where(status: 3)
.order(updated_at: :desc)

if logged_in?
render :show
else
render :unauthorized_show, layout: 'not_logged_in'
end
end

def new
Expand Down
24 changes: 17 additions & 7 deletions app/javascript/components/Products.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,22 @@ export default function Products({
)
} else if (data.products.length === 0) {
return (
<div className="o-empty-message">
<div className="o-empty-message__icon">
<i className="fa-regular fa-smile"></i>
<>
{selectedTab === 'unchecked' || selectedTab === 'self_assigned' ? (
<nav className="pill-nav">
<ul className="pill-nav__items">
<FilterButtons selectedTab={selectedTab} />
</ul>
</nav>
) : null}

<div className="o-empty-message">
<div className="o-empty-message__icon">
<i className="fa-regular fa-smile"></i>
</div>
<p className="o-empty-message__text">{title}はありません</p>
</div>
<p className="o-empty-message__text">{title}はありません</p>
</div>
</>
)
} else if (isDashboard() && isNotProduct5daysElapsed()) {
return (
Expand Down Expand Up @@ -232,9 +242,9 @@ function ProductHeader({
const FilterButtons = ({ selectedTab }) => {
let targets
if (selectedTab === 'self_assigned') {
targets = ['self_assigned_no_replied', 'self_assigned_all']
targets = ['self_assigned_all', 'self_assigned_no_replied']
} else {
targets = ['unchecked_no_replied', 'unchecked_all']
targets = ['unchecked_all', 'unchecked_no_replied']
}

const filterButtonUrl = ({ selectedTab, target }) => {
Expand Down
101 changes: 101 additions & 0 deletions app/javascript/components/course-books.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<template lang="pug">
.page-body
.page-content.is-books
.container
.books
.empty(v-if='books === null')
.fa-solid.fa-spinner.fa-pulse
|
| ロード中
.books__items(v-else-if='books.length !== 0')
.row
book(
v-for='book in filteredBooks',
:key='book.id',
:book='book',
:isAdmin='isAdmin',
:isMentor='isMentor')
.o-empty-message(v-else)
.o-empty-message__icon
i.fa-regular.fa-sad-tear
p.o-empty-message__text
| 登録されている本はありません
</template>
<script>
import CSRF from 'csrf'
import Book from './book'
export default {
name: 'CourseBooks',
components: {
book: Book
},
props: {
isAdmin: { type: Boolean, required: true },
isMentor: { type: Boolean, required: true },
course: { type: Object, required: true }
},
data() {
return {
books: null,
practices: []
}
},
computed: {
filteredBooks() {
return this.books.filter((book) =>
book.practices.some((practice) =>
this.practices.some(
(coursePractice) => coursePractice.id === practice.id
)
)
)
}
},
created() {
this.getBooks()
this.getPractices()
},
methods: {
fetchGetData(url, callback) {
const uri = `/api/${url}`
fetch(uri, {
method: 'GET',
headers: {
'content-type': 'application/json; charset=utf-8',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': CSRF.getToken()
},
credentials: 'same-origin',
redirect: 'manual'
})
.then((res) => res.json())
.then(callback)
.catch((err) => console.warn(err))
},
getBooks() {
this.fetchGetData(`books.json`, (json) => {
const urlParams = new URLSearchParams(window.location.search)
const status = urlParams.get('status')
if (status === 'mustread') {
this.books = json.books.filter((book) => book.mustRead)
} else {
this.books = []
json.books.forEach((book) => this.books.push(book))
}
})
},
getPractices() {
this.fetchGetData(`courses/${this.course.id}/practices.json`, (json) => {
json.categories.forEach((category) => {
this.practices.push(
...category.practices.map(
(categoryPractice) => categoryPractice.practice
)
)
})
})
}
}
}
</script>
12 changes: 9 additions & 3 deletions app/javascript/components/user.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
.col-xxl-3.col-xl-4.col-lg-4.col-md-6.col-xs-12
.users-item
.users-item__inner.a-card
.users-item__inactive-message.is-only-mentor(
v-if='currentUser.mentor && user.student_or_trainee && !user.active')
| 1ヶ月以上ログインがありません
.users-item__inactive-message-container.is-only-mentor(
v-if='(currentUser.mentor || currentUser.admin) && user.student_or_trainee')
.users-item__inactive-message(v-if='user.roles.includes("retired")')
| 退会しました
.users-item__inactive-message(
v-else-if='user.roles.includes("hibernationed")')
| 休会中: {{ user.hibernated_at }}〜({{ user.hibernation_elapsed_days }}日経過)
.users-item__inactive-message(v-else-if='!user.active')
| 1ヶ月以上ログインがありません
header.users-item__header
.users-item__header-inner
.users-item__header-start
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import SadReports from '../components/sad_reports.vue'
import UserProducts from '../components/user-products.vue'
import MentorPractices from '../components/mentor-practices.vue'
import ActionCompletedButton from '../components/action-completed-button.vue'
import CourseBooks from '../components/course-books.vue'

import '../stylesheets/application'

Expand All @@ -106,6 +107,7 @@ mounter.addComponent(SadReports)
mounter.addComponent(UserProducts)
mounter.addComponent(MentorPractices)
mounter.addComponent(ActionCompletedButton)
mounter.addComponent(CourseBooks)
mounter.mount()

// Support component names relative to this directory:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
height: 100%

.users-item__inactive-message
background-color: var(--background)
background-color: var(--disabled)
+text-block(.625rem 1.4, center)
padding: .25rem
+border-radius(top, .1875rem)
margin-bottom: -.25rem
margin: -1px -1px -.25rem

.users-item__inner
+media-breakpoint-up(md)
Expand All @@ -16,7 +16,7 @@

.users-item__header
+position(relative)
padding: 1rem
padding: .75rem 1rem
border-bottom: solid 1px var(--border-tint)

.users-item__header-inner
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/activity_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def watching_notification(args = {})
kind: Notification.kinds[:watched]
)
@action = @watchable.instance_of?(Question) ? '回答' : 'コメント'
subject = "[FBC] #{@watchable.user.login_name}さんの#{@watchable.notification_title}#{@sender.login_name}さんが#{@action}しました。"
subject = "[FBC] #{@watchable.user.login_name}さんの#{@watchable.notification_title}#{@sender.login_name}さんが#{@action}しました。"

message = mail to: @user.email, subject: subject
message.perform_deliveries = @user.mail_notification? && !@user.retired?
Expand Down
2 changes: 1 addition & 1 deletion app/models/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def delete_unchecked_report_count

def unchecked_product_count
Rails.cache.fetch 'unchecked_product_count' do
Product.unchecked.not_wip.count
Product.unhibernated_user_products.unchecked.not_wip.count
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/mentioner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def new_mention_users
def where_mention
case self
when Product
"#{user.login_name}さんの#{practice[:title]}の提出物"
"#{user.login_name}さんの提出物#{practice[:title]}」"
when Report
"#{user.login_name}さんの日報「#{self[:title]}」"
when Comment
Expand Down
Loading

0 comments on commit 8e11f39

Please sign in to comment.