Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ameya86 committed Mar 20, 2012
0 parents commit 535f708
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 0 deletions.
40 changes: 40 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
= Already Read Plugin

チケットの既読/未読を管理し、チケット一覧に「既読」「読んだ日時」列を追加します。
チケットを更新すると、そのチケットは未読チケットに戻ります。


== インストール

1. RAILS_ROOT/vendor/pluginsに配置する。

2. rake db:migrate_plugins RAILS_ENV=production
を実行する。

3. Redmineを再起動する。


== アンインストール

1. RAILS_ROOTで
rake db:migrate:plugin RAILS_ENV=production VERSION=0 NAME=redmine_already_read
を実行する。

2. RAILS_ROOT/vendor/pluginsから削除する。

3. Redmineを再起動する。


== 備考

チケットのclass指定に、既読の場合は「read」、未読の場合は「unread」を追加します。
このプラグインではCSSを提供していませんが、
利用者側で「read」や「unread」に対するCSSを追加していただくことで
未読チケットの強調表示などを実現できます。


== 更新履歴

=== Version 0.0.,1

リリース
6 changes: 6 additions & 0 deletions app/models/already_read.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AlreadyRead < ActiveRecord::Base
belongs_to :user
belongs_to :issue

validates_presence_of :user, :issue
end
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
en:
field_already_read: Read
field_already_read_date: Read Date

label_already_read: Read
label_read: Read
label_unread: Unread
7 changes: 7 additions & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ja:
field_already_read: 既読
field_already_read_date: 読んだ日時

label_already_read: 既読
label_read: 既読
label_unread: 未読
14 changes: 14 additions & 0 deletions db/migrate/001_create_already_reads.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateAlreadyReads < ActiveRecord::Migration
def self.up
create_table :already_reads do |t|
t.column :issue_id, :integer
t.column :user_id, :integer
t.column :created_on, :datetime
end
add_index :already_reads, [:issue_id, :user_id], :name => :index_already_reads, :unique => true
end

def self.down
drop_table :already_reads
end
end
14 changes: 14 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'redmine'
require 'already_read/issue_patch'
require 'already_read/issues_controller_patch'
require 'already_read/user_patch'
require 'already_read/query_patch'

Redmine::Plugin.register :redmine_already_read do
name 'Redmine Already Read plugin'
author 'OZAWA Yasuhiro'
description 'Markup read issues.'
version '0.0.1'
url 'https://github.com/ameya86/redmine_already_read'
author_url 'http://blog.livedoor.jp/ameya86/'
end
50 changes: 50 additions & 0 deletions lib/already_read/issue_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require_dependency 'issue'

module AlreadyReadIssuePatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods) # obj.method

base.class_eval do
alias_method_chain :css_classes, :already_read
end
end

module InstanceMethods # obj.method
# チケットのclassに既読/未読も追加する
def css_classes_with_already_read
s = css_classes_without_already_read
s << ((self.already_read?)? ' read' : ' unread')
return s
end
end
end

class Issue < ActiveRecord::Base
has_many :already_reads, :include => [:user], :order => :created_on
has_many :already_read_users, :through => :already_reads, :source => :user
after_update :reset_already_read

# 状態を文字で返す
def already_read(user = User.current)
return (already_read?(user))? l(:label_read) : l(:label_unread)
end

# 既読ならtrueを返す
def already_read?(user = User.current)
return !user.anonymous? && user.already_read_issue_ids.include?(self.id)
end

# チケットを読んだ日
def already_read_date(user = User.current)
read = already_reads.detect{|r| r.user_id == user.id}
return (read)? read.created_on : nil
end

private
# 既読フラグはチケットを更新したらリセットする
def reset_already_read
AlreadyRead.destroy_all(:issue_id => self.id)
end
end

Issue.send(:include, AlreadyReadIssuePatch)
13 changes: 13 additions & 0 deletions lib/already_read/issues_controller_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require_dependency 'issues_controller'

class IssuesController < ApplicationController
after_filter :issue_read, :only => [:show]

private
# 既読フラグを付ける
def issue_read
if User.current.logged? && @issue && !@issue.already_read?
User.current.already_read_issues << @issue
end
end
end
50 changes: 50 additions & 0 deletions lib/already_read/query_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require_dependency 'query'

Query.add_available_column(QueryColumn.new(:already_read))
Query.add_available_column(QueryColumn.new(:already_read_date))

module AlreadyReadQueryPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods) # obj.method

base.class_eval do
alias_method_chain :available_filters, :already_read
end
end

module InstanceMethods # obj.method
# 既読フィルタを追加
def available_filters_with_already_read
return @available_filters if @available_filters
available_filters_without_already_read

if !has_filter?('already_read')
@available_filters['already_read'] = {:type => :list, :order => 20, :values => @available_filters['author_id'][:values]}
end

return @available_filters
end
end
end

class Query < ActiveRecord::Base
# 既読/未読検出のSQL
def sql_for_already_read_field(field, operator, value)
db_table = AlreadyRead.table_name
# <<自分>>を変換
if value.include?('me') && value.delete('me')
if User.current.logged?
value.push(User.current.id.to_s)
elsif value.empty?
value.push("0")
end
end
op = ('=' == operator)? 'IN' : 'NOT IN'

sql = "#{Issue.table_name}.id #{op} (SELECT #{db_table}.issue_id FROM #{db_table} WHERE " + sql_for_field(field, '=', value, db_table, 'user_id') + ")"

return sql
end
end

Query.send(:include, AlreadyReadQueryPatch)
7 changes: 7 additions & 0 deletions lib/already_read/user_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require_dependency 'principal'
require_dependency 'user'

class User < Principal
has_many :already_reads, :order => :created_on
has_many :already_read_issues, :through => :already_reads, :source => :issue
end
9 changes: 9 additions & 0 deletions test/fixtures/read_issues.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
one:
id: 1
issue_id: 1
user_id: 1
two:
id: 2
issue_id: 1
user_id: 1
5 changes: 5 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Load the normal Rails helper
require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')

# Ensure that we are using the temporary fixture path
Engines::Testing.set_fixture_path
10 changes: 10 additions & 0 deletions test/unit/read_issues_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'

class ReadIssuesTest < ActiveSupport::TestCase
fixtures :read_issues

# Replace this with your real tests.
def test_truth
assert true
end
end

0 comments on commit 535f708

Please sign in to comment.