Skip to content

Commit

Permalink
Merge pull request #61 from kaishuu0123/master
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
kaishuu0123 authored Dec 24, 2019
2 parents 15be751 + 1f6c4f4 commit 14539de
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ gem 'omniauth-google-oauth2', '~> 0.8'
gem 'config'

gem 'kaminari', '~> 1.1'

gem 'gravatar_image_tag'
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ GEM
ffi (1.11.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
gravatar_image_tag (1.2.0)
hashie (3.6.0)
htmlentities (4.3.4)
i18n (1.7.0)
Expand Down Expand Up @@ -229,7 +230,7 @@ GEM
method_source (~> 0.9.0)
public_suffix (4.0.1)
puma (3.12.2)
rack (2.0.7)
rack (2.0.8)
rack-proxy (0.6.5)
rack
rack-test (1.1.0)
Expand Down Expand Up @@ -377,6 +378,7 @@ DEPENDENCIES
config
devise
devise-i18n
gravatar_image_tag
identicon
initial_avatar
jbuilder (~> 2.7)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/omniauth_finished_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def finish_signup
if (request.post? || request.patch?) && @user.update(user_params)
# OAuth の場合には希望アカウントが入力された後にグループを作る
@user.create_default_group
@user.use_gravatar_icon(false)
# @user.send_confirmation_instructions unless @user.confirmed?
sign_in(@user, bypass: true)
redirect_to root_url, notice: t('devise.omniauth_callbacks.success', kind: @provider.capitalize)
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def update_password
end
end

def use_gravatar
current_user.use_gravatar_icon

respond_to do |format|
format.html { redirect_to profiles_path, notice: 'Profile was successfully updated.' }
end
end

def destroy_image
current_user.image.purge

Expand Down
40 changes: 37 additions & 3 deletions app/javascript/components/backlogs/SprintCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@
<i class="fas fa-door-open"></i>
</a>
</div>
<div>
{{ totalSprintPoint | numeral('0.0') }}
</div>
</div>
</div>
<ul class="list-group list-group-flush rb-draggable">
Expand All @@ -83,6 +80,30 @@
</li>
</VueDraggable>
</ul>
<div v-if="sprint.stories.length > 0" class="card-footer bg-gray-100 px-2 py-1">
<div class="row text-center">
<div class="col-sm-12 col-md mb-0">
<div class="d-flex">
<div class="text-muted mr-2">{{ $t('title.progress')}}</div>
<div>
<strong>{{ doneStoriesLength }} / {{ totalStoriesLength }} ({{ progressPercent | numeral('0') }}%)</strong>
</div>
</div>
<div class="progress progress-xs mt-2">
<div class="progress-bar bg-success" role="progressbar"
:style="{width: `${progressPercent}%`}" :aria-valuenow="progressPercent" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="col-sm-12 col-md mb-0">
<div class="d-flex justify-content-end">
<div class="text-muted mr-2">{{ $t('title.totalStoryPoints') }}</div>
<div>
<strong>{{ totalSprintPoint | numeral('0.0') }} {{ $t('title.points') }}</strong>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

Expand Down Expand Up @@ -249,6 +270,15 @@ export default {
return this.sprint.stories.reduce((a, b) => {
return a + b.point
}, 0)
},
doneStoriesLength() {
return this.sprint.stories.filter(story => story.is_done).length
},
totalStoriesLength() {
return this.sprint.stories.length
},
progressPercent() {
return ((this.doneStoriesLength / this.totalStoriesLength) * 100)
}
}
}
Expand Down Expand Up @@ -278,4 +308,8 @@ li.rb-alert-primary {
@extend .alert;
@extend .alert-primary;
}
.progress-xs {
height: 4px;
}
</style>
26 changes: 13 additions & 13 deletions app/javascript/components/commons/TicketForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,6 @@
size="sm"
/>
</b-form-group>
<b-form-group
id="tag-group"
label-for="tag-input"
>
<div class="d-flex align-items-center">
<div class="text-nowrap text-gray-600 mr-2">
{{ $t('title.tag') }}:
</div>
<div class="w-100">
<TagInput v-model="ticket.tags" :projectId="projectId" />
</div>
</div>
</b-form-group>
<b-form-group
id="body-group"
label-for="body-input"
Expand All @@ -42,6 +29,19 @@
size="sm"
/>
</b-form-group>
<b-form-group
id="tag-group"
label-for="tag-input"
>
<div class="d-flex align-items-center">
<div class="text-nowrap text-gray-600 mr-2">
{{ $t('title.tag') }}:
</div>
<div class="w-100">
<TagInput v-model="ticket.tags" :projectId="projectId" />
</div>
</div>
</b-form-group>
<div class="d-flex align-items-center">
<b-form-text><i class="fab fa-markdown"></i> Markdown available</b-form-text>
<b-button class="ml-auto" variant="primary" size="sm" type="submit">
Expand Down
8 changes: 4 additions & 4 deletions app/javascript/components/commons/TicketPreview.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<template>
<div>
<h1 class="h4 text-gray-800 mb-2">{{ ticket.title }}</h1>
<MarkdownText :content="ticket.body" v-if="ticket.body" />
<div v-else class="d-flex bg-gray-100 align-items-center border rounded">
<p class="text-xs text-gray-500 p-1 mb-0"> {{ $t('message.noDescription') }}</p>
</div>
<div class="d-flex align-items-center mb-2">
<div class="text-gray-600 mr-2">
{{ $t('title.tag') }}:
Expand All @@ -9,10 +13,6 @@
{{ tag.name }}
</span>
</div>
<MarkdownText :content="ticket.body" v-if="ticket.body" />
<div v-else class="d-flex bg-gray-100 align-items-center border rounded">
<p class="text-xs text-gray-500 p-1 mb-0"> {{ $t('message.noDescription') }}</p>
</div>
</div>
</template>

Expand Down
16 changes: 12 additions & 4 deletions app/javascript/i18n/globals.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
"tag": "Tags",
"unassigned": "Unassigned",
"search": "Search by keyword",
"is_public": "Public"
"is_public": "Public",
"progress": "Progress (Done / Total)",
"totalStoryPoints": "Total Story Points",
"points": "points"
},
"ticket": {
"title": "Title",
Expand Down Expand Up @@ -96,7 +99,8 @@
"storyDoesNotExistsInSprint": "Story doesn't exists. Let's add the added story to Sprint by D&D from Backlogs.",
"historyIsEmpty": "History is empty.",
"tagInput": "Please input tags",
"publicProject": "This is a public project. Non-member users are only allowed to comment on tickets."
"publicProject": "This is a public project. Non-member users are only allowed to comment on tickets.",
"addGroup": "Enter a few characters for the group name you want to add to the project. If you want to add a user, enter the username."
},
"tab": {
"comment": "Comment",
Expand Down Expand Up @@ -143,7 +147,10 @@
"tag": "タグ",
"unassigned": "未アサイン",
"search": "キーワード検索",
"is_public": "公開"
"is_public": "公開",
"progress": "進捗 (完了 / 合計)",
"totalStoryPoints": "ストーリーポイント合計",
"points": "ポイント"
},
"ticket": {
"title": "タイトル",
Expand Down Expand Up @@ -200,7 +207,8 @@
"storyDoesNotExistsInSprint": "Story がありません。Backlogs に追加した Story を D&D で Sprint に追加してみましょう",
"historyIsEmpty": "更新履歴はありません",
"tagInput": "タグを入力してください",
"publicProject": "これは公開プロジェクトです。メンバーではないユーザはチケットへのコメントのみ許可されています。"
"publicProject": "これは公開プロジェクトです。メンバーではないユーザはチケットへのコメントのみ許可されています。",
"addGroup": "プロジェクトに追加したいグループ名を数文字入力してください。ユーザを追加したい場合にはユーザ名を入力してください。"
},
"tab": {
"comment": "コメント",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<div class="row">
<div class="card w-100 mb-4">
<div class="card-body">
<p>{{ $t('message.addGroup') }}</p>
<b-form ref="form" class="w-100" @submit.stop.prevent="handleSubmit" @keydown.enter.prevent.self="">
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ $t('action.selectGroup') }}</label>
Expand Down
4 changes: 2 additions & 2 deletions app/models/ticket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ def ticket_number_with_ticket_prefix

def created_user_by
whodunnit = versions.reorder(:created_at).find_by(event: 'create').whodunnit
whodunnit ? User.find(whodunnit) : nil
whodunnit ? User.find_by_id(id: whodunnit) : nil
end

def last_updated_user_by
whodunnit = versions.reorder(created_at: :desc).find_by(event: 'update')&.whodunnit
whodunnit ? User.find(whodunnit) : nil
whodunnit ? User.find_by_id(id: whodunnit) : nil
end

def update_is_done
Expand Down
60 changes: 54 additions & 6 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,24 @@
#

class User < ApplicationRecord
# GRAVATAR のデフォルトアイコン (電源ボタンっぽいやつ)
GRAVATAR_DEFAULT_ICON_BASE64 = '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'

rolify
attr_accessor :skip_create_default_group
after_commit :create_default_group, on: [:create], if: Proc.new { skip_create_default_group == false }
after_create :assign_default_role
attribute :skip_create_default_group, :boolean, default: false
# XXX: set_gravatar_icon を create_default_group より後の行に書くと処理が継続されない問題を調べる必要がある
after_create_commit :set_gravatar_icon, if: Proc.new {
skip_create_default_group == false
}
after_create_commit :create_default_group, if: Proc.new {
skip_create_default_group == false
}
after_create_commit :assign_default_role

attr_writer :login

TEMP_EMAIL_PREFIX = 'change@me'
TEMP_EMAIL_REGEX = /\Achange@me/
TEMP_EMAIL_PREFIX = 'change@me'.freeze
TEMP_EMAIL_REGEX = /\Achange@me/.freeze

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
Expand All @@ -36,7 +45,7 @@ class User < ApplicationRecord
has_many :group_users, dependent: :destroy
has_many :groups, through: :group_users
has_many :tickets, foreign_key: :assignee_id, dependent: :nullify
has_one_attached :image
has_one_attached :image, dependent: :purge
has_many :social_profiles, dependent: :destroy

# emailの登録状況を判定するカスタムvalidatorを使用するためのおまじない。
Expand Down Expand Up @@ -65,6 +74,11 @@ def create_default_group
groups.create(name: username)
end

# ユーザ作成時に呼び出される Gravatar アイコンを設定するフック
def set_gravatar_icon
use_gravatar_icon(false)
end

def user_image_url
if image.present?
base64 = Base64.strict_encode64(image.download)
Expand All @@ -81,6 +95,40 @@ def assign_default_role
self.add_role(:developer) if self.roles.blank?
end

# 現在のアイコンを Gravatar アイコンにセットする
# use_default_icon を false にすると、 gravatar 公式のデフォルトアイコンと合致した場合には何もしないようになっている
def use_gravatar_icon(use_default_icon = true)
require 'open-uri'

# Gravatar の デフォルトアイコンを使わない場合
unless use_default_icon
image_url = ApplicationController.helpers.gravatar_image_url(
email
)
image_data = nil
URI.open(image_url) do |file|
image_data = file.read
end

return if GRAVATAR_DEFAULT_ICON_BASE64 == Base64.strict_encode64(image_data)
end

image_url = ApplicationController.helpers.gravatar_image_url(
email,
size: 180,
secure: true
)

URI.open(image_url) do |file|
image.purge
image.attach(
io: file,
filename: "#{username}-gravatar.#{File.basename(file.meta['content-type'])}",
content_type: file.meta['content-type']
)
end
end

###
# refs: https://qiita.com/mnishiguchi/items/e15bbef61287f84b546e
###
Expand Down
9 changes: 8 additions & 1 deletion app/views/profiles/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@
<%= f.button :submit, t('actions.upload', default: 'Upload'), class: 'btn btn-sm btn-primary mr-3' %>
<% if current_user.image.present? %>
<div>
<%= link_to t('actions.remove', default: 'Remove'), profiles_image_path(), method: :delete, class: 'btn btn-sm btn-danger' %>
<%= link_to t('actions.remove', default: 'Remove'), profiles_image_path(), method: :delete, class: 'btn btn-sm btn-danger mr-3' %>
</div>
<% end %>
<%=
link_to profiles_use_gravatar_path,
class: "btn btn-sm btn-success",
data: { toggle: "tooltip", html: "true", title: "#{gravatar_image_tag(current_user.email, size: 180, secure: true)}" },
method: :patch do %>
<%= t('.user_gravatar', default: 'Use Gravatar Icon') %>
<% end %>
</div>
<% end %>
</div>
Expand Down
1 change: 1 addition & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ ja:
current_image: 現在の画像
change_password: パスワード変更
choose_a_file: ファイルを選択 ...
user_gravatar: Gravatar アイコンを使う
application_settings:
common:
sidebar:
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
get '/profiles', to: 'profiles#index'
patch '/profiles', to: 'profiles#update'
patch '/profiles/update_password', to: 'profiles#update_password'
patch '/profiles/use_gravatar', to: 'profiles#use_gravatar'
delete '/profiles/image', to: 'profiles#destroy_image'

namespace :application_settings do
Expand Down

0 comments on commit 14539de

Please sign in to comment.