commit
06a05c115c
@ -0,0 +1,51 @@ |
||||
# Widget Boxes |
||||
|
||||
``` |
||||
<form> |
||||
<section class="widget-boxes"> |
||||
<div class="widget-box"> |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-home1"></span> |
||||
<span class="widget-box--header-title">Widget Box</span> |
||||
</h3> |
||||
<p class="widget-box--additional-info">This widget box can be used to display content belonging to one subject.</p> |
||||
<ul class="widget-box--arrow-links"> |
||||
<li> |
||||
<a>Go to Link 1</a> |
||||
</li> |
||||
<li> |
||||
<a>Go to link 2</a> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="widget-box"> |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-home2"></span> |
||||
<span class="widget-box--header-title">Widget Box 2</span> |
||||
</h3> |
||||
<ul class="widget-box--enumeration"> |
||||
<li> |
||||
Enum1 |
||||
</li> |
||||
<li> |
||||
Enum2 |
||||
</li> |
||||
<li> |
||||
Enum3 |
||||
</li> |
||||
<li> |
||||
Enum4 |
||||
</li> |
||||
</ul> |
||||
<div class="widget-box--buttons"> |
||||
<a class="button -highlight"> |
||||
<i class="button--icon icon-add"></i> |
||||
<span class="button--text">Add</span> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
</form> |
||||
|
||||
``` |
@ -0,0 +1,106 @@ |
||||
//-- copyright |
||||
// OpenProject is a project management system. |
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
// |
||||
// This program is free software; you can redistribute it and/or |
||||
// modify it under the terms of the GNU General Public License version 3. |
||||
// |
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
// Copyright (C) 2010-2013 the ChiliProject Team |
||||
// |
||||
// 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. |
||||
// |
||||
// See doc/COPYRIGHT.rdoc for more details. |
||||
//++ |
||||
|
||||
@mixin widget-box--style |
||||
background: $widget-box-block-bg-color |
||||
border: 1px solid $widget-box-block-border-color |
||||
margin: 10px |
||||
|
||||
$widget-box--enumeration-width: 20px |
||||
|
||||
.widget-boxes--screen-header |
||||
margin-left: 10px |
||||
|
||||
.widget-boxes |
||||
display: flex |
||||
flex-flow: row wrap |
||||
|
||||
.icon-context:before |
||||
padding-right: 5px |
||||
|
||||
.widget-box |
||||
@include widget-box--style |
||||
padding: 10px 10px 10px 20px |
||||
flex: 1 |
||||
flex-basis: 32% |
||||
display: flex |
||||
flex-direction: column |
||||
min-height: 250px |
||||
word-wrap: break-words |
||||
overflow: hidden |
||||
|
||||
.widget-box--header |
||||
font-weight: bold |
||||
font-size: 1.25rem |
||||
border: none |
||||
|
||||
.widget-box--header-title |
||||
vertical-align: middle |
||||
.icon:before, |
||||
.icon-context:before |
||||
vertical-align: middle |
||||
|
||||
|
||||
.widget-box--additional-info |
||||
margin: 0 |
||||
font-size: 0.9rem |
||||
font-style: italic |
||||
|
||||
.widget-box--enumeration |
||||
margin-left: 1.5rem |
||||
margin-top: 0.5rem |
||||
flex-grow: 2 |
||||
|
||||
.widget-box--arrow-links |
||||
list-style: none |
||||
margin: 0.5rem 0 1rem 0 |
||||
flex-grow: 2 |
||||
|
||||
li:before |
||||
@include icon-common |
||||
@extend .icon-context |
||||
content: "\e03f" |
||||
display: inline-block |
||||
font-size: 0.6rem |
||||
color: $content-icon-link-color |
||||
width: $widget-box--enumeration-width |
||||
|
||||
.-widget-box--arrow-multiline |
||||
&:before |
||||
float: left |
||||
|
||||
&:after |
||||
clear: both |
||||
content: "" |
||||
display: table |
||||
|
||||
> div |
||||
float: left |
||||
margin-bottom: 10px |
||||
//necessary for correct alignment even with long texts |
||||
width: calc(100% - #{$widget-box--enumeration-width}) |
@ -0,0 +1,110 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module UserInvitation |
||||
EVENT_NAME = 'user_invited' |
||||
|
||||
module_function |
||||
|
||||
## |
||||
# Creates an invited user with the given email address. |
||||
# If no first and last is given it will default to 'OpenProject User' |
||||
# for the first name and 'To-be' for the last name. |
||||
# The default login is the email address. |
||||
# |
||||
# @param email E-Mail address the invitation is sent to. |
||||
# @param login User's login (optional) |
||||
# @param first_name The user's first name (optional) |
||||
# @param last_name The user's last name (optional) |
||||
# |
||||
# @yield [user] Allows modifying the created user before saving it. |
||||
# |
||||
# @return The invited user. If the invitation failed, calling `#registered?` |
||||
# on the returned user will yield `false`. Check for validation errors |
||||
# in that case. |
||||
def invite_new_user(email:, login: nil, first_name: nil, last_name: nil) |
||||
user = User.new login: login || email, |
||||
mail: email, |
||||
firstname: first_name || email, |
||||
lastname: last_name || '(invited)', |
||||
status: Principal::STATUSES[:invited] |
||||
|
||||
yield user if block_given? |
||||
|
||||
invite_user! user |
||||
end |
||||
|
||||
## |
||||
# Invites the given user. An email will be sent to their email address |
||||
# containing the token necessary for the user to register. |
||||
# |
||||
# Validates and saves the given user. The invitation will fail if the user is invalid. |
||||
# |
||||
# @return The invited user or nil if the invitation failed. |
||||
def invite_user!(user) |
||||
user, token = user_invitation user |
||||
|
||||
if token |
||||
OpenProject::Notifications.send(EVENT_NAME, token) |
||||
|
||||
user |
||||
end |
||||
end |
||||
|
||||
## |
||||
# Creates an invited user with the given email address. |
||||
# If no first and last is given it will default to 'OpenProject User' |
||||
# for the first name and 'To-be' for the last name. |
||||
# The default login is the email address. |
||||
# |
||||
# @return Returns the user and the invitation token required to register. |
||||
def user_invitation(user) |
||||
User.transaction do |
||||
user.invite |
||||
|
||||
if user.valid? |
||||
token = invitation_token user |
||||
token.save! |
||||
|
||||
user.save! |
||||
|
||||
return [user, token] |
||||
end |
||||
end |
||||
|
||||
[user, nil] |
||||
end |
||||
|
||||
def token_action |
||||
'invite' |
||||
end |
||||
|
||||
def invitation_token(user) |
||||
Token.find_or_initialize_by user: user, action: token_action |
||||
end |
||||
end |
@ -0,0 +1,109 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'uri' |
||||
|
||||
class InvitationsController < ApplicationController |
||||
|
||||
skip_before_filter :check_if_login_required, only: [:claim] |
||||
|
||||
def index |
||||
|
||||
end |
||||
|
||||
def create |
||||
email = params.require(:email) |
||||
user = User.create mail: email, login: email, firstname: email, lastname: email |
||||
token = invite_user user |
||||
|
||||
if user.errors.empty? |
||||
first, last = email.split("@") |
||||
user.firstname = first |
||||
user.lastname = "@#{last}" |
||||
user.invite |
||||
|
||||
user.save! |
||||
token.save! |
||||
|
||||
puts |
||||
puts "CREATED NEW TOKEN: #{token.value}" |
||||
puts |
||||
|
||||
redirect_to action: :show, id: user.id |
||||
else |
||||
flash.now[:error] = user.errors.full_messages.first |
||||
|
||||
render 'index', locals: { email: email } |
||||
end |
||||
end |
||||
|
||||
def show |
||||
user = User.find params.require(:id) |
||||
token = Token.find_by action: token_action, user: user |
||||
|
||||
render 'show', locals: { token: token.value, email: user.mail } |
||||
end |
||||
|
||||
def claim |
||||
token = Token.find_by action: token_action, value: params.require(:id) |
||||
|
||||
if current_user.logged? |
||||
flash[:warning] = 'You are already registered, mate.' |
||||
|
||||
redirect_to invitation_path id: token.user_id |
||||
elsif token.expired? |
||||
flash[:error] = 'The invitation has expired.' |
||||
token.destroy |
||||
|
||||
redirect_to signin_path |
||||
else |
||||
session[:invitation_token] = token.value |
||||
flash[:info] = 'Create a new account or register now, pl0x!' |
||||
|
||||
redirect_to signin_path |
||||
end |
||||
end |
||||
|
||||
module Functions |
||||
def token_action |
||||
'invitation' |
||||
end |
||||
|
||||
def invite_user(user) |
||||
token = invitation_token user |
||||
|
||||
token |
||||
end |
||||
|
||||
def invitation_token(user) |
||||
Token.find_or_initialize_by user: user, action: token_action |
||||
end |
||||
end |
||||
|
||||
include Functions |
||||
end |
@ -0,0 +1,50 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module HomescreenHelper |
||||
## |
||||
# Homescreen name |
||||
def organization_name |
||||
Setting.app_title || Setting.software_name |
||||
end |
||||
|
||||
## |
||||
# Homescreen organization icon |
||||
def organization_icon |
||||
content_tag :span, '', class: 'icon-context icon-enterprise' |
||||
end |
||||
|
||||
## |
||||
# Returns the user avatar or a default image |
||||
def homescreen_user_avatar |
||||
avatar = avatar(User.current) |
||||
|
||||
avatar.presence || content_tag(:span, '', class: 'icon-context icon-user1') |
||||
end |
||||
end |
@ -0,0 +1,39 @@ |
||||
class DummyAuthSource < AuthSource |
||||
def test_connection |
||||
# the dummy connection is always available |
||||
end |
||||
|
||||
def authenticate(login, password) |
||||
existing_user(login, password) || on_the_fly_user(login) |
||||
end |
||||
|
||||
def auth_method_name |
||||
'LDAP' |
||||
end |
||||
|
||||
private |
||||
|
||||
def existing_user(login, password) |
||||
registered_login?(login) && password == 'dummy' |
||||
end |
||||
|
||||
def on_the_fly_user(login) |
||||
return nil unless onthefly_register? |
||||
|
||||
{ |
||||
firstname: login.capitalize, |
||||
lastname: 'Dummy', |
||||
mail: 'login@DerpLAP.net', |
||||
auth_source_id: id |
||||
} |
||||
end |
||||
|
||||
def registered_login?(login) |
||||
not users.where(login: login).empty? # empty? to use EXISTS query |
||||
end |
||||
|
||||
# Does this auth source backend allow password changes? |
||||
def self.allow_password_changes? |
||||
false |
||||
end |
||||
end |
@ -0,0 +1,149 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'uri' |
||||
require 'cgi' |
||||
|
||||
# This capsulates the validation of a requested redirect URL. |
||||
# |
||||
class RedirectPolicy |
||||
attr_reader :validated_redirect_url, :request |
||||
|
||||
def initialize(requested_url, hostname:, default:, return_escaped: true) |
||||
@current_host = hostname |
||||
@return_escaped = return_escaped |
||||
|
||||
@requested_url = preprocess(requested_url) |
||||
@default_url = default |
||||
end |
||||
|
||||
## |
||||
# Performs all validations for the requested URL |
||||
def valid? |
||||
return false if @requested_url.nil? |
||||
|
||||
[ |
||||
# back_url must not contain two consecutive dots |
||||
:no_upper_levels, |
||||
# Require the path to begin with a slash |
||||
:path_has_slash, |
||||
# do not redirect user to another host |
||||
:same_host, |
||||
# do not redirect user to the login or register page |
||||
:path_not_blacklisted, |
||||
# do not redirect to another subdirectory |
||||
:matches_relative_root |
||||
].all? { |check| send(check) } |
||||
end |
||||
|
||||
## |
||||
# Return a valid redirect URI. |
||||
# If the validation check on the current back URL apply |
||||
def redirect_url |
||||
if valid? |
||||
postprocess(@requested_url) |
||||
else |
||||
@default_url |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
## |
||||
# Preprocesses the requested redirect URL. |
||||
# - Escapes it when necessary |
||||
# - Tries to parse it |
||||
# - Escapes the redirect URL when requested so. |
||||
def preprocess(requested) |
||||
url = URI.escape(CGI.unescape(requested.to_s)) |
||||
URI.parse(url) |
||||
rescue URI::InvalidURIError => e |
||||
Rails.logger.warn("Encountered invalid redirect URL '#{requested}': #{e.message}") |
||||
nil |
||||
end |
||||
|
||||
## |
||||
# Postprocesses the validated URL |
||||
def postprocess(redirect_url) |
||||
# Remove basic auth credentials |
||||
redirect_url.userinfo = '' |
||||
|
||||
if @return_escaped |
||||
redirect_url.to_s |
||||
else |
||||
URI.unescape(redirect_url.to_s) |
||||
end |
||||
end |
||||
|
||||
## |
||||
# Avoid paths with references to parent paths |
||||
def no_upper_levels |
||||
!@requested_url.path.include? '../' |
||||
end |
||||
|
||||
## |
||||
# Require URLs to contain a path slash. |
||||
# This will always be the case for parsed URLs unless |
||||
# +URI.parse('@foo.bar')+ or a non-root relative URL +URI.parse('foo')+ |
||||
def path_has_slash |
||||
@requested_url.path =~ %r{\A/([^/]|\z)} |
||||
end |
||||
|
||||
## |
||||
# do not redirect user to another host (even protocol relative urls have the host set) |
||||
# whenever a host is set it must match the request's host |
||||
def same_host |
||||
@requested_url.host.nil? || @requested_url.host == @current_host |
||||
end |
||||
|
||||
## |
||||
# Avoid redirect URLs to specific locations, such as login page |
||||
def path_not_blacklisted |
||||
!@requested_url.path.match( |
||||
%r{/( |
||||
# Ignore login since redirect to back url is result of successful login. |
||||
login | |
||||
# When signing out with a direct login provider enabled you will be left at the logout |
||||
# page with a message indicating that you were logged out. Logging in from there would |
||||
# normally cause you to be redirected to this page. As it is the logout page, however, |
||||
# this would log you right out again after a successful login. |
||||
logout | |
||||
# Avoid sending users to the register form. The exact reasoning behind |
||||
# this is unclear, but grown from tradition. |
||||
account/register |
||||
)}x # ignore whitespace |
||||
) |
||||
end |
||||
|
||||
## |
||||
# Requires the redirect URL to reside inside the relative root, when given. |
||||
def matches_relative_root |
||||
relative_root = OpenProject::Configuration['rails_relative_url_root'] |
||||
relative_root.blank? || @requested_url.path.starts_with?(relative_root) |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-settings"></span> |
||||
<span class="widget-box--header-title"><%= l(:label_administration) %></span> |
||||
</h3> |
||||
|
||||
<ul class="widget-box--arrow-links"> |
||||
<li> |
||||
<%= link_to l(:label_project_plural), admin_projects_path, |
||||
title: l(:label_project_plural) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_user_plural), users_path, |
||||
title: l(:label_user_plural) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_group_plural), groups_path, |
||||
title: l(:label_group_plural) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_role_and_permissions), roles_path, |
||||
title: l(:label_role_and_permissions) %> |
||||
|
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_work_package_types), types_path, |
||||
title: l(:label_work_package_types) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_work_package_status), statuses_path, |
||||
title: l(:label_work_package_status) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_workflow_plural), workflows_path, |
||||
title: l(:label_workflow_plural) %> |
||||
|
||||
</li> |
||||
<li> |
||||
<%= link_to l('attributes.custom_values'), custom_fields_path, |
||||
title: l('attributes.custom_values') %> |
||||
|
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_settings), settings_path, |
||||
title: l(:label_settings) %> |
||||
</li> |
||||
<%= call_hook(:homescreen_administration_links) %> |
||||
</ul> |
@ -0,0 +1,55 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-op-icon"></span> |
||||
<span class="widget-box--header-title"><%= l('homescreen.blocks.community') %></span> |
||||
</h3> |
||||
|
||||
<ul class="widget-box--arrow-links"> |
||||
<li> |
||||
<a href="https://www.openproject.org/open-source/release-notes/" |
||||
title="<%= l(:label_release_notes) %>"> |
||||
<%= l(:label_release_notes) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://community.openproject.org/projects/openproject/roadmap" |
||||
title="<%= l(:label_development_roadmap) %>"> |
||||
<%= l(:label_development_roadmap) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://community.openproject.org/projects/openproject/work_packages" |
||||
title="<%= l(:label_report_bug) %>"> |
||||
<%= l(:label_report_bug) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://www.openproject.com/enterprise-services/" |
||||
title="<%= l(:label_professional_support) %>"> |
||||
<%= l(:label_professional_support) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://www.openproject.org/blog/" |
||||
title="<%= l(:label_blog) %>"> |
||||
<%= l(:label_blog) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://www.openproject.org/open-source/openproject-plugins/" |
||||
title="<%= l(:label_plugins) %>"> |
||||
<%= l(:label_plugins) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://crowdin.com/projects/opf" |
||||
title="<%= l(:label_add_edit_translations) %>"> |
||||
<%= l(:label_add_edit_translations) %> |
||||
</a> |
||||
</li> |
||||
<li> |
||||
<a href="https://www.openproject.org/api/" |
||||
title="<%= l(:label_api_documentation) %>"> |
||||
<%= l(:label_api_documentation) %> |
||||
</a> |
||||
</li> |
||||
</ul> |
@ -0,0 +1,17 @@ |
||||
<h3 class="widget-box--header"> |
||||
<%= homescreen_user_avatar %> |
||||
<span class="widget-box--header-title"><%= l(:label_my_account) %></span> |
||||
</h3> |
||||
|
||||
<ul class="widget-box--arrow-links"> |
||||
<li> |
||||
<%= link_to l(:label_profile), my_account_path, title: l(:label_profile) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:label_my_page), my_page_path, |
||||
title: l(:label_my_page) %> |
||||
</li> |
||||
<li> |
||||
<%= link_to l(:button_change_password), my_password_path, title: l(:button_change_password) %> |
||||
</li> |
||||
</ul> |
@ -0,0 +1,20 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-news"></span> |
||||
<span class="widget-box--header-title"><%= l(:label_news_latest) %></span> |
||||
</h3> |
||||
|
||||
<% unless @news.empty? %> |
||||
<ul class="widget-box--arrow-links"> |
||||
<% @news.each do |news| %> |
||||
<li class="-widget-box--arrow-multiline"> |
||||
<div> |
||||
<%= avatar(news.author, {class: 'avatar-mini'}) %> |
||||
<%= link_to_project(news.project) + ': ' %> |
||||
<%= link_to h(news.title), news_path(news) %> |
||||
<br/> |
||||
<p class="widget-box--additional-info"><%= authoring news.created_on, news.author %></p> |
||||
</div> |
||||
</li> |
||||
<% end %> |
||||
</ul> |
||||
<% end %> |
@ -0,0 +1,28 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-unit"></span> |
||||
<span class="widget-box--header-title"><%= l(:label_project_plural) %></span> |
||||
</h3> |
||||
|
||||
<% unless @newest_projects.empty? %> |
||||
<p class="widget-box--additional-info"><%= l('homescreen.additional.projects') %></p> |
||||
<ul class="widget-box--arrow-links"> |
||||
<% @newest_projects.each do |project| %> |
||||
<li> |
||||
<%= link_to project, project_path(project), :title => project.short_description %> |
||||
<small>(<%= format_date(project.created_on) %>)</small> |
||||
</li> |
||||
<% end %> |
||||
</ul> |
||||
<% end %> |
||||
|
||||
<div class="widget-box--blocks--buttons"> |
||||
<% if User.current.allowed_to?(:add_project, nil, global: true) %> |
||||
<%= link_to new_project_path, class: 'button -alt-highlight' do %> |
||||
<i class="button--icon icon-add"></i> |
||||
<span class="button--text"><%= l(:label_project_new) %></span> |
||||
<% end %> |
||||
<% end %> |
||||
<%= link_to l(:label_project_view_all), projects_path, |
||||
class: 'button -highlight', |
||||
title: l(:label_project_view_all) %> |
||||
</div> |
@ -0,0 +1,26 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-group"></span> |
||||
<span class="widget-box--header-title"><%= l(:label_user_plural) %></span> |
||||
</h3> |
||||
|
||||
<p class="widget-box--additional-info"><%= l('homescreen.additional.users') %></p> |
||||
|
||||
<% unless @newest_users.empty? %> |
||||
<ul class="widget-box--arrow-links"> |
||||
<% @newest_users.each do |user| %> |
||||
<li> |
||||
<%= link_to user, user_path(user), :title => user.name %> |
||||
<small>(<%= format_date(user.created_on) %>)</small> |
||||
</li> |
||||
<% end %> |
||||
</ul> |
||||
<% end %> |
||||
|
||||
<div class="widget-box--buttons"> |
||||
<% if User.current.admin? %> |
||||
<%= link_to new_user_path, class: 'button -alt-highlight' do %> |
||||
<i class="button--icon icon-add"></i> |
||||
<span class="button--text"><%= l(:label_invite_user) %></span> |
||||
<% end %> |
||||
<% end %> |
||||
</div> |
@ -0,0 +1,8 @@ |
||||
<h3 class="widget-box--header"> |
||||
<span class="icon-context icon-projects"></span> |
||||
<span class="widget-box--header-title"><%= Setting.welcome_title.presence || organization_name %></span> |
||||
</h3> |
||||
|
||||
<div class="wiki"> |
||||
<%= format_text(Setting.welcome_text, headings: false) %> |
||||
</div> |
@ -0,0 +1,61 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
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. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
<% breadcrumb_paths(nil) %> |
||||
<div class="widget-boxes--screen-header"> |
||||
<h2> |
||||
<span><%= organization_icon %></span> |
||||
<%= organization_name %> |
||||
</h2> |
||||
</div> |
||||
|
||||
<% if @homescreen[:blocks].any? %> |
||||
<section class="widget-boxes"> |
||||
<% @homescreen[:blocks].each do |block| %> |
||||
<% if block[:if].nil? || instance_eval(&block[:if]) %> |
||||
<div class="widget-box"> |
||||
<%= render partial: "homescreen/blocks/#{block[:partial]}", locals: (block[:locals] || {}) %> |
||||
</div> |
||||
<% end %> |
||||
<% end %> |
||||
</section> |
||||
<% end %> |
||||
|
||||
<% if @homescreen[:links].any? %> |
||||
<section class="homescreen--links"> |
||||
<% @homescreen[:links].each do |link| %> |
||||
<% title = I18n.t(link[:label], scope: 'homescreen.links') %> |
||||
<a class="homescreen--links--item" href="<%= link[:url] %>" title="<%= title %>"> |
||||
<span class="<%= link[:icon] %>"></span> |
||||
<%= title %> |
||||
</a> |
||||
<% end %> |
||||
</section> |
||||
<% end %> |
||||
|
||||
<%= call_hook :homescreen_after_links %> |
@ -0,0 +1,4 @@ |
||||
// reload iframes parent (project members view) |
||||
// to show updated list of members and a flash message |
||||
window.parent.document.location.reload(); |
||||
|
@ -0,0 +1,158 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
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. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<% html_title 'Members' %> |
||||
<%= toolbar title: 'Members' do %> |
||||
<% if authorize_for(:members, :new) %> |
||||
<a href="<%= new_project_member_path %>" id="add-member-button" title="Add Member" class="button -alt-highlight"> |
||||
<i class="button--icon icon-add"></i> |
||||
<span class="button--text"><%= I18n.t(:button_add_member) %></span> |
||||
</a> |
||||
<% end %> |
||||
<% end %> |
||||
|
||||
<%= error_messages_for 'member' %> |
||||
|
||||
<div> |
||||
<% if @members.any? %> |
||||
<% authorized = authorize_for('members', 'update') %> |
||||
<div class="generic-table--container"> |
||||
<div class="generic-table--results-container"> |
||||
<table interactive-table role="grid" class="generic-table"> |
||||
<colgroup> |
||||
<col highlight-col> |
||||
<col highlight-col> |
||||
<%= call_hook(:view_projects_settings_members_table_colgroup, :project => @project) %> |
||||
<col> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> |
||||
<div class="generic-table--sort-header-outer"> |
||||
<div class="generic-table--sort-header"> |
||||
<span> |
||||
<%= User.model_name.human %> / <%= Group.model_name.human %> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</th> |
||||
<th> |
||||
<div class="generic-table--sort-header-outer"> |
||||
<div class="generic-table--sort-header"> |
||||
<span> |
||||
<%= l(:label_role_plural) %> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</th> |
||||
<%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> |
||||
<th></th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<% @members.each do |member| %> |
||||
<% next if member.new_record? %> |
||||
<tr id="member-<%= member.id %>" class=" member"> |
||||
<% |
||||
member_type = member.principal.class.name.downcase |
||||
classes = [ |
||||
member_type, |
||||
('icon icon-group' if member_type == 'group'), |
||||
user_status_class(member.principal) |
||||
].compact.join(' ') |
||||
%> |
||||
<td class="<%= classes %>" title="<%= user_status_i18n member.principal %>"> |
||||
<%= link_to_user member.principal %> |
||||
<% if member.user && member.user.invited? %> |
||||
<i title="<%= t('text_user_invited') %>" class="icon icon-mail"></i> |
||||
<% end %> |
||||
</td> |
||||
<td class="roles"> |
||||
<span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span> |
||||
<% if authorized %> |
||||
<%= form_for(member, :url => {:controller => '/members', |
||||
:action => 'update', |
||||
:id => member, |
||||
:page => params[:page], |
||||
:per_page => params[:per_page] }, |
||||
:method => :put, |
||||
:html => { :id => "member-#{member.id}-roles-form", |
||||
:class => 'hol', |
||||
:style => 'display:none' }) do |f| %> |
||||
<p><% @roles.each do |role| %> |
||||
<label><%= check_box_tag 'member[role_ids][]', role.id, member.roles.include?(role), |
||||
:disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label> |
||||
<% end %></p> |
||||
<%= hidden_field_tag 'member[role_ids][]', '' %> |
||||
<p><%= submit_tag l(:button_change), :class => 'button -highlight -small' %> |
||||
<%= link_to_function l(:button_cancel), |
||||
"$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;", |
||||
class: 'button -small' %></p> |
||||
<% end %> |
||||
<% end %> |
||||
</td> |
||||
<%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> |
||||
<% if authorized %> |
||||
<td class="buttons"> |
||||
<% |
||||
delete_class, delete_title = if member.disposable? |
||||
['icon icon-delete', I18n.t(:title_remove_and_delete_user)] |
||||
else |
||||
['icon icon-close', I18n.t(:button_remove)] |
||||
end |
||||
%> |
||||
<%= link_to_function '', "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;", :class => 'icon icon-edit', :title => l(:button_edit) %> |
||||
<%= link_to('', {:controller => '/members', :action => 'destroy', :id => member, :page => params[:page]}, |
||||
:method => :delete, |
||||
data: { confirm: ((!User.current.admin? && member.include?(User.current)) ? l(:text_own_membership_delete_confirmation) : nil) }, |
||||
:title => delete_title, :class => delete_class) if member.deletable? %> |
||||
</td> |
||||
<% end %> |
||||
</tr> |
||||
<% end %> |
||||
</tbody> |
||||
</table> |
||||
<div class="generic-table--header-background"></div> |
||||
</div> |
||||
</div> |
||||
<%= pagination_links_full @members, @pagination_url_options || {} %> |
||||
<% else %> |
||||
<div class="generic-table--container"> |
||||
<div class="generic-table--no-results-container"> |
||||
<h2 class="generic-table--no-results-title"> |
||||
<i class="icon-info"></i> |
||||
<%= l(:label_nothing_display) %> |
||||
</h2> |
||||
<div class="generic-table--no-results-description"> |
||||
<p class="nodata"><%= l(:label_no_data) %></p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<% end %> |
||||
</div> |
@ -0,0 +1,43 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
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. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
<%= javascript_include_tag "members_form.js" %> |
||||
|
||||
<%= error_messages_for 'member' %> |
||||
|
||||
<div> |
||||
<% if @principals_available.any? %> |
||||
<%= render :partial => "members/member_form", |
||||
:locals => { :project => @project, :roles => @roles } %> |
||||
<% else %> |
||||
<p> |
||||
<%= I18n.t('text_no_roles_defined') %> |
||||
</p> |
||||
<%= link_to I18n.t('button_back'), :back, class: 'button' %> |
||||
<% end %> |
||||
</div> |
@ -1,147 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
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. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
<%= javascript_include_tag "members_form.js" %> |
||||
|
||||
<%= error_messages_for 'member' %> |
||||
<% roles = Role.find_all_givable |
||||
# Check if there is at least one principal that can be added to the project |
||||
principals_available = @project.possible_members("", 1) |
||||
member_per_page = 20 |
||||
|
||||
@members = @project.member_principals.includes(:roles, :principal, :member_roles) |
||||
.order(User::USER_FORMATS_STRUCTURE[Setting.user_format].map{|attr| attr.to_s}.join(", ")) |
||||
.page(params[:page]) |
||||
.references(:users) |
||||
.per_page(per_page_param) |
||||
%> |
||||
<div> |
||||
<% if roles.any? && principals_available.any? %> |
||||
<%= render :partial => "members/member_form", |
||||
:locals => { :project => @project, |
||||
:members => @members, |
||||
:roles => roles } %> |
||||
|
||||
<% end %> |
||||
</div> |
||||
<div> |
||||
<% if @members.any? %> |
||||
<% authorized = authorize_for('members', 'update') %> |
||||
<div class="generic-table--container"> |
||||
<div class="generic-table--results-container"> |
||||
<table interactive-table role="grid" class="generic-table"> |
||||
<colgroup> |
||||
<col highlight-col> |
||||
<col highlight-col> |
||||
<%= call_hook(:view_projects_settings_members_table_colgroup, :project => @project) %> |
||||
<col> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> |
||||
<div class="generic-table--sort-header-outer"> |
||||
<div class="generic-table--sort-header"> |
||||
<span> |
||||
<%= User.model_name.human %> / <%= Group.model_name.human %> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</th> |
||||
<th> |
||||
<div class="generic-table--sort-header-outer"> |
||||
<div class="generic-table--sort-header"> |
||||
<span> |
||||
<%= l(:label_role_plural) %> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</th> |
||||
<%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> |
||||
<th></th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<% @members.each do |member| %> |
||||
<% next if member.new_record? %> |
||||
<tr id="member-<%= member.id %>" class=" member"> |
||||
<td class="<%= member.principal.class.name.downcase %> <%= 'icon icon-group' if member.principal.class.name.downcase == 'group' %> <%= user_status_class member.principal%>" title="<%= user_status_i18n member.principal%>"><%= link_to_user member.principal %></td> |
||||
<td class="roles"> |
||||
<span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span> |
||||
<% if authorized %> |
||||
<%= form_for(member, :url => {:controller => '/members', |
||||
:action => 'update', |
||||
:id => member, |
||||
:page => params[:page]}, |
||||
:method => :put, |
||||
:remote => true, |
||||
:html => { :id => "member-#{member.id}-roles-form", |
||||
:class => 'hol', |
||||
:style => 'display:none' }) do |f| %> |
||||
<p><% roles.each do |role| %> |
||||
<label><%= check_box_tag 'member[role_ids][]', role.id, member.roles.include?(role), |
||||
:disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label> |
||||
<% end %></p> |
||||
<%= hidden_field_tag 'member[role_ids][]', '' %> |
||||
<p><%= submit_tag l(:button_change), :class => 'button -highlight -small' %> |
||||
<%= link_to_function l(:button_cancel), |
||||
"$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;", |
||||
class: 'button -small' %></p> |
||||
<% end %> |
||||
<%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> |
||||
<td class="buttons"> |
||||
<%= link_to_function l(:button_edit), "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;", :class => 'icon icon-edit' %> |
||||
<%= link_to(l(:button_delete), {:controller => '/members', :action => 'destroy', :id => member, :page => params[:page]}, |
||||
:method => :delete, |
||||
:remote => true, |
||||
data: { confirm: ((!User.current.admin? && member.include?(User.current)) ? l(:text_own_membership_delete_confirmation) : nil) }, |
||||
:title => l(:button_delete), :class => 'icon icon-delete') if member.deletable? %> |
||||
</td> |
||||
<% end %> |
||||
</td> |
||||
</tr> |
||||
<% end %> |
||||
</tbody> |
||||
</table> |
||||
<div class="generic-table--header-background"></div> |
||||
</div> |
||||
</div> |
||||
<%= pagination_links_full @members, params: { tab: 'members' }.merge(@pagination_url_options || {}) %> |
||||
<% else %> |
||||
<div class="generic-table--container"> |
||||
<div class="generic-table--no-results-container"> |
||||
<h2 class="generic-table--no-results-title"> |
||||
<i class="icon-info"></i> |
||||
<%= l(:label_nothing_display) %> |
||||
</h2> |
||||
<div class="generic-table--no-results-description"> |
||||
<p class="nodata"><%= l(:label_no_data) %></p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<% end %> |
||||
</div> |
@ -0,0 +1,60 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
Copyright (C) 2010-2013 the ChiliProject Team |
||||
|
||||
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. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%= error_messages_for 'user' %> |
||||
|
||||
<%= javascript_include_tag 'admin_users' %> |
||||
|
||||
<!--[form:user]--> |
||||
<section class="form--section"> |
||||
<div class="form--field"><%= f.text_field :mail, required: true, autofocus: true %></div> |
||||
<div class="form--field"><%= f.text_field :firstname, required: true %></div> |
||||
<div class="form--field"><%= f.text_field :lastname, required: true %></div> |
||||
|
||||
<%= render partial: 'customizable/field', |
||||
collection: @user.custom_field_values, |
||||
as: :value, |
||||
locals: { form: f } %> |
||||
|
||||
<% unless @auth_sources.empty? || OpenProject::Configuration.disable_password_login? %> |
||||
<div class="form--field"> |
||||
<% sources = ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }) %> |
||||
<%= f.select :auth_source_id, sources %> |
||||
</div> |
||||
|
||||
<div class="form--field" id="new_user_login" style="display: none;"> |
||||
<%= f.text_field :login, :required => true, :size => 25, :disabled => true %> |
||||
</div> |
||||
<% end %> |
||||
|
||||
<div class="form--field"><%= f.check_box :admin, :disabled => (@user == User.current) %></div> |
||||
<%= call_hook(:view_users_form, :user => @user, :form => f) %> |
||||
</section> |
||||
|
||||
<!--[eoform:user]--> |
@ -0,0 +1,73 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class DeliverNotificationJob |
||||
include OpenProject::BeforeDelayedJob |
||||
|
||||
def initialize(recipient_id, sender_id) |
||||
@recipient_id = recipient_id |
||||
@sender_id = sender_id |
||||
end |
||||
|
||||
def perform |
||||
# nothing to do if recipient was deleted in the meantime |
||||
return unless recipient |
||||
|
||||
mail = User.execute_as(recipient) { build_mail } |
||||
if mail |
||||
mail.deliver |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
# To be implemented by subclasses. |
||||
# Actual recipient and sender User objects are passed (always non-nil). |
||||
# Returns a Mail::Message, or nil if no message should be sent. |
||||
def render_mail(recipient:, sender:) |
||||
raise 'SubclassResponsibility' |
||||
end |
||||
|
||||
def build_mail |
||||
render_mail(recipient: recipient, sender: sender) |
||||
rescue StandardError => e |
||||
Rails.logger.error "#{self.class.name}: Unexpected error rendering a mail: #{e}" |
||||
# not raising, to avoid re-schedule of DelayedJob; don't expect render errors to fix themselves |
||||
# by retrying |
||||
nil |
||||
end |
||||
|
||||
def recipient |
||||
@recipient ||= User.find_by(id: @recipient_id) |
||||
end |
||||
|
||||
def sender |
||||
@sender ||= User.find_by(id: @sender_id) || DeletedUser.first |
||||
end |
||||
end |
@ -0,0 +1,77 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# 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. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'open_project/homescreen' |
||||
|
||||
OpenProject::Homescreen.manage :blocks do |blocks| |
||||
blocks.push( |
||||
{ partial: 'welcome', |
||||
if: Proc.new { Setting.welcome_on_homescreen? && !Setting.welcome_text.empty? } }, |
||||
{ partial: 'projects' }, |
||||
{ partial: 'users', |
||||
if: Proc.new { User.current.admin? } }, |
||||
{ partial: 'my_account', |
||||
if: Proc.new { User.current.logged? } }, |
||||
{ partial: 'news', |
||||
if: Proc.new { !@news.empty? } }, |
||||
{ partial: 'community' }, |
||||
{ partial: 'administration', |
||||
if: Proc.new { User.current.admin? } } |
||||
) |
||||
end |
||||
|
||||
OpenProject::Homescreen.manage :links do |links| |
||||
links.push( |
||||
{ |
||||
label: :user_guides, |
||||
icon: 'icon-context icon-rename', |
||||
url: 'https://www.openproject.org/help/user-guides/' |
||||
}, |
||||
{ |
||||
label: :faq, |
||||
icon: 'icon-context icon-faq', |
||||
url: 'https://www.openproject.org/help/faq/' |
||||
}, |
||||
{ |
||||
label: :glossary, |
||||
icon: 'icon-context icon-glossar', |
||||
url: 'https://www.openproject.org/help/user-guides/glossary/' |
||||
}, |
||||
{ |
||||
label: :shortcuts, |
||||
icon: 'icon-context icon-shortcuts', |
||||
url: 'https://www.openproject.org/help/user-guides/keyboard-shortcuts-access-keys/' |
||||
}, |
||||
{ |
||||
label: :forums, |
||||
icon: 'icon-context icon-bubble3', |
||||
url: 'https://community.openproject.org/projects/openproject/boards' |
||||
} |
||||
) |
||||
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue