Actualiza a Redmine 3.4.13

This commit is contained in:
Manuel Cillero 2020-07-03 21:39:03 +02:00
parent 807ff3308d
commit ecddcaf1d3
224 changed files with 2222 additions and 1000 deletions

View file

@ -87,7 +87,7 @@ class AccountController < ApplicationController
@user.must_change_passwd = false
if @user.save
@token.destroy
Mailer.password_updated(@user)
Mailer.password_updated(@user, { remote_ip: request.remote_ip })
flash[:notice] = l(:notice_account_password_updated)
redirect_to signin_path
return

View file

@ -60,7 +60,7 @@ class AttachmentsController < ApplicationController
@attachment.increment_download
end
if stale?(:etag => @attachment.digest)
if stale?(:etag => @attachment.digest, :template => false)
# images are sent inline
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
:type => detect_content_type(@attachment),
@ -70,7 +70,7 @@ class AttachmentsController < ApplicationController
def thumbnail
if @attachment.thumbnailable? && tbnail = @attachment.thumbnail(:size => params[:size])
if stale?(:etag => tbnail)
if stale?(:etag => tbnail, :template => false)
send_file tbnail,
:filename => filename_for_content_disposition(@attachment.filename),
:type => detect_content_type(@attachment),

View file

@ -19,7 +19,7 @@ class AutoCompletesController < ApplicationController
before_action :find_project
def issues
@issues = []
issues = []
q = (params[:q] || params[:term]).to_s.strip
status = params[:status].to_s
issue_id = params[:issue_id].to_s
@ -32,13 +32,14 @@ class AutoCompletesController < ApplicationController
scope = scope.where.not(:id => issue_id.to_i)
end
if q.match(/\A#?(\d+)\z/)
@issues << scope.find_by_id($1.to_i)
issues << scope.find_by_id($1.to_i)
end
@issues += scope.like(q).order(:id => :desc).limit(10).to_a
@issues.compact!
issues += scope.like(q).order(:id => :desc).limit(10).to_a
issues.compact!
end
render :layout => false
render :json => format_issues_json(issues)
end
private
@ -50,4 +51,13 @@ class AutoCompletesController < ApplicationController
rescue ActiveRecord::RecordNotFound
render_404
end
def format_issues_json(issues)
issues.map {|issue| {
'id' => issue.id,
'label' => "#{issue.tracker} ##{issue.id}: #{issue.subject.to_s.truncate(60)}",
'value' => issue.id
}
}
end
end

View file

@ -91,8 +91,10 @@ class EnumerationsController < ApplicationController
def build_new_enumeration
class_name = params[:enumeration] && params[:enumeration][:type] || params[:type]
@enumeration = Enumeration.new_subclass_instance(class_name, enumeration_params)
if @enumeration.nil?
@enumeration = Enumeration.new_subclass_instance(class_name)
if @enumeration
@enumeration.attributes = enumeration_params || {}
else
render_404
end
end
@ -105,6 +107,7 @@ class EnumerationsController < ApplicationController
def enumeration_params
# can't require enumeration on #new action
params.permit(:enumeration => [:name, :active, :is_default, :position])[:enumeration]
cf_ids = @enumeration.available_custom_fields.map{|c| c.id.to_s}
params.permit(:enumeration => [:name, :active, :is_default, :position, :custom_field_values => cf_ids])[:enumeration]
end
end

View file

@ -40,7 +40,8 @@ class IssuesController < ApplicationController
helper :timelog
def index
retrieve_query
use_session = !request.format.csv?
retrieve_query(IssueQuery, use_session)
if @query.valid?
respond_to do |format|
@ -367,7 +368,12 @@ class IssuesController < ApplicationController
when 'destroy'
# nothing to do
when 'nullify'
if Setting.timelog_required_fields.include?('issue_id')
flash.now[:error] = l(:field_issue) + " " + ::I18n.t('activerecord.errors.messages.blank')
return
else
time_entries.update_all(:issue_id => nil)
end
when 'reassign'
reassign_to = @project && @project.issues.find_by_id(params[:reassign_to_id])
if reassign_to.nil?

View file

@ -37,7 +37,7 @@ class SearchController < ApplicationController
end
# quick jump to an issue
if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
if !api_request? && (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
redirect_to issue_path(issue)
return
end
@ -49,7 +49,7 @@ class SearchController < ApplicationController
when 'my_projects'
User.current.projects
when 'subprojects'
@project ? (@project.self_and_descendants.active.to_a) : nil
@project ? (@project.self_and_descendants.to_a) : nil
else
@project
end

View file

@ -114,6 +114,7 @@ class TimelogController < ApplicationController
:time_entry => {
:project_id => params[:time_entry][:project_id],
:issue_id => @time_entry.issue_id,
:spent_on => @time_entry.spent_on,
:activity_id => @time_entry.activity_id
},
:back_url => params[:back_url]

View file

@ -106,6 +106,6 @@ class TrackersController < ApplicationController
return
end
@trackers = Tracker.sorted.to_a
@custom_fields = IssueCustomField.all.sort
@custom_fields = IssueCustomField.sorted
end
end

View file

@ -32,7 +32,7 @@
class WikiController < ApplicationController
default_search_scope :wiki_pages
before_action :find_wiki, :authorize
before_action :find_existing_or_new_page, :only => [:show, :edit, :update]
before_action :find_existing_or_new_page, :only => [:show, :edit]
before_action :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
before_action :find_attachments, :only => [:preview]
accept_api_auth :index, :show, :update, :destroy
@ -42,8 +42,6 @@ class WikiController < ApplicationController
helper :watchers
include Redmine::Export::PDF
include ActionView::Helpers::SanitizeHelper
# List of pages, sorted alphabetically and by parent (hierarchy)
def index
load_pages_for_index
@ -109,7 +107,7 @@ class WikiController < ApplicationController
send_data(export, :type => 'text/html', :filename => filename_for_content_disposition("#{@page.title}.html"))
return
elsif params[:format] == 'txt'
send_data(strip_tags(@content.text), :type => 'text/plain', :filename => filename_for_content_disposition("#{@page.title}.txt"))
send_data(@content.text, :type => 'text/plain', :filename => filename_for_content_disposition("#{@page.title}.txt"))
return
end
end
@ -152,6 +150,8 @@ class WikiController < ApplicationController
# Creates a new page or updates an existing one
def update
@page = @wiki.find_or_new_page(params[:id])
return render_403 unless editable?
was_new_page = @page.new_record?
@page.safe_attributes = params[:wiki_page]

View file

@ -1272,7 +1272,7 @@ module ApplicationHelper
link_to_function '',
"toggleCheckboxesBySelector('#{selector}')",
:title => "#{l(:button_check_all)} / #{l(:button_uncheck_all)}",
:class => 'toggle-checkboxes'
:class => 'icon icon-checked'
end
def progress_bar(pcts, options={})
@ -1423,10 +1423,13 @@ module ApplicationHelper
end
if email.present?
gravatar(email.to_s.downcase, options) rescue nil
else
elsif user.is_a?(AnonymousUser)
options[:size] &&= options[:size].to_s
image_tag 'anonymous.png',
GravatarHelper::DEFAULT_OPTIONS
.except(:default, :rating, :ssl).merge(options)
else
nil
end
else
''

View file

@ -127,8 +127,8 @@ module IssuesHelper
content_tag('td', check_box_tag("ids[]", other_issue.id, false, :id => nil), :class => 'checkbox') +
content_tag('td', relation.to_s(@issue) {|other| link_to_issue(other, :project => Setting.cross_project_issue_relations?)}.html_safe, :class => 'subject', :style => 'width: 50%') +
content_tag('td', other_issue.status, :class => 'status') +
content_tag('td', other_issue.start_date, :class => 'start_date') +
content_tag('td', other_issue.due_date, :class => 'due_date') +
content_tag('td', format_date(other_issue.start_date), :class => 'start_date') +
content_tag('td', format_date(other_issue.due_date), :class => 'due_date') +
content_tag('td', other_issue.disabled_core_fields.include?('done_ratio') ? '' : progress_bar(other_issue.done_ratio), :class=> 'done_ratio') +
content_tag('td', link, :class => 'buttons'),
:id => "relation-#{relation.id}",
@ -246,8 +246,12 @@ module IssuesHelper
issue_fields_rows do |rows|
values.each_with_index do |value, i|
css = "cf_#{value.custom_field.id}"
attr_value = show_value(value)
if value.custom_field.text_formatting == 'full'
attr_value = content_tag('div', attr_value, class: 'wiki')
end
m = (i < half ? :left : :right)
rows.send m, custom_field_name_tag(value.custom_field), show_value(value), :class => css
rows.send m, custom_field_name_tag(value.custom_field), attr_value, :class => css
end
end
end
@ -310,7 +314,7 @@ module IssuesHelper
# Returns an array of users that are proposed as watchers
# on the new issue form
def users_for_new_issue_watchers(issue)
users = issue.watcher_users
users = issue.watcher_users.select{|u| u.status == User::STATUS_ACTIVE}
if issue.project.users.count <= 20
users = (users + issue.project.users.sort).uniq
end

View file

@ -18,14 +18,11 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module SearchHelper
include ActionView::Helpers::SanitizeHelper
def highlight_tokens(text, tokens)
return text unless text && tokens && !tokens.empty?
re_tokens = tokens.collect {|t| Regexp.escape(t)}
regexp = Regexp.new "(#{re_tokens.join('|')})", Regexp::IGNORECASE
result = ''
text = strip_tags(text)
text.split(regexp).each_with_index do |words, i|
if result.length > 1200
# maximum length of the preview reached

View file

@ -156,7 +156,7 @@ class Attachment < ActiveRecord::Base
end
def title
title = filename.to_s
title = filename.dup
if description.present?
title << " (#{description})"
end

View file

@ -217,6 +217,7 @@ class Import < ActiveRecord::Base
csv_options = {:headers => false}
csv_options[:encoding] = settings['encoding'].to_s.presence || 'UTF-8'
csv_options[:encoding] = 'bom|UTF-8' if csv_options[:encoding] == 'UTF-8'
separator = settings['separator'].to_s
csv_options[:col_sep] = separator if separator.size == 1
wrapper = settings['wrapper'].to_s

View file

@ -275,7 +275,8 @@ class Issue < ActiveRecord::Base
end
end
unless options[:watchers] == false
self.watcher_user_ids = issue.watcher_user_ids.dup
self.watcher_user_ids =
issue.watcher_users.select{|u| u.status == User::STATUS_ACTIVE}.map(&:id)
end
@copied_from = issue
@copy_options = options
@ -1086,7 +1087,7 @@ class Issue < ActiveRecord::Base
if leaf?
estimated_hours
else
@total_estimated_hours ||= self_and_descendants.sum(:estimated_hours)
@total_estimated_hours ||= self_and_descendants.visible.sum(:estimated_hours)
end
end
@ -1300,7 +1301,7 @@ class Issue < ActiveRecord::Base
# Reschedules the issue on the given date or the next working day and saves the record.
# If the issue is a parent task, this is done by rescheduling its subtasks.
def reschedule_on!(date)
def reschedule_on!(date, journal=nil)
return if date.nil?
if leaf? || !dates_derived?
if start_date.nil? || start_date != date
@ -1308,6 +1309,9 @@ class Issue < ActiveRecord::Base
# Issue can not be moved earlier than its soonest start date
date = [soonest_start(true), date].compact.max
end
if journal
init_journal(journal.user)
end
reschedule_on(date)
begin
save
@ -1631,6 +1635,8 @@ class Issue < ActiveRecord::Base
copy.author = author
copy.project = project
copy.parent_issue_id = copied_issue_ids[child.parent_id]
copy.fixed_version_id = nil unless child.fixed_version.present? && child.fixed_version.status == 'open'
copy.assigned_to = nil unless child.assigned_to_id.present? && child.assigned_to.status == User::STATUS_ACTIVE
unless copy.save
logger.error "Could not copy subtask ##{child.id} while copying ##{@copied_from.id} to ##{id} due to validation errors: #{copy.errors.full_messages.join(', ')}" if logger
next
@ -1789,7 +1795,7 @@ class Issue < ActiveRecord::Base
def reschedule_following_issues
if start_date_changed? || due_date_changed?
relations_from.each do |relation|
relation.set_issue_to_dates
relation.set_issue_to_dates(@current_journal)
end
end
end

View file

@ -122,7 +122,10 @@ class IssueImport < Import
end
end
if issue.project && version_name = row_value(row, 'fixed_version')
if version = issue.project.versions.named(version_name).first
version =
issue.project.versions.named(version_name).first ||
issue.project.shared_versions.named(version_name).first
if version
attributes['fixed_version_id'] = version.id
elsif create_versions?
version = issue.project.versions.build

View file

@ -37,8 +37,8 @@ class IssueQuery < Query
QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", :totalable => true),
QueryColumn.new(:total_estimated_hours,
:sortable => "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" +
" WHERE subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)",
:sortable => -> { "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" +
" WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')} AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" },
:default_order => 'desc'),
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
@ -221,6 +221,7 @@ class IssueQuery < Query
end
disabled_fields = Tracker.disabled_core_fields(trackers).map {|field| field.sub(/_id$/, '')}
disabled_fields << "total_estimated_hours" if disabled_fields.include?("estimated_hours")
@available_columns.reject! {|column|
disabled_fields.include?(column.name.to_s)
}
@ -373,7 +374,7 @@ class IssueQuery < Query
neg = (operator == '!' ? 'NOT' : '')
subquery = "SELECT 1 FROM #{Journal.table_name} sj" +
" WHERE sj.journalized_type='Issue' AND sj.journalized_id=#{Issue.table_name}.id AND (#{sql_for_field field, '=', value, 'sj', 'user_id'})" +
" AND sj.id = (SELECT MAX(#{Journal.table_name}.id) FROM #{Journal.table_name}" +
" AND sj.id IN (SELECT MAX(#{Journal.table_name}.id) FROM #{Journal.table_name}" +
" WHERE #{Journal.table_name}.journalized_type='Issue' AND #{Journal.table_name}.journalized_id=#{Issue.table_name}.id" +
" AND (#{Journal.visible_notes_condition(User.current, :skip_pre_condition => true)}))"
@ -382,8 +383,26 @@ class IssueQuery < Query
def sql_for_watcher_id_field(field, operator, value)
db_table = Watcher.table_name
"#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " +
sql_for_field(field, '=', value, db_table, 'user_id') + ')'
me, others = value.partition { |id| ['0', User.current.id.to_s].include?(id) }
sql = if others.any?
"SELECT #{Issue.table_name}.id FROM #{Issue.table_name} " +
"INNER JOIN #{db_table} ON #{Issue.table_name}.id = #{db_table}.watchable_id AND #{db_table}.watchable_type = 'Issue' " +
"LEFT OUTER JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Issue.table_name}.project_id " +
"WHERE (" +
sql_for_field(field, '=', me, db_table, 'user_id') +
') OR (' +
Project.allowed_to_condition(User.current, :view_issue_watchers) +
' AND ' +
sql_for_field(field, '=', others, db_table, 'user_id') +
')'
else
"SELECT #{db_table}.watchable_id FROM #{db_table} " +
"WHERE #{db_table}.watchable_type='Issue' AND " +
sql_for_field(field, '=', me, db_table, 'user_id')
end
"#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (#{sql})"
end
def sql_for_member_of_group_field(field, operator, value)

View file

@ -176,10 +176,10 @@ class IssueRelation < ActiveRecord::Base
set_issue_to_dates
end
def set_issue_to_dates
def set_issue_to_dates(journal=nil)
soonest_start = self.successor_soonest_start
if soonest_start && issue_to
issue_to.reschedule_on!(soonest_start)
issue_to.reschedule_on!(soonest_start, journal)
end
end

View file

@ -54,7 +54,7 @@ class MailHandler < ActionMailer::Base
def self.safe_receive(*args)
receive(*args)
rescue Exception => e
logger.error "MailHandler: an unexpected error occurred when receiving email: #{e.message}" if logger
Rails.logger.error "MailHandler: an unexpected error occurred when receiving email: #{e.message}"
return false
end
@ -65,7 +65,7 @@ class MailHandler < ActionMailer::Base
%w(project status tracker category priority assigned_to fixed_version).each do |option|
options[:issue][option.to_sym] = env[option] if env[option]
end
%w(allow_override unknown_user no_permission_check no_account_notice default_group project_from_subaddress).each do |option|
%w(allow_override unknown_user no_permission_check no_account_notice no_notification default_group project_from_subaddress).each do |option|
options[option.to_sym] = env[option] if env[option]
end
if env['private']
@ -250,8 +250,8 @@ class MailHandler < ActionMailer::Base
# add To and Cc as watchers before saving so the watchers can reply to Redmine
add_watchers(issue)
add_attachments(issue)
issue.save!
add_attachments(issue)
if logger
logger.info "MailHandler: issue ##{issue.id} updated by #{user}"
end
@ -286,7 +286,7 @@ class MailHandler < ActionMailer::Base
reply
else
if logger
logger.info "MailHandler: ignoring reply from [#{sender_email}] to a locked topic"
logger.info "MailHandler: ignoring reply from [#{email.from.first}] to a locked topic"
end
end
end

View file

@ -311,7 +311,7 @@ class Mailer < ActionMailer::Base
end
# Notifies user that his password was updated
def self.password_updated(user)
def self.password_updated(user, options={})
# Don't send a notification to the dummy email address when changing the password
# of the default admin account which is required after the first login
# TODO: maybe not the best way to handle this
@ -320,6 +320,8 @@ class Mailer < ActionMailer::Base
security_notification(user,
message: :mail_body_password_updated,
title: :button_change_password,
remote_ip: options[:remote_ip],
originator: user,
url: {controller: 'my', action: 'password'}
).deliver
end
@ -333,7 +335,6 @@ class Mailer < ActionMailer::Base
end
def security_notification(recipients, options={})
redmine_headers 'Sender' => User.current.login
@user = Array(recipients).detect{|r| r.is_a? User }
set_language_if_valid(@user.try :language)
@message = l(options[:message],
@ -341,7 +342,11 @@ class Mailer < ActionMailer::Base
value: options[:value]
)
@title = options[:title] && l(options[:title])
@originator = options[:originator] || User.current
@remote_ip = options[:remote_ip] || @originator.remote_ip
@url = options[:url] && (options[:url].is_a?(Hash) ? url_for(options[:url]) : options[:url])
redmine_headers 'Sender' => @originator.login
redmine_headers 'Url' => @url
mail :to => recipients,
:subject => "[#{Setting.app_title}] #{l(:mail_subject_security_notification)}"
end

View file

@ -319,9 +319,10 @@ class Query < ActiveRecord::Base
" INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" +
" INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" +
" INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" +
" INNER JOIN #{Project.table_name} p ON p.id = m.project_id AND p.status <> ?" +
" WHERE q.project_id IS NULL OR q.project_id = m.project_id))" +
" OR #{table_name}.user_id = ?",
VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, user.id)
VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, Project::STATUS_ARCHIVED, user.id)
elsif user.logged?
scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", VISIBILITY_PUBLIC, user.id)
else
@ -340,7 +341,7 @@ class Query < ActiveRecord::Base
if project
(user.roles_for_project(project) & roles).any?
else
Member.where(:user_id => user.id).joins(:roles).where(:member_roles => {:role_id => roles.map(&:id)}).any?
user.memberships.joins(:member_roles).where(:member_roles => {:role_id => roles.map(&:id)}).any?
end
else
user == self.user
@ -398,6 +399,8 @@ class Query < ActiveRecord::Base
params[:v][field] = options[:values]
end
params[:c] = column_names
params[:group_by] = group_by.to_s if group_by.present?
params[:t] = totalable_names.map(&:to_s) if totalable_names.any?
params[:sort] = sort_criteria.to_param
params[:set_filter] = 1
params

View file

@ -45,7 +45,7 @@ class Version < ActiveRecord::Base
scope :like, lambda {|arg|
if arg.present?
pattern = "%#{arg.to_s.strip}%"
where("LOWER(#{Version.table_name}.name) LIKE :p", :p => pattern)
where([Redmine::Database.like("#{Version.table_name}.name", '?'), pattern])
end
}
scope :open, lambda { where(:status => 'open') }
@ -268,7 +268,7 @@ class Version < ActiveRecord::Base
end
def deletable?
fixed_issues.empty? && !referenced_by_a_custom_field?
fixed_issues.empty? && !referenced_by_a_custom_field? && attachments.empty?
end
def default_project_version

View file

@ -1,7 +1,6 @@
<%= call_hook :view_account_login_top %>
<div id="login-form">
<h2><%= l(:label_login) %></h2>
<%= form_tag(signin_path, onsubmit: 'return keepAnchorOnSignIn(this);') do %>
<%= back_url_hidden_field_tag %>

View file

@ -11,7 +11,7 @@
<% end %>
</table>
<br />
<div class="box">
<div class="box autoscroll">
<pre><%= Redmine::Info.environment %></pre>
</div>

View file

@ -1,19 +1,21 @@
<%= title l(:label_plugins) %>
<% if @plugins.any? %>
<table class="list plugins">
<% @plugins.each do |plugin| %>
<tr id="plugin-<%= plugin.id %>">
<td class="name"><span class="name"><%= plugin.name %></span>
<%= content_tag('span', plugin.description, :class => 'description') unless plugin.description.blank? %>
<%= content_tag('span', link_to(plugin.url, plugin.url), :class => 'url') unless plugin.url.blank? %>
</td>
<td class="author"><%= plugin.author_url.blank? ? plugin.author : link_to(plugin.author, plugin.author_url) %></td>
<td class="version"><span class="icon"><%= plugin.version %></span></td>
<td class="configure"><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %></td>
</tr>
<% end %>
</table>
<div class="autoscroll">
<table class="list plugins">
<% @plugins.each do |plugin| %>
<tr id="plugin-<%= plugin.id %>">
<td class="name"><span class="name"><%= plugin.name %></span>
<%= content_tag('span', plugin.description, :class => 'description') unless plugin.description.blank? %>
<%= content_tag('span', link_to(plugin.url, plugin.url), :class => 'url') unless plugin.url.blank? %>
</td>
<td class="author"><%= plugin.author_url.blank? ? plugin.author : link_to(plugin.author, plugin.author_url) %></td>
<td class="version"><span class="icon"><%= plugin.version %></span></td>
<td class="configure"><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %></td>
</tr>
<% end %>
</table>
</div>
<p><a href="#" id="check-for-updates"><%= l(:label_check_for_updates) %></a></p>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
@ -27,7 +29,7 @@ $(document).ready(function(){
dataType: "jsonp",
url: "https://www.redmine.org/plugins/check_updates",
data: <%= raw_json plugin_data_for_updates(@plugins) %>,
timeout: 3000,
timeout: 10000,
beforeSend: function(){
$('#ajax-indicator').show();
},

View file

@ -39,7 +39,7 @@
<ul>
<% @priorities.each do |p| -%>
<li><%= context_menu_link p.name, bulk_update_issues_path(:ids => @issue_ids, :issue => {'priority_id' => p}, :back_url => @back), :method => :post,
:selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit]) %></li>
:selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.any?(&:priority_derived?)) %></li>
<% end -%>
</ul>
</li>
@ -97,7 +97,7 @@
<ul>
<% (0..10).map{|x|x*10}.each do |p| -%>
<li><%= context_menu_link "#{p}%", bulk_update_issues_path(:ids => @issue_ids, :issue => {'done_ratio' => p}, :back_url => @back), :method => :post,
:selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
:selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.any?(&:done_ratio_derived?)) %></li>
<% end -%>
</ul>
</li>

View file

@ -6,41 +6,43 @@
<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
<table class="list files">
<thead><tr>
<%= sort_header_tag('filename', :caption => l(:field_filename)) %>
<%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
<%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
<%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
<th><%= l(:field_digest) %></th>
<th></th>
</tr></thead>
<tbody>
<% @containers.each do |container| %>
<% next if container.attachments.empty? -%>
<% if container.is_a?(Version) -%>
<tr>
<th colspan="6">
<%= link_to(container, {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
</th>
</tr>
<% end -%>
<% container.attachments.each do |file| %>
<tr class="file">
<td class="filename"><%= link_to_attachment file, :title => file.description -%></td>
<td class="created_on"><%= format_time(file.created_on) %></td>
<td class="filesize"><%= number_to_human_size(file.filesize) %></td>
<td class="downloads"><%= file.downloads %></td>
<td class="digest"><%= file.digest_type %>: <%= file.digest %></td>
<td class="buttons">
<%= link_to_attachment file, class: 'icon-only icon-download', title: l(:button_download), download: true %>
<%= link_to(l(:button_delete), attachment_path(file), :class => 'icon-only icon-del',
:data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %>
</td>
</tr>
<div class="autoscroll">
<table class="list files">
<thead><tr>
<%= sort_header_tag('filename', :caption => l(:field_filename)) %>
<%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
<%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
<%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
<th><%= l(:field_digest) %></th>
<th></th>
</tr></thead>
<tbody>
<% @containers.each do |container| %>
<% next if container.attachments.empty? -%>
<% if container.is_a?(Version) -%>
<tr>
<th colspan="6">
<%= link_to(container, {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
</th>
</tr>
<% end -%>
<% container.attachments.each do |file| %>
<tr class="file">
<td class="filename"><%= link_to_attachment file, :title => file.description -%></td>
<td class="created_on"><%= format_time(file.created_on) %></td>
<td class="filesize"><%= number_to_human_size(file.filesize) %></td>
<td class="downloads"><%= file.downloads %></td>
<td class="digest"><%= file.digest_type %>: <%= file.digest %></td>
<td class="buttons">
<%= link_to_attachment file, class: 'icon-only icon-download', title: l(:button_download), download: true %>
<%= link_to(l(:button_delete), attachment_path(file), :class => 'icon-only icon-del',
:data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
</tbody>
</table>
</tbody>
</table>
</div>
<% html_title(l(:label_attachment_plural)) -%>

View file

@ -2,6 +2,6 @@ $('#relations').html('<%= escape_javascript(render :partial => 'issues/relations
<% if @relation.errors.empty? %>
$('#relation_delay').val('');
$('#relation_issue_to_id').val('');
$('#relation_issue_to_id').focus();
<% end %>
$('#new-relation-form').show();
$('#relation_issue_to_id').focus();

View file

@ -13,6 +13,8 @@
<% end %>
<br />
<span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
<div class="wiki changeset-comments"><%= format_changeset_comments changeset %></div>
<div class="wiki changeset-comments">
<%= format_changeset_comments changeset %>
</div>
</div>
<% end %>

View file

@ -6,7 +6,9 @@
<p><strong><%= l(:text_destroy_time_entries_question, :hours => number_with_precision(@hours, :precision => 2)) %></strong></p>
<p>
<label><%= radio_button_tag 'todo', 'destroy', true %> <%= l(:text_destroy_time_entries) %></label><br />
<% unless Setting.timelog_required_fields.include?('issue_id') %>
<label><%= radio_button_tag 'todo', 'nullify', false %> <%= l(:text_assign_time_entries_to_project) %></label><br />
<% end %>
<% if @project %>
<label><%= radio_button_tag 'todo', 'reassign', false, :onchange => 'if (this.checked) { $("#reassign_to_id").focus(); }' %> <%= l(:text_reassign_time_entries) %></label>
<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %>

View file

@ -2,31 +2,28 @@
<html lang="<%= current_language %>">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title><%= html_title %></title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="description" content="<%= Redmine::Info.app_name %>" />
<meta name="keywords" content="issue,bug,tracker" />
<%= csrf_meta_tag %>
<%= favicon %>
<%= stylesheet_link_tag 'jquery/jquery-ui-1.11.0', 'cookieconsent.min', 'application', 'responsive', :media => 'all' %>
<%= stylesheet_link_tag 'jquery/jquery-ui-1.11.0', 'application', 'responsive', :media => 'all' %>
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
<% is_welcome = !User.current.logged? && current_page?(:controller => 'welcome', :action => 'index') %>
<%= stylesheet_link_tag 'frontpage', :media => 'all' if is_welcome %>
<%= javascript_heads %>
<script src="/themes/circlepro/javascripts/cookieconsent.min.js"></script>
<%= heads_for_theme %>
<%= call_hook :view_layouts_base_html_head %>
<!-- page specific tags -->
<%= yield :header_tags -%>
</head>
<body class="<%= body_css_classes %><%= ' is-preload' if is_welcome %>">
<body class="<%= body_css_classes %>">
<%= call_hook :view_layouts_base_body_top %>
<div id="wrapper">
<div class="flyout-menu js-flyout-menu">
<% if User.current.logged? || !Setting.login_required? %>
<div class="flyout-menu__search">
<%= form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
@ -64,58 +61,45 @@
<div id="wrapper2">
<div id="wrapper3">
<div id="top-menu">
<div id="wrapper-top-menu">
<ul class="social-menu">
<li class="social-link-blog"><a href="https://manuel.cillero.es" title="<%= l(:link_my_blog) %>" class="icon-blog"><span><%= l(:link_my_blog) %></span></a></li>
<li class="social-link-twitter"><a href="https://twitter.com/manuelcillero" title="Twitter" target="_blank" class="icon-twitter"><span>Twitter</span></a></li>
<li class="social-link-facebook"><a href="https://facebook.com/manuelcillero" title="Facebook" target="_blank" class="icon-facebook"><span>Facebook</span></a></li>
<li class="social-link-linkedin"><a href="https://es.linkedin.com/in/manuelcillero" title="Linkedin" target="_blank" class="icon-linkedin"><span>Linkedin</span></a></li>
<li class="social-link-gitlab"><a href="https://gitlab.com/manuelcillero" title="Gitlab" target="_blank" class="icon-gitlab"><span>Gitlab</span></a></li>
<li class="social-link-mail"><a href="https://manuel.cillero.es/contacto/#suitepro" title="Mail" class="icon-mail"><span>Mail</span></a></li>
</ul>
<div id="account">
<%= render_menu :account_menu -%>
</div>
<%= content_tag('div', "#{l(:label_logged_as)} #{link_to_user(User.current, :format => :username)}".html_safe, :id => 'loggedas') if User.current.logged? %>
<%= render_menu :top_menu if User.current.logged? || !Setting.login_required? -%>
</div>
</div>
<div id="header">
<a href="#" class="mobile-toggle-button js-flyout-menu-toggle-button"></a>
<div id="wrapper-header">
<% if User.current.logged? || !Setting.login_required? %>
<div id="quick-search" class="hide-when-print">
<div id="quick-search">
<%= form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
<%= hidden_field_tag 'scope', default_search_project_scope, :id => nil %>
<%= hidden_field_tag(controller.default_search_scope, 1, :id => nil) if controller.default_search_scope %>
<label for='q'>
<%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project}, :accesskey => accesskey(:search) %>:
<%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project, :scope => default_search_project_scope}, :accesskey => accesskey(:search) %>:
</label>
<%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search) %>
<% end %>
<%= render_project_jump_box %>
</div>
<% end %>
<h1><%= page_header_title %></h1>
</div>
<% if display_main_menu?(@project) %>
<div id="main-menu" class="tabs">
<div id="wrapper-main-menu">
<%= render_main_menu(@project) %>
<div class="tabs-buttons" style="display:none;">
<button class="tab-left" onclick="moveTabLeft(this); return false;"></button>
<button class="tab-right" onclick="moveTabRight(this); return false;"></button>
</div>
</div>
</div>
<% end %>
</div>
<div id="main" class="<%= sidebar_content? ? '' : 'nosidebar' %>">
<div id="wrapper-main">
<div id="sidebar">
<%= yield :sidebar %>
<%= view_layouts_base_sidebar_hook_response %>
@ -127,51 +111,19 @@
<%= call_hook :view_layouts_base_content %>
<div style="clear:both;"></div>
</div>
</div>
</div>
</div>
<a href="#" id="scrollup" class="hide-when-print"><%=l(:label_sort_higher)%></a><%= javascript_tag "$('#scrollup').click(function(){$('html,body').animate({scrollTop:0},600);return false;});" %>
<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
<div id="ajax-modal" style="display:none;"></div>
<div id="footer">
<div id="wrapper-footer">
<ul class="social-menu">
<li class="social-link-blog"><a href="https://manuel.cillero.es" title="<%= l(:link_my_blog) %>" class="icon-blog"><span><%= l(:link_my_blog) %></span></a></li>
<li class="social-link-twitter"><a href="https://twitter.com/manuelcillero" title="Twitter" target="_blank" class="icon-twitter"><span>Twitter</span></a></li>
<li class="social-link-facebook"><a href="https://facebook.com/manuelcillero" title="Facebook" target="_blank" class="icon-facebook"><span>Facebook</span></a></li>
<li class="social-link-linkedin"><a href="https://es.linkedin.com/in/manuelcillero" title="Linkedin" target="_blank" class="icon-linkedin"><span>Linkedin</span></a></li>
<li class="social-link-gitlab"><a href="https://gitlab.com/manuelcillero" title="Gitlab" target="_blank" class="icon-gitlab"><span>Gitlab</span></a></li>
<li class="social-link-mail"><a href="https://manuel.cillero.es/contacto/#suitepro" title="Mail" class="icon-mail"><span>Mail</span></a></li>
</ul>
<div class="bgl"><div class="bgr">
<div id="legal">
<span class="legal-legal"><a href="/projects/suitepro/wiki/Legal"><%= l(:label_legal) %></a></span>
<span class="legal-terms"> &nbsp;|&nbsp; <a href="/projects/suitepro/wiki/Condiciones_de_uso"><%= l(:label_legal_terms) %></a></span>
<span class="legal-privacy"> &nbsp;|&nbsp; <a href="/projects/suitepro/wiki/Política_de_privacidad"><%= l(:label_legal_privacy) %></a></span>
<span class="legal-cookies"> &nbsp;|&nbsp; <a href="/projects/suitepro/wiki/Política_de_cookies"><%= l(:label_legal_cookies) %></a></span>
</div>
<%= Time.current.year %> &copy; SuitePro (powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %>)
</div></div>
</div>
<div class="bgl"><div class="bgr">
Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> &copy; 2006-2019 Jean-Philippe Lang
</div></div>
</div>
</div>
</div>
<%= call_hook :view_layouts_base_body_bottom %>
<script>
//<![CDATA[
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": { "popup": { "background": "rgba(20,20,20,0.8)" }, "button": { "background": "#fff" } },
"theme": "classic",
"position": "bottom-left",
"content": { "message": "<a href='https://suitepro.cillero.es'>SuitePro</a> requiere el uso de cookies para ofrecer la mejor experiencia de acceso a sus contenidos. Puedes aceptar su uso o abandonar la página si lo deseas.", "dismiss": "ACEPTO SU USO", "link": "Más información", "href": "/projects/suitepro/wiki/Pol%C3%ADtica_de_cookies", "target": "_self" }
})});
//]]>
</script>
</body>
</html>

View file

@ -7,7 +7,7 @@
<%= content_tag :h1, @title -%>
<% end %></p>
<p><%= l(:field_user) %>: <strong><%= User.current.login %></strong><br/>
<%= l(:field_remote_ip) %>: <strong><%= User.current.remote_ip %></strong><br/>
<p><%= l(:field_user) %>: <strong><%= @originator.login %></strong><br/>
<%= l(:field_remote_ip) %>: <strong><%= @remote_ip %></strong><br/>
<%= l(:label_date) %>: <strong><%= format_time Time.now, true, @user %></strong></p>

View file

@ -2,7 +2,7 @@
<%= @url || @title %>
<%= l(:field_user) %>: <%= User.current.login %>
<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
<%= l(:field_user) %>: <%= @originator.login %>
<%= l(:field_remote_ip) %>: <%= @remote_ip %>
<%= l(:label_date) %>: <%= format_time Time.now, true, @user %>

View file

@ -7,7 +7,7 @@
</div>
</fieldset>
<fieldset class="box">
<legend><%= l(:label_role_plural) %> <%= toggle_checkboxes_link('.roles-selection input') %></legend>
<legend><%= toggle_checkboxes_link('.roles-selection input') %><%= l(:label_role_plural) %></legend>
<div class="roles-selection">
<% User.current.managed_roles(@project).each do |role| %>
<label><%= check_box_tag 'membership[role_ids][]', role.id, false, :id => nil %> <%= role %></label>

View file

@ -1,5 +1,5 @@
<fieldset class="box">
<legend><%= l(:label_project_plural) %> <%= toggle_checkboxes_link('.projects-selection input:enabled') %></legend>
<legend><%= toggle_checkboxes_link('.projects-selection input:enabled') %><%= l(:label_project_plural) %></legend>
<div class="objects-selection">
<div class="projects-selection">
<%= render_project_nested_lists(@projects) do |p| %>
@ -12,7 +12,7 @@
</fieldset>
<fieldset class="box">
<legend><%= l(:label_role_plural) %> <%= toggle_checkboxes_link('.roles-selection input') %></legend>
<legend><%= toggle_checkboxes_link('.roles-selection input') %><%= l(:label_role_plural) %></legend>
<div class="roles-selection">
<% @roles.each do |role| %>
<label>

View file

@ -3,39 +3,41 @@
<% end %>
<% if @project.repositories.any? %>
<table class="list">
<thead>
<tr>
<th><%= l(:field_identifier) %></th>
<th><%= l(:field_repository_is_default) %></th>
<th><%= l(:label_scm) %></th>
<th><%= l(:label_repository) %></th>
<th></th>
</tr>
</thead>
<tbody>
<% @project.repositories.sort.each do |repository| %>
<tr>
<td class="name">
<%= link_to repository.identifier,
{:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %>
</td>
<td><%= checked_image repository.is_default? %></td>
<td><%= repository.scm_name %></td>
<td><%= repository.url %></td>
<td class="buttons">
<% if User.current.allowed_to?(:manage_repository, @project) %>
<%= link_to(l(:label_user_plural), committers_repository_path(repository),
:class => 'icon icon-user') %>
<%= link_to(l(:button_edit), edit_repository_path(repository),
:class => 'icon icon-edit') %>
<%= delete_link repository_path(repository) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<div class="autoscroll">
<table class="list">
<thead>
<tr>
<th><%= l(:field_identifier) %></th>
<th><%= l(:field_repository_is_default) %></th>
<th><%= l(:label_scm) %></th>
<th><%= l(:label_repository) %></th>
<th></th>
</tr>
</thead>
<tbody>
<% @project.repositories.sort.each do |repository| %>
<tr>
<td class="name">
<%= link_to repository.identifier,
{:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %>
</td>
<td><%= checked_image repository.is_default? %></td>
<td><%= repository.scm_name %></td>
<td><%= repository.url %></td>
<td class="buttons">
<% if User.current.allowed_to?(:manage_repository, @project) %>
<%= link_to(l(:label_user_plural), committers_repository_path(repository),
:class => 'icon icon-user') %>
<%= link_to(l(:button_edit), edit_repository_path(repository),
:class => 'icon icon-edit') %>
<%= delete_link repository_path(repository) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>

View file

@ -33,7 +33,9 @@
</div>
<div class="wiki changeset-comments"><%= format_changeset_comments @changeset %></div>
<div class="wiki changeset-comments">
<%= format_changeset_comments @changeset %>
</div>
<% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %>
<%= render :partial => 'related_issues' %>

View file

@ -21,10 +21,11 @@
</p>
<%= hidden_field_tag 'tracker[core_fields][]', '' %>
<% if IssueCustomField.all.any? %>
<% @issue_custom_fields = IssueCustomField.sorted %>
<% if @issue_custom_fields.present? %>
<p>
<label><%= l(:label_custom_field_plural) %></label>
<% IssueCustomField.all.each do |field| %>
<% @issue_custom_fields.each do |field| %>
<label class="block">
<%= check_box_tag 'tracker[custom_field_ids][]',field.id, @tracker.custom_fields.to_a.include?(field), :id => nil %>
<%= field.name %>

View file

@ -1,5 +1,3 @@
<% if User.current.logged? %>
<h2><%= l(:label_home) %></h2>
<div class="splitcontentleft">
@ -26,149 +24,3 @@
<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
:title => "#{Setting.app_title}: #{l(:label_activity)}") %>
<% end %>
<% else %><!-- Frontpage -->
<div id="fp"><%= text_field_tag 'forcetop', nil, :style => 'display: none;' %>
<!-- Banner -->
<section id="fp-banner">
<div class="inner">
<h2>SuitePro</h2>
<p><%= l(:welcome_suitepro) %></p>
<ul class="actions special">
<li><a href="#fp-login" class="button primary scrolly"><%= l(:label_login) %></a></li>
</ul>
</div>
<a href="#one" class="more scrolly"><%= l(:welcome_discover) %></a>
</section>
<!-- One -->
<section id="one" class="frapper style1 special">
<div class="inner">
<header class="major">
<h2>A SIMPLE WAY TO GET WORK DONE&nbsp;&nbsp;;)</h2>
<p><%= raw l(:welcome_suitepro_is_redmine, :suitepro => '<strong>SuitePro</strong>', :redmine => '<a href="https://www.redmine.org"><strong>Redmine</strong></a>') %></p>
</header>
<ul class="icons major">
<li><span class="fp-icon fp-icon_1 major style1"><span class="label">Lorem</span></span></li>
<li><span class="fp-icon fp-icon_2 major style2"><span class="label">Ipsum</span></span></li>
<li><span class="fp-icon fp-icon_3 major style3"><span class="label">Dolor</span></span></li>
</ul>
</div>
</section>
<!-- Two -->
<section id="two" class="frapper alt style2">
<section class="spotlight">
<div class="image"><%= image_tag '/themes/circlepro/images/pic01.jpg' %></div><div class="content">
<h2><%= raw l(:welcome_spotlight_1_title) %></h2>
<p><%= l(:welcome_spotlight_1_text) %></p>
</div>
</section>
<section class="spotlight">
<div class="image"><%= image_tag '/themes/circlepro/images/pic02.jpg' %></div><div class="content">
<h2><%= raw l(:welcome_spotlight_2_title) %></h2>
<p><%= l(:welcome_spotlight_2_text) %></p>
</div>
</section>
<section class="spotlight">
<div class="image"><%= image_tag '/themes/circlepro/images/pic03.jpg' %></div><div class="content">
<h2><%= raw l(:welcome_spotlight_3_title) %></h2>
<p><%= l(:welcome_spotlight_3_text) %></p>
</div>
</section>
</section>
<!-- Three -->
<section id="three" class="frapper style3 special">
<div class="inner">
<header class="major">
<h2><%= l(:welcome_other_features) %></h2>
</header>
<ul class="features">
<li class="fp-icon fp-icon_4">
<h3><%= l(:welcome_feature_1_title) %></h3>
<p><%= l(:welcome_feature_1_text) %></p>
</li>
<li class="fp-icon fp-icon_5">
<h3><%= l(:welcome_feature_2_title) %></h3>
<p><%= l(:welcome_feature_2_text) %></p>
</li>
<li class="fp-icon fp-icon_6">
<h3><%= l(:welcome_feature_3_title) %></h3>
<p><%= l(:welcome_feature_3_text) %></p>
</li>
<li class="fp-icon fp-icon_7">
<h3><%= l(:welcome_feature_4_title) %></h3>
<p><%= l(:welcome_feature_4_text) %></p>
</li>
<li class="fp-icon fp-icon_8">
<h3><%= l(:welcome_feature_5_title) %></h3>
<p><%= l(:welcome_feature_5_text) %></p>
</li>
<li class="fp-icon fp-icon_9">
<h3><%= l(:welcome_feature_6_title) %></h3>
<p><%= l(:welcome_feature_6_text) %></p>
</li>
</ul>
</div>
</section>
<!-- Login -->
<section id="fp-login" class="frapper style4">
<div class="inner">
<%= call_hook :view_account_login_top %>
<div id="login-form">
<h2><%= l(:label_login) %></h2>
<%= form_tag(signin_path, onsubmit: 'return keepAnchorOnSignIn(this);') do %>
<%= back_url_hidden_field_tag %>
<label for="username"><%=l(:field_login)%></label>
<%= text_field_tag 'username', params[:username], :tabindex => '1' %>
<label for="password">
<%=l(:field_password)%>
<%= link_to l(:label_password_lost), lost_password_path, :class => "lost_password" if Setting.lost_password? %>
</label>
<%= password_field_tag 'password', nil, :tabindex => '2' %>
<% if Setting.openid? %>
<label for="openid_url"><%=l(:field_identity_url)%></label>
<%= text_field_tag "openid_url", nil, :tabindex => '3' %>
<% end %>
<% if Setting.autologin? %>
<label for="autologin"><%= check_box_tag 'autologin', 1, false, :tabindex => 4 %> <%= l(:label_stay_logged_in) %></label>
<% end %>
<input type="submit" name="login" value="<%=l(:button_login)%>" tabindex="5" id="login-submit" />
<% end %>
</div>
</div>
</section>
<!-- CTA -->
<section id="fp-cta" class="frapper style4">
<div class="inner">
<header>
<h2><%= l(:welcome_any_questions) %></h2>
<p><%= l(:welcome_please_contact) %></p>
</header>
<ul class="actions stacked">
<li><a href="https://manuel.cillero.es/contacto/#suitepro" class="button fit primary"><%= l(:welcome_contact) %></a></li>
<li><a href="https://manuel.cillero.es/sobre-mi" class="button fit"><%= l(:welcome_about_me) %></a></li>
</ul>
</div>
</section>
</div>
<script src="/themes/circlepro/javascripts/frontpage/jquery.scrolly.min.js"></script>
<script src="/themes/circlepro/javascripts/frontpage/browser.min.js"></script>
<script src="/themes/circlepro/javascripts/frontpage/breakpoints.min.js"></script>
<script src="/themes/circlepro/javascripts/frontpage/util.js"></script>
<script src="/themes/circlepro/javascripts/frontpage/main.js"></script>
<% end %>

View file

@ -46,8 +46,7 @@
<%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
<% if @page.attachments.length > 0 || (@editable && authorize_for('wiki', 'add_attachment')) %>
<fieldset class="collapsible collapsed<% if @page.attachments.length == 0 %> hide-when-print<% end %>">
<fieldset class="collapsible collapsed hide-when-print">
<legend onclick="toggleFieldset(this);"><%= l(:label_attachment_plural) %> (<%= @page.attachments.length %>)</legend>
<div style="display: none;">
@ -67,7 +66,6 @@
<% end %>
</div>
</fieldset>
<% end %>
<% other_formats_links do |f| %>
<%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>