- new controller "myController"
- account/my_page moved to my/page - account/my_account mmoved to my/account - "my page" is now customizable (table user_preferences added) git-svn-id: http://redmine.rubyforge.org/svn/trunk@62 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
120e39ba80
commit
362633d486
|
@ -40,7 +40,7 @@ class AccountController < ApplicationController
|
|||
user = User.try_to_login(params[:login], params[:password])
|
||||
if user
|
||||
self.logged_in_user = user
|
||||
redirect_back_or_default :controller => 'account', :action => 'my_page'
|
||||
redirect_back_or_default :controller => 'my', :action => 'page'
|
||||
else
|
||||
flash.now[:notice] = l(:notice_account_invalid_creditentials)
|
||||
end
|
||||
|
@ -52,41 +52,6 @@ class AccountController < ApplicationController
|
|||
self.logged_in_user = nil
|
||||
redirect_to :controller => ''
|
||||
end
|
||||
|
||||
# Show logged in user's page
|
||||
def my_page
|
||||
@user = self.logged_in_user
|
||||
@reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
|
||||
@assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
|
||||
end
|
||||
|
||||
# Edit logged in user's account
|
||||
def my_account
|
||||
@user = self.logged_in_user
|
||||
if request.post? and @user.update_attributes(@params[:user])
|
||||
set_localization
|
||||
flash.now[:notice] = l(:notice_account_updated)
|
||||
self.logged_in_user.reload
|
||||
end
|
||||
end
|
||||
|
||||
# Change logged in user's password
|
||||
def change_password
|
||||
@user = self.logged_in_user
|
||||
flash[:notice] = l(:notice_can_t_change_password) and redirect_to :action => 'my_account' and return if @user.auth_source_id
|
||||
if @user.check_password?(@params[:password])
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if @user.save
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
else
|
||||
render :action => 'my_account'
|
||||
return
|
||||
end
|
||||
else
|
||||
flash[:notice] = l(:notice_account_wrong_password)
|
||||
end
|
||||
redirect_to :action => 'my_account'
|
||||
end
|
||||
|
||||
# Enable user to choose a new password
|
||||
def lost_password
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
# redMine - project management software
|
||||
# Copyright (C) 2006 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class MyController < ApplicationController
|
||||
layout 'base'
|
||||
before_filter :require_login
|
||||
|
||||
BLOCKS = { 'issues_assigned_to_me' => :label_assigned_to_me_issues,
|
||||
'issues_reported_by_me' => :label_reported_issues,
|
||||
'latest_news' => :label_news_latest,
|
||||
'calendar' => :label_calendar,
|
||||
'documents' => :label_document_plural
|
||||
}.freeze
|
||||
|
||||
verify :xhr => true,
|
||||
:session => :page_layout,
|
||||
:only => [:add_block, :remove_block, :order_blocks]
|
||||
|
||||
def index
|
||||
page
|
||||
render :action => 'page'
|
||||
end
|
||||
|
||||
# Show user's page
|
||||
def page
|
||||
@user = self.logged_in_user
|
||||
@blocks = @user.pref[:my_page_layout] || { 'left' => ['issues_assigned_to_me'], 'right' => ['issues_reported_by_me'] }
|
||||
end
|
||||
|
||||
# Edit user's account
|
||||
def account
|
||||
@user = self.logged_in_user
|
||||
if request.post? and @user.update_attributes(@params[:user])
|
||||
set_localization
|
||||
flash.now[:notice] = l(:notice_account_updated)
|
||||
self.logged_in_user.reload
|
||||
end
|
||||
end
|
||||
|
||||
# Change user's password
|
||||
def change_password
|
||||
@user = self.logged_in_user
|
||||
flash[:notice] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
|
||||
if @user.check_password?(@params[:password])
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if @user.save
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
else
|
||||
render :action => 'account'
|
||||
return
|
||||
end
|
||||
else
|
||||
flash[:notice] = l(:notice_account_wrong_password)
|
||||
end
|
||||
redirect_to :action => 'account'
|
||||
end
|
||||
|
||||
# User's page layout configuration
|
||||
def page_layout
|
||||
@user = self.logged_in_user
|
||||
@blocks = @user.pref[:my_page_layout] || { 'left' => ['issues_assigned_to_me'], 'right' => ['issues_reported_by_me'] }
|
||||
session[:page_layout] = @blocks
|
||||
%w(top left right).each {|f| session[:page_layout][f] ||= [] }
|
||||
@block_options = []
|
||||
BLOCKS.each {|k, v| @block_options << [l(v), k]}
|
||||
end
|
||||
|
||||
# Add a block to user's page
|
||||
# The block is added on top of the page
|
||||
# params[:block] : id of the block to add
|
||||
def add_block
|
||||
@user = self.logged_in_user
|
||||
block = params[:block]
|
||||
# remove if already present in a group
|
||||
%w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block }
|
||||
# add it on top
|
||||
session[:page_layout]['top'].unshift block
|
||||
render :partial => "block", :locals => {:user => @user, :block_name => block}
|
||||
end
|
||||
|
||||
# Remove a block to user's page
|
||||
# params[:block] : id of the block to remove
|
||||
def remove_block
|
||||
block = params[:block]
|
||||
# remove block in all groups
|
||||
%w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block }
|
||||
render :nothing => true
|
||||
end
|
||||
|
||||
# Change blocks order on user's page
|
||||
# params[:group] : group to order (top, left or right)
|
||||
# params[:list-(top|left|right)] : array of block ids of the group
|
||||
def order_blocks
|
||||
group = params[:group]
|
||||
group_items = params["list-#{group}"]
|
||||
if group_items and group_items.is_a? Array
|
||||
# remove group blocks if they are presents in other groups
|
||||
%w(top left right).each {|f|
|
||||
session[:page_layout][f] = (session[:page_layout][f] || []) - group_items
|
||||
}
|
||||
session[:page_layout][group] = group_items
|
||||
end
|
||||
render :nothing => true
|
||||
end
|
||||
|
||||
# Save user's page layout
|
||||
def page_layout_save
|
||||
@user = self.logged_in_user
|
||||
@user.pref[:my_page_layout] = session[:page_layout] if session[:page_layout]
|
||||
@user.pref.save
|
||||
session[:page_layout] = nil
|
||||
redirect_to :action => 'page'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# redMine - project management software
|
||||
# Copyright (C) 2006 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module MyHelper
|
||||
end
|
|
@ -19,7 +19,9 @@ require "digest/sha1"
|
|||
|
||||
class User < ActiveRecord::Base
|
||||
has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
|
||||
has_many :projects, :through => :memberships
|
||||
has_many :custom_values, :dependent => true, :as => :customized
|
||||
has_one :preference, :dependent => true, :class_name => 'UserPreference'
|
||||
belongs_to :auth_source
|
||||
|
||||
attr_accessor :password, :password_confirmation
|
||||
|
@ -114,6 +116,10 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
@role_for_projects[project_id]
|
||||
end
|
||||
|
||||
def pref
|
||||
self.preference ||= UserPreference.new(:user => self)
|
||||
end
|
||||
|
||||
private
|
||||
# Return password digest
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# redMine - project management software
|
||||
# Copyright (C) 2006 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class UserPreference < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
serialize :others, Hash
|
||||
|
||||
attr_protected :others
|
||||
|
||||
def initialize(attributes = nil)
|
||||
super
|
||||
self.others ||= {}
|
||||
end
|
||||
|
||||
def [](attr_name)
|
||||
if attribute_present? attr_name
|
||||
super
|
||||
else
|
||||
others[attr_name]
|
||||
end
|
||||
end
|
||||
|
||||
def []=(attr_name, value)
|
||||
if attribute_present? attr_name
|
||||
super
|
||||
else
|
||||
others.store attr_name, value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
<h2><%=l(:label_my_page)%></h2>
|
||||
|
||||
<p>
|
||||
<% unless @user.last_before_login_on.nil? %>
|
||||
<%=l(:label_last_login)%>: <%= format_time(@user.last_before_login_on) %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<div class="splitcontentleft">
|
||||
<h3><%=l(:label_reported_issues)%></h3>
|
||||
<%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %>
|
||||
<% if @reported_issues.length > 0 %>
|
||||
<p><%=lwr(:label_last_updates, @reported_issues.length)%></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="splitcontentright">
|
||||
<h3><%=l(:label_assigned_to_me_issues)%></h3>
|
||||
<%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %>
|
||||
<% if @assigned_issues.length > 0 %>
|
||||
<p><%=lwr(:label_last_updates, @assigned_issues.length)%></p>
|
||||
<% end %>
|
||||
</div>
|
|
@ -70,7 +70,7 @@ var menu_contenu=' \
|
|||
<div id="navigation">
|
||||
<ul>
|
||||
<li class="selected"><%= link_to l(:label_home), { :controller => '' }, :class => "picHome" %></li>
|
||||
<li><%= link_to l(:label_my_page), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
|
||||
<li><%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'}, :class => "picUserPage" %></li>
|
||||
<li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "picProject" %></li>
|
||||
|
||||
<% unless @project.nil? || @project.id.nil? %>
|
||||
|
@ -78,7 +78,7 @@ var menu_contenu=' \
|
|||
<% end %>
|
||||
|
||||
<% if loggedin? %>
|
||||
<li><%= link_to l(:label_my_account), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
|
||||
<li><%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' }, :class => "picUser" %></li>
|
||||
<% end %>
|
||||
|
||||
<% if admin_loggedin? %>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<div id="block_<%= block_name %>" class="mypage-box">
|
||||
|
||||
<div style="float:right;margin-right:16px;z-index:500;">
|
||||
<%= link_to_remote "", {
|
||||
:url => { :action => "remove_block", :block => block_name },
|
||||
:complete => "removeBlock('block_#{block_name}')",
|
||||
:loading => "Element.show('indicator')",
|
||||
:loaded => "Element.hide('indicator')" },
|
||||
:class => "close-icon"
|
||||
%>
|
||||
</div>
|
||||
|
||||
<div class="handle">
|
||||
<%= render :partial => "my/blocks/#{block_name}", :locals => { :user => user } %>
|
||||
</div>
|
||||
</div>
|
|
@ -9,7 +9,7 @@
|
|||
<div class="box">
|
||||
<h3><%=l(:label_information_plural)%></h3>
|
||||
|
||||
<%= start_form_tag({:action => 'my_account'}, :class => "tabular") %>
|
||||
<%= start_form_tag({:action => 'account'}, :class => "tabular") %>
|
||||
|
||||
<!--[form:user]-->
|
||||
<p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label>
|
|
@ -0,0 +1,45 @@
|
|||
<h3><%= l(:label_calendar) %></h3>
|
||||
|
||||
<%
|
||||
@date_from = Date.today - (Date.today.cwday-1)
|
||||
@date_to = Date.today + (7-Date.today.cwday)
|
||||
@issues = Issue.find :all,
|
||||
:conditions => ["issues.project_id in (#{@user.projects.collect{|m| m.id}.join(',')}) AND ((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to],
|
||||
:include => [:project, :tracker] unless @user.projects.empty?
|
||||
@issues ||= []
|
||||
%>
|
||||
|
||||
<table class="calenderTable">
|
||||
<tr class="ListHead">
|
||||
<td></td>
|
||||
<% 1.upto(7) do |d| %>
|
||||
<td align="center" width="14%"><%= day_name(d) %></td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<tr height="100">
|
||||
<% day = @date_from
|
||||
while day <= @date_to
|
||||
if day.cwday == 1 %>
|
||||
<td valign="middle"><%= day.cweek %></td>
|
||||
<% end %>
|
||||
<td valign="top" width="14%" class="<%= day.month==@month ? "even" : "odd" %>">
|
||||
<p align="right"><%= day==Date.today ? "<b>#{day.day}</b>" : day.day %></p>
|
||||
<% day_issues = []
|
||||
@issues.each { |i| day_issues << i if i.start_date == day or i.due_date == day }
|
||||
day_issues.each do |i| %>
|
||||
<%= if day == i.start_date and day == i.due_date
|
||||
image_tag('arrow_bw')
|
||||
elsif day == i.start_date
|
||||
image_tag('arrow_from')
|
||||
elsif day == i.due_date
|
||||
image_tag('arrow_to')
|
||||
end %>
|
||||
<small><%= link_to "#{i.tracker.name} ##{i.id}", :controller => 'issues', :action => 'show', :id => i %>: <%= i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)') %></small><br />
|
||||
<% end %>
|
||||
</td>
|
||||
<%= '</tr><tr height="100">' if day.cwday >= 7 and day!=@date_to %>
|
||||
<%
|
||||
day = day + 1
|
||||
end %>
|
||||
</tr>
|
||||
</table>
|
|
@ -0,0 +1,15 @@
|
|||
<h3><%=l(:label_document_plural)%></h3>
|
||||
|
||||
<ul>
|
||||
<% for document in Document.find :all,
|
||||
:limit => 10,
|
||||
:conditions => "documents.project_id in (#{@user.projects.collect{|m| m.id}.join(',')})",
|
||||
:include => [:project] %>
|
||||
<li>
|
||||
<b><%= link_to document.title, :controller => 'documents', :action => 'show', :id => document %></b>
|
||||
<br />
|
||||
<%= truncate document.description, 150 %><br />
|
||||
<em><%= format_time(document.created_on) %></em><br />
|
||||
</li>
|
||||
<% end unless @user.projects.empty? %>
|
||||
</ul>
|
|
@ -0,0 +1,10 @@
|
|||
<h3><%=l(:label_assigned_to_me_issues)%></h3>
|
||||
<% assigned_issues = Issue.find(:all,
|
||||
:conditions => ["assigned_to_id=?", user.id],
|
||||
:limit => 10,
|
||||
:include => [ :status, :project, :tracker ],
|
||||
:order => 'issues.updated_on DESC') %>
|
||||
<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
|
||||
<% if assigned_issues.length > 0 %>
|
||||
<p><%=lwr(:label_last_updates, assigned_issues.length)%></p>
|
||||
<% end %>
|
|
@ -0,0 +1,10 @@
|
|||
<h3><%=l(:label_reported_issues)%></h3>
|
||||
<% reported_issues = Issue.find(:all,
|
||||
:conditions => ["author_id=?", user.id],
|
||||
:limit => 10,
|
||||
:include => [ :status, :project, :tracker ],
|
||||
:order => 'issues.updated_on DESC') %>
|
||||
<%= render :partial => 'issues/list_simple', :locals => { :issues => reported_issues } %>
|
||||
<% if reported_issues.length > 0 %>
|
||||
<p><%=lwr(:label_last_updates, reported_issues.length)%></p>
|
||||
<% end %>
|
|
@ -0,0 +1,13 @@
|
|||
<h3><%=l(:label_news_latest)%></h3>
|
||||
|
||||
<ul>
|
||||
<% for news in News.find :all,
|
||||
:limit => 10,
|
||||
:conditions => "news.project_id in (#{@user.projects.collect{|m| m.id}.join(',')})",
|
||||
:include => [:project, :author] %>
|
||||
<li><%= link_to news.title, :controller => 'news', :action => 'show', :id => news %><br />
|
||||
<% unless news.summary.empty? %><%= news.summary %><br /><% end %>
|
||||
<em><%= news.author.name %>, <%= format_time(news.created_on) %></em><br />
|
||||
</li>
|
||||
<% end unless @user.projects.empty? %>
|
||||
</ul>
|
|
@ -0,0 +1,30 @@
|
|||
<h2><%=l(:label_my_page)%></h2>
|
||||
|
||||
<div class="topright">
|
||||
<small><%= link_to l(:label_personalize_page), :action => 'page_layout' %></small>
|
||||
</div>
|
||||
|
||||
<div id="list-top">
|
||||
<% @blocks['top'].each do |b| %>
|
||||
<div class="mypage-box">
|
||||
<%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
|
||||
</div>
|
||||
<% end if @blocks['top'] %>
|
||||
</div>
|
||||
|
||||
<div id="list-left" class="splitcontentleft">
|
||||
<% @blocks['left'].each do |b| %>
|
||||
<div class="mypage-box">
|
||||
<%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
|
||||
</div>
|
||||
<% end if @blocks['left'] %>
|
||||
</div>
|
||||
|
||||
<div id="list-right" class="splitcontentright">
|
||||
<% @blocks['right'].each do |b| %>
|
||||
<div class="mypage-box">
|
||||
<%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
|
||||
</div>
|
||||
<% end if @blocks['right'] %>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<script language="JavaScript">
|
||||
|
||||
function recreateSortables() {
|
||||
Sortable.destroy('list-top');
|
||||
Sortable.destroy('list-left');
|
||||
Sortable.destroy('list-right');
|
||||
|
||||
Sortable.create("list-top", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=top', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Highlight("list-top",{});}, onLoaded:function(request){Element.hide('indicator')}, onLoading:function(request){Element.show('indicator')}, parameters:Sortable.serialize("list-top")})}, only:'mypage-box', tag:'div'})
|
||||
Sortable.create("list-left", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=left', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Highlight("list-left",{});}, onLoaded:function(request){Element.hide('indicator')}, onLoading:function(request){Element.show('indicator')}, parameters:Sortable.serialize("list-left")})}, only:'mypage-box', tag:'div'})
|
||||
Sortable.create("list-right", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=right', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Highlight("list-right",{});}, onLoaded:function(request){Element.hide('indicator')}, onLoading:function(request){Element.show('indicator')}, parameters:Sortable.serialize("list-right")})}, only:'mypage-box', tag:'div'})
|
||||
}
|
||||
|
||||
function updateSelect() {
|
||||
s = $('block-select')
|
||||
for (var i = 0; i < s.options.length; i++) {
|
||||
if ($('block_' + s.options[i].value)) {
|
||||
s.options[i].disabled = true;
|
||||
} else {
|
||||
s.options[i].disabled = false;
|
||||
}
|
||||
}
|
||||
s.options[0].selected = true;
|
||||
}
|
||||
|
||||
function afterAddBlock() {
|
||||
recreateSortables();
|
||||
updateSelect();
|
||||
}
|
||||
|
||||
function removeBlock(block) {
|
||||
$(block).parentNode.removeChild($(block));
|
||||
updateSelect();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div style="float:right;">
|
||||
<%= start_form_tag({:action => "add_block"}, :id => "block-form") %>
|
||||
|
||||
<%= select_tag 'block', "<option></option>" + options_for_select(@block_options), :id => "block-select", :class => "select-small" %>
|
||||
<small>
|
||||
<%= link_to_remote l(:button_add),
|
||||
:url => { :action => "add_block" },
|
||||
:with => "Form.serialize('block-form')",
|
||||
:update => "list-top",
|
||||
:position => :top,
|
||||
:complete => "afterAddBlock();",
|
||||
:loading => "Element.show('indicator')",
|
||||
:loaded => "Element.hide('indicator')"
|
||||
%>
|
||||
</small>
|
||||
<%= end_form_tag %>
|
||||
<small>|
|
||||
<%= link_to l(:button_save), :action => 'page_layout_save' %> |
|
||||
<%= link_to l(:button_cancel), :action => 'page' %>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div style="float:right;margin-right:20px;">
|
||||
<span id="indicator" style="display:none"><%= image_tag "loading.gif" %></span>
|
||||
</div>
|
||||
|
||||
<h2><%=l(:label_my_page)%></h2>
|
||||
|
||||
<div id="list-top" class="block-receiver">
|
||||
<% @blocks['top'].each do |b| %>
|
||||
<%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
|
||||
<% end if @blocks['top'] %>
|
||||
</div>
|
||||
|
||||
<div id="list-left" class="splitcontentleft block-receiver">
|
||||
<% @blocks['left'].each do |b| %>
|
||||
<%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
|
||||
<% end if @blocks['left'] %>
|
||||
</div>
|
||||
|
||||
<div id="list-right" class="splitcontentright block-receiver">
|
||||
<% @blocks['right'].each do |b| %>
|
||||
<%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
|
||||
<% end if @blocks['right'] %>
|
||||
</div>
|
||||
|
||||
<%= sortable_element 'list-top',
|
||||
:tag => 'div',
|
||||
:only => 'mypage-box',
|
||||
:handle => "handle",
|
||||
:dropOnEmpty => true,
|
||||
:containment => ['list-top', 'list-left', 'list-right'],
|
||||
:constraint => false,
|
||||
:complete => visual_effect(:highlight, 'list-top'),
|
||||
:url => { :action => "order_blocks", :group => "top" },
|
||||
:loading => "Element.show('indicator')",
|
||||
:loaded => "Element.hide('indicator')"
|
||||
%>
|
||||
|
||||
|
||||
<%= sortable_element 'list-left',
|
||||
:tag => 'div',
|
||||
:only => 'mypage-box',
|
||||
:handle => "handle",
|
||||
:dropOnEmpty => true,
|
||||
:containment => ['list-top', 'list-left', 'list-right'],
|
||||
:constraint => false,
|
||||
:complete => visual_effect(:highlight, 'list-left'),
|
||||
:url => { :action => "order_blocks", :group => "left" },
|
||||
:loading => "Element.show('indicator')",
|
||||
:loaded => "Element.hide('indicator')" %>
|
||||
|
||||
<%= sortable_element 'list-right',
|
||||
:tag => 'div',
|
||||
:only => 'mypage-box',
|
||||
:handle => "handle",
|
||||
:dropOnEmpty => true,
|
||||
:containment => ['list-top', 'list-left', 'list-right'],
|
||||
:constraint => false,
|
||||
:complete => visual_effect(:highlight, 'list-right'),
|
||||
:url => { :action => "order_blocks", :group => "right" },
|
||||
:loading => "Element.show('indicator')",
|
||||
:loaded => "Element.hide('indicator')" %>
|
||||
|
||||
<%= javascript_tag "updateSelect()" %>
|
|
@ -0,0 +1,12 @@
|
|||
class CreateUserPreferences < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :user_preferences do |t|
|
||||
t.column "user_id", :integer, :default => 0, :null => false
|
||||
t.column "others", :text
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :user_preferences
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ http://redmine.org/
|
|||
|
||||
== xx/xx/2006 v0.x.x
|
||||
|
||||
* "my page" is now customizable
|
||||
* improved issues change history
|
||||
* new functionality: move an issue to another project or tracker
|
||||
* new functionality: add a note to an issue
|
||||
|
|
|
@ -257,6 +257,7 @@ label_gantt_chart: Gantt Diagramm
|
|||
label_internal: Intern
|
||||
label_last_changes: %d änderungen des Letzten
|
||||
label_change_view_all: Alle änderungen ansehen
|
||||
label_personalize_page: Diese Seite personifizieren
|
||||
|
||||
button_login: Einloggen
|
||||
button_submit: Einreichen
|
||||
|
@ -278,6 +279,7 @@ button_list: Aufzulisten
|
|||
button_view: Siehe
|
||||
button_move: Bewegen
|
||||
button_back: Rückkehr
|
||||
button_cancel: Annullieren
|
||||
|
||||
text_select_mail_notifications: Aktionen für die Mailbenachrichtigung aktiviert werden soll.
|
||||
text_regexp_info: eg. ^[A-Z0-9]+$
|
||||
|
|
|
@ -257,6 +257,7 @@ label_gantt_chart: Gantt chart
|
|||
label_internal: Internal
|
||||
label_last_changes: last %d changes
|
||||
label_change_view_all: View all changes
|
||||
label_personalize_page: Personalize this page
|
||||
|
||||
button_login: Login
|
||||
button_submit: Submit
|
||||
|
@ -278,6 +279,7 @@ button_list: List
|
|||
button_view: View
|
||||
button_move: Move
|
||||
button_back: Back
|
||||
button_cancel: Cancel
|
||||
|
||||
text_select_mail_notifications: Select actions for which mail notifications should be sent.
|
||||
text_regexp_info: eg. ^[A-Z0-9]+$
|
||||
|
|
|
@ -257,6 +257,7 @@ label_gantt_chart: Diagrama de Gantt
|
|||
label_internal: Interno
|
||||
label_last_changes: %d cambios del último
|
||||
label_change_view_all: Ver todos los cambios
|
||||
label_personalize_page: Personalizar esta página
|
||||
|
||||
button_login: Conexión
|
||||
button_submit: Someter
|
||||
|
@ -278,6 +279,7 @@ button_list: Listar
|
|||
button_view: Ver
|
||||
button_move: Mover
|
||||
button_back: Atrás
|
||||
button_cancel: Cancelar
|
||||
|
||||
text_select_mail_notifications: Seleccionar las actividades que necesitan la activación de la notificación por mail.
|
||||
text_regexp_info: eg. ^[A-Z0-9]+$
|
||||
|
|
|
@ -258,10 +258,11 @@ label_gantt_chart: Diagramme de Gantt
|
|||
label_internal: Interne
|
||||
label_last_changes: %d derniers changements
|
||||
label_change_view_all: Voir tous les changements
|
||||
label_personalize_page: Personnaliser cette page
|
||||
|
||||
button_login: Connexion
|
||||
button_submit: Soumettre
|
||||
button_save: Valider
|
||||
button_save: Sauvegarder
|
||||
button_check_all: Tout cocher
|
||||
button_uncheck_all: Tout décocher
|
||||
button_delete: Supprimer
|
||||
|
@ -279,6 +280,7 @@ button_list: Lister
|
|||
button_view: Voir
|
||||
button_move: Déplacer
|
||||
button_back: Retour
|
||||
button_cancel: Annuler
|
||||
|
||||
text_select_mail_notifications: Sélectionner les actions pour lesquelles la notification par mail doit être activée.
|
||||
text_regexp_info: ex. ^[A-Z0-9]+$
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 200 B |
Binary file not shown.
After Width: | Height: | Size: 199 B |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -379,6 +379,22 @@ color:#505050;
|
|||
line-height:1.5em;
|
||||
}
|
||||
|
||||
a.close-icon {
|
||||
display:block;
|
||||
margin-top:3px;
|
||||
overflow:hidden;
|
||||
width:12px;
|
||||
height:12px;
|
||||
background-repeat: no-repeat;
|
||||
cursor:hand;
|
||||
cursor:pointer;
|
||||
background-image:url('../images/close.png');
|
||||
}
|
||||
|
||||
a.close-icon:hover {
|
||||
background-image:url('../images/close_hl.png');
|
||||
}
|
||||
|
||||
.rightbox{
|
||||
background: #fafbfc;
|
||||
border: 1px solid #c0c0c0;
|
||||
|
@ -388,6 +404,26 @@ position: relative;
|
|||
margin: 0 5px 5px;
|
||||
}
|
||||
|
||||
.layout-active {
|
||||
background: #ECF3E1;
|
||||
}
|
||||
|
||||
.block-receiver {
|
||||
border:1px dashed #c0c0c0;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
.mypage-box {
|
||||
margin:0 0 20px 0;
|
||||
color:#505050;
|
||||
line-height:1.5em;
|
||||
}
|
||||
|
||||
.blocks {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.topright{
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
first:
|
||||
id: 1
|
||||
another:
|
||||
id: 2
|
|
@ -0,0 +1,18 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'my_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class MyController; def rescue_action(e) raise e end; end
|
||||
|
||||
class MyControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = MyController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
|
@ -22,44 +22,44 @@ class AccountTest < ActionController::IntegrationTest
|
|||
|
||||
# Replace this with your real tests.
|
||||
def test_login
|
||||
get "account/my_page"
|
||||
get "my/page"
|
||||
assert_redirected_to "account/login"
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
get "account/my_account"
|
||||
get "my/account"
|
||||
assert_response :success
|
||||
assert_template "account/my_account"
|
||||
assert_template "my/account"
|
||||
end
|
||||
|
||||
def test_change_password
|
||||
log_user('jsmith', 'jsmith')
|
||||
get "account/my_account"
|
||||
get "my/account"
|
||||
assert_response :success
|
||||
assert_template "account/my_account"
|
||||
assert_template "my/account"
|
||||
|
||||
post "account/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello2"
|
||||
post "my/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello2"
|
||||
assert_response :success
|
||||
assert_template "account/my_account"
|
||||
assert_template "my/account"
|
||||
assert_tag :tag => "div", :attributes => { :class => "errorExplanation" }
|
||||
|
||||
post "account/change_password", :password => 'jsmithZZ', :new_password => "hello", :new_password_confirmation => "hello"
|
||||
assert_redirected_to "account/my_account"
|
||||
post "my/change_password", :password => 'jsmithZZ', :new_password => "hello", :new_password_confirmation => "hello"
|
||||
assert_redirected_to "my/account"
|
||||
assert_equal 'Wrong password', flash[:notice]
|
||||
|
||||
post "account/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello"
|
||||
assert_redirected_to "account/my_account"
|
||||
post "my/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello"
|
||||
assert_redirected_to "my/account"
|
||||
log_user('jsmith', 'hello')
|
||||
end
|
||||
|
||||
def test_my_account
|
||||
log_user('jsmith', 'jsmith')
|
||||
get "account/my_account"
|
||||
get "my/account"
|
||||
assert_response :success
|
||||
assert_template "account/my_account"
|
||||
assert_template "my/account"
|
||||
|
||||
post "account/my_account", :user => {:firstname => "Joe", :login => "root", :admin => 1}
|
||||
post "my/account", :user => {:firstname => "Joe", :login => "root", :admin => 1}
|
||||
assert_response :success
|
||||
assert_template "account/my_account"
|
||||
assert_template "my/account"
|
||||
user = User.find(2)
|
||||
assert_equal "Joe", user.firstname
|
||||
assert_equal "jsmith", user.login
|
||||
|
@ -68,9 +68,9 @@ class AccountTest < ActionController::IntegrationTest
|
|||
|
||||
def test_my_page
|
||||
log_user('jsmith', 'jsmith')
|
||||
get "account/my_page"
|
||||
get "my/page"
|
||||
assert_response :success
|
||||
assert_template "account/my_page"
|
||||
assert_template "my/page"
|
||||
end
|
||||
|
||||
def test_lost_password
|
||||
|
|
|
@ -49,7 +49,7 @@ class Test::Unit::TestCase
|
|||
assert_response :success
|
||||
assert_template "account/login"
|
||||
post "/account/login", :login => login, :password => password
|
||||
assert_redirected_to "account/my_page"
|
||||
assert_redirected_to "my/page"
|
||||
assert_equal login, User.find(session[:user_id]).login
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class UserPreferenceTest < Test::Unit::TestCase
|
||||
fixtures :user_preferences
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue